Content
"pelican" on https://aligot-death.space, available at https://aligot-death.space/wiki/pelican-en
pelican
A few tips and notes on the static site generator pelican
Pelican is a static site generator in python which is not necessarily beautiful out of the box, but offers a lot of control on the generation process.
More practical work environment#
Add to ~/.bashrc the following aliases:
1 alias pc="pelican content" 2 alias pl="pelican --listen"
simply build the website py typing pc from the directory, and pl to launch Pelican’s web server.
The website can be build without shutting down the server, so you can simply launch the pl command in another terminal (or typically, in another tmux pane) and build the website on the fly.
Writing#
This part assumes that you use RestructuredText format for your articles.
Easy styling#
to add a class to a paragraph, use (be careful with the whitespaces to avoid errors):
1 .. class:: warning 2 3 This part assumes that you use RestructuredText format for your articles.
Example: the warning just above (assuming you've created the corresponding CSS class)!
Multiple ..class can be nested, as long as the empty lines are respected. For instance:
1 .. class:: align-right 2 3 .. class:: side-note 4 5 **Le Règlement Général sur la Protection des Données (RGPD) c'est quoi ?**
using html within a .rst file#
Use:
1 .. raw:: html 2 3 <details> 4 <summary><b>Here is a summary.</b><br> 5 this is a summary that can be clicked to view/hide its details </summary> 6 Even though there is not much to see here. 7 </details>
Result:
Here is a summary.
this is a summary that can be clicked to view/hide its details
Even though there is not much to see here.
Table of content#
Simply add above your first part title (or anywhere, really):
1 .. contents:: <ToC title> 2 :depth: 2 3 :backlinks: none
Result:
Configuration#
Link management#
To ensure proper links, working page anchors and website structure:
- Add <base href="{{ SITEURL }}/{{ output_file }}"/> to HTML header
- add RELATIVE_URLS = False to pelicanconf.py (and do not override it to True in publishconf.py)
- Make sure to use {{ SITEURL }}/ in templates, such as href = "{{ SITEURL }}/{{ article.url }}"
- Use relative links prefixed with "/" to ensure that they start from the root of your website.
clean URLs#
In the pelicanconf.py file, set the following variables:
TAGS_URL = "tags" CATEGORIES_URL = "categories" ARCHIVES_URL = "archives" ARTICLE_URL = "{slug}" ARTICLE_LANG_URL = '{slug}-{lang}' PAGE_URL = "{slug}" PAGE_SAVE_AS = "{slug}.html" PAGE_LANG_URL = 'pages/{slug}-{lang}' CATEGORY_SAVE_AS = 'categories/{slug}.html' CATEGORY_URL = 'categories/{slug}' TAG_SAVE_AS = 'tags/{slug}.html' TAG_URL = 'tags/{slug}'
The result will be urls of the form example.com/making-soup or example.com/categories/linux.
To ensure that these links are used, you also need to configure the web server. In the case of nginx:
location = / { index index.html; } location / { root /var/www/example.com/; try_files $uri.html $uri =404; }
Theming#
Using article "summary"#
Use the striptags filter to avoid having <p class = "first"> garbage in your meta description:
1 {% if article.summary %} 2 <meta property="og:description" content="{{ article.summary|striptags|safe }}"> 3 {% endif %}
Article ordering#
By default articles are ordered in "reverse-date". But any metadata (with a "reverse-" prefix to... reverse) can be used: for instance, this wiki uses "title", like this in pelicanconf.py:
1 ARTICLE_ORDER_BY = "title"
See Ordering content for more details.
Translation switch for custom pages#
To get translation links for custom page (:save_as: and :template:), edit the translations.html from the theme and the following new macro:
1 {% macro translations_for_page(page) %} 2 <div> 3 {% if page.translations %} 4 <span class = "block">{{ page.lang }}</span> 5 {% for translation in page.translations %} 6 <a class = "inverted-block" href="{{ SITEURL }}/{{ translation.url }}" hreflang="{{ translation.lang }}">{{ translation.lang }}</a> 7 {% endfor %} 8 {% endif %} 9 </div> 10 {% endmacro %}
This new macro is called translation for page. And then call it using the following jinja code (or copy-paste it from another template and adapt it):
1 {% import 'translations.html' as translations with context %} 2 {% if translations.translations_for_page(page) %} 3 {{ translations.translations_for_page(page) }} 4 {% endif %}
For good mesure, here is the content of the file content/pages/index_wiki-fr.rst, which corresponds to the french homepage of this wiki:
1 Wiki 2 ######## 3 4 :date: 2021-09-29 5 :template: custom/index_wiki 6 :save_as: wiki/index-fr.html 7 :slug: wiki/index 8 :category: wiki 9 :lang: fr 10 :status: published
Custom home page#
To write properly
Do not modify the "index.html" file hoping to change the homepage: this file is also used for the category, tags and archives pages, which will probably be messed up if you change it. Instead, create a custom template.
follow https://stackoverflow.com/questions/55363180/how-do-i-choose-a-category-page-to-be-the-home-page-for-a-pelican-site /!template "homepage" must be in content/templates and exclude it, as weird as it is then, https://stackoverflow.com/questions/19283880/querying-for-specific-articles-via-tag-category-in-pelican-themes
Articles listed per year#
A common way to list articles on personal websites nowaday is to list them by year like so:
2021
- I saw a nice rock yesterday
2020
- I'm giving up on that blog
- More articles to come this year!
2019
- A long essay on consciousness
- New blog!
To do so in pelican, here is a skeleton template to use within templates.index.html:
1 <ul class = "article-list"> 2 {% for year, year_posts in articles_page.object_list|groupby('date.year')|reverse %} 3 <h2>{{year}}</h2> 4 {% for article in year_posts %} 5 <li> 6 <article> 7 <header> 8 <h2> 9 <a href="{{ SITEURL }}/{{ article.url }}" rel="bookmark" title="Permalink to {{ article.title|striptags }}"> 10 {{ article.title }} 11 </a> 12 </h2> 13 </header> 14 </article> 15 </li> 16 {% endfor %} 17 {% endfor %} 18 </ul>
Explanation: the heavylifting is done by the articles_page.object_list|groupby('date.year')|reverse which groups articles per year with the newest ones at the top. The resulting list is unpacked as the year + the list of articles for that year, the latter being iterated on by a second loop.
List x articles#
If for instance you only want to list the first three articles of a category, you can use the counter tag like so (in this example, 3 articles will be listed):
1 <div class = "image-gallery"> 2 {% set counter = namespace(value=0) %}{% for article in articles if ("miscellaneous_digital_drawings" in article.subcategories and counter.value < 3) %}<a href = "{{ SITEURL }}/{{ article.url }}"><img src="{{ article.cover_image }}" alt="{{ counter.value }}"></a>{% set counter.value = counter.value + 1 %} 3 {% endfor %} 4 </div>
Must have plugins#
Refer yourself to the `pelican-plugins<https://github.com/getpelican/pelican-plugins/>`__ repository for more informations
headerid: adds relative links to section headers