Why use a compass?
The simple form of this macro looks like this:
# app/templates/macros.html
{% macro build_site_navigation(pages, selected) %}
<div class="w-1/4 mr-8">
<ul>
{% for page in pages %}
<a href="{{page.url}}">
<li>{{page.name}}</li>
</a>
{% endfor %}
</ul>
</div>
{% endmacro %}
To use this macro in our template:
- import the macro into the template by inserting
{% import "macros.html" as macros %}
at the top of the template file
- add the following code where you would like to insert the sidebar:
{{macros.build_site_navigation(pages=pages, selected="Site Details")}}
To populate the links in the sidebar I created a function generate_page_list
and then pass pages
into the template
# app/routes.py
def generate_page_list(server_id, site_id):
pages = [
{"name": "Site Details", "url": url_for(
"sites.show", server_id=server_id,
site_id=site_id)
},
{"name": "Environment", "url": url_for(
"sites.environment_page", server_id=server_id, site_id=site_id)
},
{"name": "SSL", "url": url_for(
"sites.ssl_page", server_id=server_id,
site_id=site_id)
},
{"name": "NGINX Config", "url": url_for(
"sites.nginx_config_page", server_id=server_id,
site_id=site_id)
},
{"name": "Workers", "url": url_for(
"sites.workers_page", server_id=server_id,
site_id=site_id)
}
]
return pages
This gives us a simple sidebar
Styling the sidebar
So the sidebar is now functioning but it needs some styles. Let's improve the macro a little bit to include styling with
tailwindcss
# app/templates/macros.html
{% macro build_site_navigation(pages, selected) %}
<div class="w-1/4 mr-8">
<ul>
{% for page in pages %}
<a href="{{page.url}}">
<li class="text-lg pl-6 py-3 {% if selected == page.name %}border-l-4 bg-gray-200{% endif %}">{{page.name}}</li>
</a>
{% endfor %}
</ul>
</div>
{% endmacro %}
Now we are getting somewhere, here's an updated view
Add routes to support new views
To make this fully functional some code changes must be made with the current
routes. Previously the only route that was necessary to show this looked like
this:
# app/routes.py
@app.route('servers/<int:server_id>/sites/<int:site_id>', methods=['GET'])
def show(server_id, site_id):
...
To support all of our new routes for the sidebar we are going to add a few more:
# app/routes.py
# this will now show the site details by default
@app.route('servers/<int:server_id>/sites/<int:site_id>', methods=['GET'])
# additional routes for new views
@app.route('servers/<int:server_id>/sites/<int:site_id>/environment', methods=['GET'])
@app.route('servers/<int:server_id>/sites/<int:site_id>/ssl', methods=['GET'])
@app.route('servers/<int:server_id>/sites/<int:site_id>/nginx', methods=['GET'])
@app.route('servers/<int:server_id>/sites/<int:site_id>/workers', methods=['GET'])
Add template files for the routes
Everything was previosly held within a single template file, now we need to
create a separate template file for each view
# the following files were created and their html was transfered from the
# original template file into their own
app/templates/site/details.html
app/templates/site/environment.html
app/templates/site/ssl.html
app/templates/site/nginx.html
app/templates/site/workers.html
Install the requirements and run the pelican-quickstart
command, following the prompts:
$ pip install -r requirements.txt
$ pelican-quickstart
Setup the project
$ mkdir pelican-netlify-cms && cd $_
# create and activate a virtual environment for your project, for example:
$ python -m venv venv
$ source venv/bin/activate
Create a requirements.txt
file. This is important as Netlify will look for this file to determine dependencies. In the file:
Now assuming you have created an empty repo on Github, we will add this project to that repo.
$ git init
$ git add .
$ git commit -m 'initial commit'
$ git remote add origin Your_Own_Git_Repository_URL
Now that the git repo is connected create the first post
For example, content/2019-04-20-sample.md
---
Title: My First Post
Date: 2019-04-20 05:30
Category: example
---
Post content
Push the post to Github
On Netlify
Connect to Github
Choose the repositories that Netlify will have access to.
Now choose the repository to publish.
Add the build command and output folder.
Build command
pelican content -s publishconf.py
Publish directory
output
Now click Deploy site!
I recently started using Less Css with Django, after using it briefly I found
that I did not want to manually compile Less after making changes during
development. Using this approach I
am able to compile Less client-side during development and have
django-compressor compile server-side on live site.
1. Install less via your package manager of choice:
# Using arch linux
sudo pacman -S npm
sudo npm install -g less
# Other distribution
sudo apt-get install npm
sudo npm install -g less
2. Install django-compressor app:
pip install django-compressor
3. Add compressor as installed app:
INSTALLED_APPS = (
# other installed apps
'compressor',
4. Specify less as a precompiler:
COMPRESS_PRECOMPILERS = (
('text/less', 'lessc {infile} {outfile}'),
)
5. Add compressor as a static file finder:
STATICFILES_FINDERS = (
# other static files finder
'compressor.finders.CompressorFinder',
)
6. Compiling less
There are many ways to set this up. A simple, yet effective way is to compile
less client-side when debugging and server-side during production. To do this
we need to do the following:
- Download less js file from the Less Website
- Create a theme.less (or other name) file
- Now your base.html file will be setup something like this:
{% load staticfiles %}
{% load compress %}
<!DOCTYPE html>
<html>
<head>
{% if debug %}
<link rel="stylesheet" type="text/less" media="all" href="{% static 'less/theme.less' %}" />
<script src="{% static 'js/less-1.6.1.min.js' %}"></script>
{% else %}
{% compress css %}
<link rel="stylesheet" type="text/less" media="all" href="{% static 'less/theme.less' %}" />
{% endcompress %}
{% endif %}
</head>
I was recently adding a slug field to a model in a Django application when I ran into this error when doing the South migration:
Error in migration: test_app:0002_auto__add_field_category_slug
DatabaseError: table "_south_new_test_app_category" already exists
When South makes changes to an existing table, it creates a new
table with a temporary name. The table is named
"_south_new_" + table_name
. In this case, the new table name is _south_new_test_app_category
.
Assuming the changes are successful, the old table is deleted and replaced with the new table.
However, the previous migration failed and the temporary table still existed.
To fix this, we need to drop the temporary table and redo the migration.
If you are not familiar with dropping a table, you can run the sqlclear
command to get a list of the drop table sql statements for an app. For
this test app it looks like this:
> python manage.py sqlclear test_app
BEGIN;
DROP TABLE "test_app_person";
DROP TABLE "test_app_category";
DROP TABLE "test_app_organization";
DROP TABLE "_south_new_test_app_category";
COMMIT;
Using the syntax you see from sqlclear
you can run the dbshell
command and drop temporary table.
> python manage.py dbshell
sqlite> DROP TABLE "_south_new_test_app_category";
Now as long as you fixed the issue with the migration that failed, you can
run the migration again and it will work as planned.