duncanlock.net

How I built this website, using Pelican: Part 2 - Themes

The Pelican quickstart site that we created in Part 1 used the default theme - which you will probably want to change or, at least, customize. In this post I break down the Pelican theme I created for this site and show you exactly how it’s built. I’ll be going through each part of the theme in depth, explaining why I did things that way and how each part works.

The theme for this site is professional grade - high quality, polished and responsive. It puts the focus on the reader, is 100% easy to read and works flawlessly at any screen size, including mobiles & tablets. It also takes into account best practices for both social media and Problematic, check error messages! : :abbr:`SEO (Search Engine Optimization)`, so that you can make the most of your writing.

Unknown interpreted text role “abbr”.

Before We Begin, a Word About Editing Workflow

I’m going to assume that you’re carrying on from Part 1 - so we’re using a python virtualenv & virtualenvwrapper, for example. With that in mind, here’s the workflow I’d recommend for working on your site. Open a text editor {fn-subl}, open a browser and point it at your local site, then open a Terminal window and run the following:

workon duncanlock.net-pelican
pelican -qrs pelicanconf.py

This should just sit there and monitor the site for changes and automatically rebuild it whenever anything changes:

--- AutoReload Mode: Monitoring `content`, `theme` and `settings` for changes. ---
-> Modified: content, theme, settings. re-generating...
Done: Processed 13 articles and 1 pages in 5.83 seconds.

To test it, open pelicanconf.py in your text editor and just save it - this should trigger an automatic rebuild. Now, whenever you change anything - the theme, the content or the settings, that process will automatically notice & rebuild the site - you just save your changes, then refresh your browser window once it’s finished building.

Standing on the Shoulders of Giants

My theme - which I’m currently calling Blueprint - wasn’t created from scratch. It was based on an existing theme, from the pelican-themes repository. To checkout this repository and see what themes are available, just check it out from github with git. Don’t do this in the same folder as your main site, do it somewhere else. This command will clone the repository into a folder called pelican-themes, in the folder where you run it:

git clone --recursive git@github.com:getpelican/pelican-themes.git

Note that this repository uses sub-modules, so you need to use --recursive when cloning. In order to pull the latest changes in the future, you need to do this:

cd pelican-themes
git pull --recurse-submodules

Once you’ve done this, you can try out the different themes by creating or changing the following setting in your pelicanconf.py file:

# Which theme to use
THEME = '../pelican-themes/built-texts'

Just point this to a different theme folder and re-generate your site to see what it looks like. If you’re using the editing workflow mentioned above, just saving the file should rebuild the site automatically.

My theme was based on the theme called Built Texts. You can still see the family resemblance, but the two themes have diverged quite a bit.

I suggest that you try the different themes in the pelican-themes repository and either find one you like and stop reading, or find one you almost-sorta-like – and want to use as a base for your theme.

Forking or Copying to a New Theme

You now have some options - you can either fork the pelican-plugins repository on github, then copy the theme folder you wish to start from and rename it - or you can just copy the theme folder somewhere else - such as your sites ./themes folder, or a separate folder altogether - and work on it in it’s own git repo.

I’m not going to explain in depth how to use git or github here - they have excellent help documentation. If you want to

TODO:

The Structure of a Pelican Theme

You can find the minimum requirements for a working pelican theme here, but my theme expands on this a bit, to add extra features. The current structure of the blueprint theme looks like this:

├── themes
    ├── blueprint
        ├── static
        │   ├── css
        │   │   ├── fontello.css
        │   │   ├── main.css
        │   │   ├── print.css
        │   │   ├── pygments.css
        │   │   └── pygments-monokai.css
        │   ├── font
        │   │   ├── fontello.eot
        │   │   ├── fontello.svg
        │   │   ├── fontello.ttf
        │   │   └── fontello.woff
        │   └── js
        │       └── html5.js
        └── templates
            ├── analytics.html                    # Google Analytics snippet
            ├── archives.html                     # to display archives
            ├── article.html                      # processed for each article
            ├── article-sidebar.html              #
            ├── article-sidebar-multipart.html    # article sidebar snippets
            ├── article-sidebar-toc.html          #
            ├── author.html                       # processed for each author
            ├── base.html                         # base page template
            ├── categories.html                   # list all the categories
            ├── category.html                     # processed for each category
            ├── colophon.html                     # colophon snippet for footer
            ├── disqus.html                       # disqus comments snippet
            ├── googleplus.html                   # google+ snippet
            ├── footer.html                       # footer snippet
            ├── index.html                        # the index (list all articles)
            ├── page.html                         # processed for each page
            ├── pagination.html                   # pagination snippet for index pages
            ├── period_archives.html              # to display time-period archives
            ├── tag.html                          # processed for each tag
            ├── tags.html                         # list all tags; can be a tag cloud
            └── twitter.html                      # snippet for twitter share button

Yes – I’m going to explain what all those are for.

The Main Theme Components

base.html

base page template
Figure 1. The base page template. This defines the skeleton structure for the page, and includes the snippets for the footer & analytics where required.

This is the main template - all the other ones inherit and extend this one, filling in the gaps with the appropriate output, depending on which page is actually being generated.

