Skip to content

pelican-themes/sidecar

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

252 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Sidecar

A plain but pretty theme for the Pelican static site generator. Demo site.

A screenshot of the theme.

Features

  • Nice typography and a wide range of HTML elements you can use in pages and articles. Sidecar is based on Oatcake, my universal CSS typography theme. See Oatcake's site for documentation: anything you see on that page, you can use in your pages and articles with Sidecar. The dummy articles on Sidecar's demo site show some of the elements in action.
  • Responsive design: works great on both desktop and mobile.
  • Customizable colors, fonts, and elements, both site-wide and per-page/article styles.
  • Code blocks with syntax highlighting. Use the SIDECAR_PYGMENTS_THEME setting to choose from a few dozen builtin syntax highlighting color themes.
  • Automatically generated tables of contents for pages and articles.
  • A customizable navbar with the SIDECAR_NAVBAR setting.
  • Customizable article and page taglines and footers with the SIDECAR_{ARTICLE|PAGE}_{TAGLINE|FOOTER}_ITEMS settings.
  • Supports Pelican's Atom and RSS feeds with feed autodiscovery links in the HTML <head>.
  • Supports all of Pelican's pages: the index page, article pages (example), static pages (example), the archives page, authors, categories, tags, and period archives (for example: all articles from 2024, all articles from January 2024, or all articles from 26th January 2024).
  • Uses semantic HTML including: the <html> element's lang attribute for the site's default language (the DEFAULT_LANG setting) or the page/article's language; <header> for the site header; <nav> for the navbar; <main> for the page's main content; <hgroup> to group headings and subheadings together; <footer> for page and article taglines and footers; link relations: rel="bookmark" for article permalinks, rel="author" for article and page authors, rel="tag" for tags, rel="next" and rel="prev" for pagination links; <time> elements with the datetime attribute for article/page created/updated dates; links have helpful tooltips with the title attribute; and pages have good tab titles with the <title> element.

Installation

  1. Clone the theme to a local directory:

    git clone https://github.com/pelican-themes/sidecar.git
    
  2. Pin your version by checking out the latest Sidecar release:

    git -C sidecar checkout VERSION
    

    Replace VERSION with the latest version number from Sidecar's releases.

    Follow Sidecar on GitHub or subscribe to GitHub's Atom feed for new releases to get notified so you can update your version number.

  3. Set the THEME setting in your Pelican config to the path to your local clone of Sidecar. It can be either an absolute path or a path relative to your Pelican config file:

    # pelicanconf.py
    
    THEME = "../sidecar"

Usage

Summaries

Sidecar supports optional article and page "summaries" (or "subtitles" / "subheadings") that're displayed in large-text beneath the article or page's title. See this demo post for an example of an article with a summary.

You create a summary by adding a Summary to your article or page's metadata, like this:

Title: Example Post Title
Summary: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin a malesuada orci.

Nullam at massa eros. Nullam ultricies suscipit volutpat.
Maecenas at elit quis sem semper rutrum eu condimentum lorem…