archives.html

This template

article.html

author.html

categories.html

category.html

index.html

page.html

tags.html

The Supporting Cast

These aren’t full templates - they don’t inherit the base template. They’re included in other templates to output certain reusable snippets of the site - the footer, the sidebar, etc…​

article-sidebar.html

article-sidebar-multipart.html

article-sidebar-toc.html

analytics.html

colophon.html

This snippet is output on the right hand side of the footer. It’s a simple snippet and is conditional on a setting in your config file. It’s output currently looks like this:

colophon

and contains the following code:

{% if COLOPHON %}
<div class="colophon span5" id="colophon">
  <h4 class="nav-header">{{ COLOPHON_TITLE }}</h4>
  <p>{{ COLOPHON_CONTENT }}</p>
</div>
{% endif %}

You can then define the COLOPHON variables in your pelicanconf.py file, like this:

# Set Colophon variables, which can be output by the theme.
COLOPHON = True
COLOPHON_TITLE = 'About'
COLOPHON_CONTENT = '<a href="/pages/duncan-locks-resume.html">An adaptable...</a>'

Metadata & Microdata

Blueprint has extensive support for rich meta and microdata. Metadata like title and description have always been important for your site’s appearance in search results and for SEO generally - so the blueprint theme is very careful to provide complete support for all the traditional metadata - plus a few newer ones like favicons for phones & tablets.

In addition, Microdata is becoming more and more important and is increasingly being used by large services like Twitter, Google+ and, crucially, Google Search. Marking up your content with mircodata is a simple and unobtrusive way of adding machine readable metadata to your content - giving you an advantage when your content appears on services that can use this data.

The blueprint theme fully supports the following microdata:

Twitter Cards

Twitter cards make it possible for you to attach media experiences to Tweets that link to your content. Simply add a few lines of HTML to your webpages, and users who Tweet links to your content will have a “card” added to the Tweet that’s visible to all of their followers. – https://dev.twitter.com/docs/cards

This is what this looks like in action:

twitter card example

This is controlled by the following settings in your pelicanconf.py file:

TWITTER_USERNAME = 'duncanlock'
TWITTER_ACCOUNT_ID = 'XXXXXXXXX'
TWITTER_CARD = True

Authorship

Google is piloting the display of author information in search results to help users discover great content. – https://support.google.com/webmasters/answer/1408986?hl=en

This is what this looks like in a Google Search result when this is setup and working:

google authorship microdata results

Google In-depth Articles

This Google feature prefers articles which use schema.org Article microdata, specifically the following items:

  • headline
  • alternativeHeadline
  • image
  • description
  • datePublished
  • articleBody

See here for more information about Google In-depth articles.

Supporting image also has other benefits, notably Google+ and Facebook, which will both default that image in as the thumbnail if you post a link:

google plus image thumbnail example

Facebook & OpenGraph

facebook image thumbnail example

Blueprint also supports OpenGraph metadata, for Facebook and other services which make use of it.

This is controlled by the following setting in your pelicanconf.py file:

OPEN_GRAPH_METADATA = True

The Devil is in the Detail

Mention

A Multitude of Favicons

Put this into the <head> section of base.html:

{# Favicons #}
<meta itemprop="image" content="{{ SITEURL }}/static/images/favicon-128x128.png">
<link rel="shortcut icon" href="{{ SITEURL }}/favicon.ico">
<link rel="apple-touch-icon" href="{{ SITEURL }}/static/images/apple-touch-icon.png">
<link rel="apple-touch-icon" sizes="72x72" href="{{ SITEURL }}/static/images/apple-touch-icon-72x72.png">
<link rel="apple-touch-icon" sizes="114x114" href="{{ SITEURL }}/static/images/apple-touch-icon-114x114.png">

Google Analytics Integration

This goes into your publishconf.py file:

# Output Google Analytics code
GOOGLE_ANALYTICS_ID = "UA-XXXXXXX-X" # <-- Replace with your Property ID
GOOGLE_ANALYTICS_UNIVERSAL = True

This goes at the bottom of base.html:

{% include "analytics.html" %}

</body>
</html>

and analytics.html looks like this:

{% if GOOGLE_ANALYTICS_ID %}
    {% if GOOGLE_ANALYTICS_UNIVERSAL %}
        <script>
          (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
          (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
          m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
          })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

          ga('create', '{{GOOGLE_ANALYTICS_ID}}', 'duncanlock.net');
          ga('send', 'pageview');
        </script>
    {% else %}
        <script>var _gaq=[['_setAccount','{{GOOGLE_ANALYTICS_ID}}'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'))</script>
    {% endif %}
{% endif %}

Plugins I use, which affect the theme

The theme expects some plugins to

webassets

  • rearrange theme files
  • first name in list of output is actual output filename
  • use filename not query param for name

Future Plans

  • Upgrade to Bootstrap 3
  • Do I really need to be loading jQuery?
  • Header snippet
  • Move snippets into sub-folder & rename template files to .j2 instead of .html?

Footnotes & References:

SublimeText is currently my favourite text editor - it’s really pretty great, you should try it.]


This post is part 2 of the 2 part "How I built this website, using Pelican" series:


Comments