You can also use Subtitle or Subheading instead of Summary. The difference is that if you use Summary Pelican will also use the provided summary in its RSS and Atom feeds (overriding the default summary that Pelican generates from your article's body), whereas if you use Subtitle or Subheading this will not replace the article summary in RSS and Atom feeds.

Markdown syntax works in Summary fields by default, but not in Subtitle or Subheading fields. To get Markdown to work in Subtitle or Subheading fields add them to the FORMATTED_FIELDS setting in your Pelican config:

# pelicanconf.py

FORMATTED_FIELDS = ["summary", "subheading", "subtitle"]

Python-Markdown doesn't allow blank lines in metadata, so to create a multi-paragraph summary you need to use <p>'s:

Title: About
Summary:
    <p>
      Sidecar is a plain but pretty theme for the Pelican static site generator
      that works great on both mobile and desktop.
    </p>
    <p markdown="1">
      This *About* page is an example of what a static page looks like
      with Sidecar.
    </p>

(The markdown="1" is needed to enable Markdown syntax within a <p>.)

You can also add subheadings to <h2> or <h3> headings within article or page bodies by wrapping the <h2> or <h3> in an <hgroup> along with one or more <p>'s above and/or below the heading, like this:

<hgroup>
  <h2>The reality dysfunction</h2>
  <p>Space is not the only void</p>
</hgroup>

Meta descriptions

Sidecar includes support for HTML <meta name="description" content="..." /> metadata tags.

These are used by search engines like Google to generate the "snippets" that are shown in search page results. See Google's Best practices for creating quality meta descriptions.

A meta description is supposed to be "a short, relevant summary of what a particular page is about" that "informs and interests users": "[t]hey are like a pitch that convince the user that the page is exactly what they're looking for." Here's one of the examples Google gives of a good meta description:

<meta name="description" content="Learn how to cook eggs with this complete guide in 1 hour or less. We cover all the methods, including: over-easy, sunny side up, boiled, and poached.">

To customize your page's meta descriptions using Sidecar:

  • On static pages and article pages, if the static page or article has a Description in its metadata then that will be used for the meta description. If not, then if the page or article has a Summary in its metadata that will be used. If neither Description or Summary is present in the page or article's metadata then the page will have no meta description.

    The difference between Description and Summary is that Description is used for the meta description tag only, whereas Summary's are also displayed below the page or article's title and in RSS and Atom feeds (see above).

    For example to add a meta description to a Markdown-based article:

    Title: Ruff Python formatting in Vim without plugins
    Tags: Python, Vim
    Description: The simplest way to integrate Ruff's Python code formatter into Vim.
    
    This is the body of the article...
    

    If you want to be able to write multi-line descriptions add "description" to the FORMATTED_FIELDS setting in your Pelican config:

    # pelicanconf.py
    
    FORMATTED_FIELDS = ["summary", "description"]

    Now you can add multi-line descriptions to pages and articles like this:

    Title: Ruff Python formatting in Vim without plugins
    Tags: Python, Vim
    Description:
        The simplest way to integrate Ruff's Python code formatter into Vim, no
        plugins or language servers needed. The same technique can also be used to
        integrate any command line formatter, for any file type.
    
    This is the body of the article...
    
  • If you add a SITEDESCRIPTION string to your site's Pelican config, Sidecar will use it as the meta description for your site's index page. Otherwise, Sidecar will fall back to the SITESUBTITLE setting.

  • Sidecar uses hard-coded meta descriptions for the archives page, period archives pages, tags/tag, categories/category and authors/author pages. For example the hard-coded meta description for the archives page is: "Archive of all posts."

    Each hard-coded meta description can be customized with a corresponding *_METADESCRIPTION setting in your site's Pelican config:

    # pelicanconf.py
    
    # The meta description for the archives page.
    ARCHIVES_METADESCRIPTION = "Archive of all posts."
    
    # The meta description string for the authors page.
    AUTHORS_METADESCRIPTION = "List of all authors with posts on this site."
    
    # The meta description string for the categories page.
    CATEGORIES_METADESCRIPTION = "List of all categories on this site."
    
    # The meta description string for the tags page.
    TAGS_METADESCRIPTION = "List of all tags on this site."
    
    # The meta description string for author pages.
    # {author} will be replaced with the name of the author.
    AUTHOR_METADESCRIPTION = "All posts by {author}."
    
    # The meta description string for category pages.
    # {category} will be replaced with the name of the category.
    CATEGORY_METADESCRIPTION = "All posts in category β€œ{category}”."
    
    # The meta description string for tag pages.
    # {tag} will be replaced with the name of the tag.
    TAG_METADESCRIPTION = "All posts with tag β€œ{tag}”."
    
    # The meta description string for period archive pages.
    # {periodstr} will be replaced with a string representing the period, e.g. "Jan 2026".
    PERIODARCHIVES_METADESCRIPTION = "All posts from {periodstr}."

Tables of contents

Sidecar uses Tocbot to generate tables of contents with anchor links from AnchorJS. I prefer this approach rather than using a Pelican plugin or Markdown extension to generate tables of contents because it's portable to other site generators and even to static HTML: just include AnchorJS and Tocbot in your pages and your tables of contents will work.

Insert a <div> with the CSS class toc anywhere in a page or article and it'll be turned into a table of contents based on the page or article's headers:

<!-- Tocbot will turn this div into a table of contents. -->
<div class="toc"></div>

If you want to omit a particular heading from the table of contents add the CSS class notoc to it:

<h2 class="notoc">Heading</h2>

Anchor links

The table of contents depends on all your headings having id attributes for anchor links. Sidecar uses AnchorJS to automatically generate id's for all your headings, with the id values based on the contents of the headings. If you want to control a heading's id value yourself (for example so it doesn't change if you re-word the heading), add an id attribute manually as normal and AnchorJS will use it instead of generating its own:

<h2 id="my-heading">My Heading</h2>

If you don't want a heading to have an anchor link, add the CSS class noanchor to it (this will also remove the heading from the table of contents):

<h2 class="noanchor">Heading</h2>

Per-page custom styles

You can add site-wide custom CSS to Sidecar using the STYLESHEET_URL and STYLESHEET settings. To add per-page or per-article CSS add a Stylesheet line to a page or article's metadata, this way you can style different pages and articles differently from each other:

Title: A Page or Article with a Custom Stylesheet
Stylesheet:
    :root {
      --ok-color-bg: #ff851b;
      --ok-color-fg: #85144b;
    }

Lorem ipsum dolor sit amet, consectetur adipiscing elit…

Modification dates

If you add a Modified date to an article's metadata it'll be shown in the article's tagline as its "updated" date:

Title: My Article
Date: 2015-11-12
Modified: 2015-12-05

You can see an example in this dummy article.

Static pages don't show any created or updated date by default, but if you add a Modified date to a static page's metadata it'll be shown at the bottom of the page as "Last updated". You can see an example on the demo site's About page.

Settings

SITEURL

You must set this to the base URL of your site with no trailing slash. It's used to generate URLs in feeds, links in the navbar, etc.

# pelicanconf.py

SITEURL = "http://blog.notmyidea.org"

ANALYTICS

Put any desired analytics scripts in this setting. Example:

# pelicanconf.py

ANALYTICS = """
    <script src="/theme/js/primary-analytics.js"></script>
    <script>
        [ … in-line Javascript code for secondary analytics … ]
    </script>
"""

DEFAULT_DATE_FORMAT

The format to use for page and article dates in Python strftime format. Sidecar looks best if DEFAULT_DATE_FORMAT is set to something that makes different dates (with different months and day numbers) roughly the same length, for example:

# pelicanconf.py

DEFAULT_DATE_FORMAT = "%b %d, %Y"

DEFAULT_LANG

Your site's default language, used for the standard lang attribute on the root <html> element. If not set this defaults to "en".

# pelicanconf.py

DEFAULT_LANG = "en"

DEFAULT_PAGINATION

The maximum number of articles to show per-page, on paginated pages. Set to False to disable pagination and show all articles on one page. See Pelican's docs on pagination.

# pelicanconf.py

DEFAULT_PAGINATION = 10

DISPLAY_PAGES_ON_MENU

Set this to True to add links to each of your site's static pages to the navbar. If SIDECAR_NAVBAR is set it overrides this setting.

# pelicanconf.py

DISPLAY_PAGES_ON_MENU = True

GITHUB_URL

If GITHUB_URL is set in your Pelican config then a GitHub icon linking to GITHUB_URL will be added to your site's navbar (as long as "GITHUB" is in your SIDECAR_NAVBAR setting). The idea is that you set GITHUB_URL to your GitHub profile page:

# pelicanconf.py

GITHUB_URL = "https://github.com/seanh"

SITENAME

Sets the name of your site in tab and feed titles:

# pelicanconf.py

SITENAME = "A Pelican Blog"

Avatar and bio: AVATAR_URL, SITESUBTITLE and SITEBIO

Sidecar's front page includes an optional "bio" section with an avatar image, site subtitle, and bio text. To make this appear add the AVATAR_URL, SITESUBTITLE and SITEBIO settings to your Pelican config. You can omit any one of these settings and its corresponding element will be omitted from the bio.

# pelicanconf.py

AVATAR_URL = "https://gravatar.com/avatar/bfda7359103e3879e16f65bed41ce848fb8c2e9ea44822fc7469984c19cb1902?s=72"
SITESUBTITLE = "I blog, you blog, weblog."
SITEBIO = '''Hi πŸ‘‹, I'm <a rel="author" href="{SITEURL}/about/">Sean</a>, a developer and future Portuguese Water Dog owner living in <s>Berlin</s>, <s>Edinburgh</s>.'''

Syntax highlighting: SIDECAR_PYGMENTS_THEME

Sidecar supports code blocks with syntax highlighting. See Syntax highlighting in Pelican's docs, and see the Pygments site for the list of available language names.

There are several ways to create syntax-highlighted code blocks but I recommend the "fenced code block" style because it also works on GitHub:

```python
def hello_world():
    print("Hello, world!")
```

You can add hl_lines to highlight certain lines within the code block:

```python hl_lines="1 3"
def hello_world():
    print("Hello, world!")
```

You can set your syntax highlighting color scheme with the SIDECAR_PYGMENTS_THEME setting:

# pelicanconf.py

SIDECAR_PYGMENTS_THEME = "monokai"

See this folder for all the available themes and see the Pygments site for previews of all the themes.

Set SIDECAR_PYGMENTS_BORDERLESS = True to remove the border from code blocks:

# pelicanconf.py

SIDECAR_PYGMENTS_BORDERLESS = True

Customizing Sidecar's colors, fonts, and CSS: STYLESHEET and STYLESHEET_URL

Oatcake provides several CSS variables for customizing the colors, fonts, etc. See Oatcake's site for docs. You can use the STYLESHEET and STYLESHEET_URL settings to inject your own site-wide CSS that changes these variables or just adds arbitrary CSS rules. You can also inject per-page/article CSS. Both Oatcake and Sidecar use CSS layers so your own custom CSS rules will take precedence regardless of specificity.

STYLESHEET

Just set STYLESHEET in your Pelican config to some custom CSS:

# pelicanconf.py

STYLESHEET = """
    :root {
      --ok-color-bg: #ff851b;
      --ok-color-fg: #85144b;
    }
"""

STYLESHEET_URL

First, add a CSS stylesheet to your site as static content then set STYLESHEET_URL to its URL, for example:

# pelicanconf.py

STYLESHEET_URL = "css/stylesheet.css"

Customizing the navbar with SIDECAR_NAVBAR

You can customize the contents of the navbar by adding a SIDECAR_NAVBAR setting (list of strings) to your Pelican config. For example:

# pelicanconf.py

SIDECAR_NAVBAR = [
    "HOME",
    "SPACE",
    "MENUITEMS",
    "PAGES",
    "CATEGORIES",
    "ARCHIVES",
    "GITHUB",
    '<a rel="external" href="https://example.com">Custom Link</a>',
]

Certain string values have special meanings in SIDECAR_NAVBAR:

  • HOME: inserts a link to your site's home page (uses Pelican's SITEURL and SITENAME settings).

  • SPACE: inserts a flexible space. All items after a SPACE will be right-aligned rather than left-aligned.

  • MENUITEMS: inserts the items from Pelican's MENUITEMS setting.

  • PAGES: inserts links to each of your site's static pages.

  • GITHUB: inserts a GitHub logo linking to your GITHUB_URL.

  • CATEGORIES: inserts a link to your site's categories page.

    For this to work you must add matching CATEGORIES_SAVE_AS and CATEGORIES_URL settings to your Pelican config. For example:

    # pelicanconf.py
    
    CATEGORIES_SAVE_AS = "categories/index.html"
    CATEGORIES_URL = "categories/"
  • TAGS: inserts a link to your site's tags page.

    For this to work you must add matching TAGS_SAVE_AS and TAGS_URL settings to your Pelican config. For example:

    # pelicanconf.py
    
    TAGS_SAVE_AS = "tags/index.html"
    TAGS_URL = "tags/"
  • AUTHORS: inserts a link to your site's authors page.

    For this to work you must add matching AUTHORS_SAVE_AS and AUTHORS_URL settings to your Pelican config. For example:

    # pelicanconf.py
    
    AUTHORS_SAVE_AS = "authors/index.html"
    AUTHORS_URL = "authors/"
  • ARCHIVES: inserts a link to your site's archives page.

    For this to work you must add matching ARCHIVES_SAVE_AS and ARCHIVES_URL settings to your Pelican config. For example:

    # pelicanconf.py
    
    ARCHIVES_SAVE_AS = "archives/index.html"
    ARCHIVES_URL = "archives/"

Items in SIDECAR_NAVBAR that don't match any of the special strings above are rendered directly. This lets you include your own raw HTML strings as menu items. For example, you could include a custom link. This lets you use HTML attributes other than href in your navbar links, which you can't do with Pelican's MENUITEMS:

# pelicanconf.py

SIDECAR_NAVBAR = [
    ...
    '<a rel="external" href="https://example.com">Custom Link</a>',
    '<a rel="license" href="{SITEURL}/license/">License</a>',
]

{SITEURL} in menu item strings will be replaced with Pelican's SITEURL setting.

Customizing article and page taglines and footers

You can customize the contents of the taglines above article and page titles and the footers at the bottoms of articles and pages with four settings in your Pelican config file: SIDECAR_ARTICLE_TAGLINE_ITEMS, SIDECAR_ARTICLE_FOOTER_ITEMS, SIDECAR_PAGE_TAGLINE_ITEMS, and SIDECAR_PAGE_FOOTER_ITEMS. The default values are:

# pelicanconf.py

SIDECAR_ARTICLE_TAGLINE_ITEMS = ["TIME", "TAGS"]
SIDECAR_ARTICLE_FOOTER_ITEMS = ["AUTHORS"]
SIDECAR_PAGE_TAGLINE_ITEMS = [] # No page tagline will be shown by default.
SIDECAR_PAGE_FOOTER_ITEMS = ["TIME"] # Shows 'Last updated' dates for pages that have Modified times.

Certain string values have special meanings in SIDECAR_{ARTICLE|PAGE}_{TAGLINE|FOOTER}_ITEMS settings:

  • AUTHORS: insert links to Pelican's author pages for the article's authors.

  • TIME: inserts the article's publication date/time.

    You can customize the format of dates with Pelican's DEFAULT_DATE_FORMAT and DATE_FORMATS settings.

  • CATEGORY: inserts a link to Pelican's category page for the article's category.

  • TAGS: inserts links to Pelican's tag pages for each of the article's tags, if any.

Items that don't match any of the special strings above are rendered directly, so you can include your own raw HTML strings:

Linking to article/page source files

If Pelican's OUTPUT_SOURCES setting is enabled Pelican includes the plaintext source files (e.g. Markdown files) of your articles and pages in your site.

Source links can be included in article or page taglines or footers by including "SOURCE" in the SIDECAR_{ARTICLE|PAGE}_{TAGLINE|FOOTER}_ITEMS settings.

Warning

This may cause URLs to the plain text versions of your articles to appear in search results! If you have control of your HTTP headers you can add an X-Robots-Tag: noindex header to prevent this. Otherwise you might consider not adding these links.

If you've changed Pelican's ARTICLE_SAVE_AS and ARTICLE_URL or PAGE_SAVE_AS and PAGE_URL settings from the defaults then you need to add ARTICLE_SOURCE_URL and PAGE_SOURCE_URL settings to your Pelican config to tell Sidecar how to generate the URLs to your article and page source files. For example:

# pelicanconf.py

ARTICLE_SAVE_AS = '{date:%Y}/{date:%m}/{date:%d}/{slug}/index.html'
ARTICLE_URL = '{date:%Y}/{date:%m}/{date:%d}/{slug}/'
ARTICLE_SOURCE_URL = "{article.url}index{OUTPUT_SOURCES_EXTENSION}"

PAGE_SAVE_AS = '{slug}/index.html'
PAGE_URL = '{slug}/'
PAGE_SOURCE_URL = "{page.url}index{OUTPUT_SOURCES_EXTENSION}"

Template Customization

You can customize the Sidecar theme by using Pelican's THEME_TEMPLATES_OVERRIDES setting to override some of Sidecar's templates.

When overriding a template you can inherit from one of the theme's templates with {% extends '!theme/<template>.html' %} and then override some of the template's blocks with {% block %}. When overriding a block you can call the template's original block with {{ super() }}.

Adding a favicon

Let's work through an example of using template customization to add a favicon to a site:

  1. Generate some favicon images for your site. You can start with an image or photo and use a favicon generator site like https://realfavicongenerator.net/ to convert it into favicon files in the right formats.

  2. Add the favicon images to your site's content/images/ directory as static content.

  3. Create a templates directory in your site, to hold your custom templates:

    mkdir -p templates
    
  4. Add the THEME_TEMPLATES_OVERRIDES setting to your Pelican config file:

    # pelicanconf.py
    
    THEME_TEMPLATES_OVERRIDES = ["templates"]
  5. Add a templates/base.html file, something like this:

    {# templates/base.html #}
    
    {% extends '!theme/base.html' %}
    
    {% block head %}
      {{ super() }}
    
      <link rel="icon" type="image/png" href="{{ SITEURL }}/images/favicon-96x96.png" sizes="96x96" />
      <link rel="icon" type="image/svg+xml" href="{{ SITEURL }}/images/favicon.svg" />
      <link rel="shortcut icon" href="{{ SITEURL }}/images/favicon.ico" />
      <link rel="apple-touch-icon" sizes="180x180" href="{{ SITEURL }}/images/apple-touch-icon.png" />
    {% endblock %}

That's it--your site should now have a favicon!

What the base.html template does is:

  1. Overrides Sidecar's base.html template.
  2. Uses {% extends %} to inherit from Sidecar's base.html template.
  3. Uses {% block %} to override the head block in Sidecar's base.html template.
  4. Uses {{ super() }} to call the base template's head block.
  5. Finally, adds some HTML to the head block to inject the favicons into the site.

Customizing the search bar

Sidecar puts a search bar on the archives page that, by default, uses Google to search your site. You can customize the search bar by overriding the search.html template. For example to change the search to use Duck Duck Go you could add a templates/search.html file to your site, like this:

{# templates/search.html #}

<form method="get" action="https://duckduckgo.com/" class="search">
  <input type="hidden" name="sites" value="{{ SITEURL }}" />
  <input type="search" name="q" placeholder="Full-text search&hellip;" aria-label="Full-text search" />
</form>

If you simply want to remove the search bar, just add an empty templates/search.html file to your site.

About

A plain but pretty Pelican theme based on Oatcake.

Topics

Resources

License

Stars

Watchers

Forks

Contributors 4

  •  
  •  
  •  
  •