A Bulma-based Pelican blog theme; clean, flexible and responsive.

  • By Jonathan Sharpe
  • Last update: Jan 4, 2023
  • Comments: 13


A Bulma-based Pelican blog theme; clean, flexible and responsive.

Screenshot - Bulrush at 1440px

The icons are from Font Awesome by Dave Gandy. The pure HTML/CSS "Fork me on GitHub" ribbon is based on github-fork-ribbon-css by Simon Whitaker; I modified it to be flatter.


  • Responsive design - four column layout on desktop (≥980px), three column on tablet (≥769px), single column on mobile. Tabbed navigation bar collapses into drop-down "burger menu" on mobile.

  • Meta tagging functionality - support for Open Graph and Twitter Cards meta tags, giving enhanced display when sharing articles on social media sites (note: currently only available for articles and pages).

  • Printable layouts - the navigation is hidden when printed, avoiding wasted space.

  • Custom styling - additional CSS files can be included to customise the default styling.

  • Service integrations - including Disqus, GitHub, Google Analytics and MailChimp.

  • PyPI package available - so it can be pip install-ed.


Bulrush is available via the Python Package Index, so you can install it with:

pip install bulrush

The main exports from the module are:

  • PATH: the path to the theme;
  • FILTERS: the additional Jinja filters used by the theme; and
  • ENVIRONMENT: the Jinja environment required by the theme.

You can use them in your pelicanconf.py as follows:

import bulrush

THEME = bulrush.PATH

Other Requirements

You need to make the appropriate Pelican plugin, assets, available. One way of achieving this is to make the pelican-plugin repository a submodule of your site, then you can add to your pelicanconf.py:

PLUGIN_PATHS = ['pelican-plugins']
PLUGINS = ['assets']

Note: referencing the Pelican plugins in this way may have implications for the license of your project. See https://github.com/textbook/bulrush/issues/17.


If you don't want to install the theme from PyPI you can simply give Pelican a relative path to the inner bulrush/ directory. For example, add bulrush as a submodule and set:

THEME = 'bulrush/bulrush'

In this case you will need to configure the environment and filters yourself and ensure that webassets is installed from PyPI.

Additional Screenshots

  • 480 x 480px (mobile):

    Screenshot - Bulrush at 480px

  • 840 x 480px (tablet):

    Screenshot - Bulrush at 840px

  • 980 x 480px (desktop):

    Screenshot - Bulrush at 980px


As well as the basic settings, Bulrush supports the following options in your pelicanconf.py:

Setting name What does it do?
BULRUSH_SHOW_SUMMARY A boolean, whether to show a summary rather than full article on index, category and tag pages. Defaults to False.
DISQUS_SITENAME Enables Disqus comments. Note that you should set up the full Comment Count Link, as no additional text is applied.
GITHUB_URL Enables the "Fork me on GitHub" ribbon.
GOOGLE_ANALYTICS Set to 'UA-XXXX-YYYY' to activate Google Analytics.
LICENSE A string or dictionary describing the license for the site; see details below.
LINKS A list of tuples ('Title', 'URL') for links to appear in the "blogroll" section of the sidebar.
MAILCHIMP Configure to activate a MailChimp sign-up form; see details below.
MENUITEMS A list of tuples ('Title', 'URL') for items to appear in the tabbed navigation.
SITESUBTITLE A subtitle to appear in the header.
SOCIAL A list of tuples ('Title', 'URL') to appear in the "social" section of the sidebar.
TWITTER_USERNAME Enables Twitter meta-tags in the article and page headers.

If DISPLAY_CATEGORIES_ON_MENU is omitted or set explicitly to True, the categories are shown in the tabbed navigation with any MENUITEMS. If DISPLAY_PAGES_ON_MENU is omitted or set explicitly to True, they are listed in the sidebar with any SOCIAL or other LINKS.

Social Links

Appropriate icons are provided in the sidebar for a range of sites in the SOCIAL link list. Have a look in social.html to see which titles this applies to. If none of the sites are a match, then:

  • if the second, URL element in the tuple starts with 'mailto:', an envelope icon is used; otherwise
  • a globe icon is used.

Screenshot - Social icons in sidebar

MailChimp Configuration

If you're using MailChimp to handle a mailing list for your blog, you can configure a subscription form in the sidebar. You need to set three values to enable this, which you can get from the signup form creator. Simply look for the form action:

<form action="//user.region.list-manage.com/subscribe/post?u=abc123&amp;id=def456" ...

and extract the relevant sections:

    validation=True,  # enable jQuery validation

If you set validation=False (or leave it out entirely) you will reduce the page load (as it won't need 140KB of JavaScript) but won't get inline form submission or email validation.

You can also add rewards_url, providing your unique MonkeyRewards URL, to enable a "Powered by MailChimp" link.

License Settings

You can provide one of two options to specify the license for your content:

  • License name (str): The name of the license to display. Unless otherwise specified, a default icon (file-text-o) will be used and the entry will link to the current page.

    Creative Commons license names (e.g. 'CC BY-SA 4.0') are automatically recognised and an appropriate icon and link are generated.

  • License definition (dict): A dictionary specifying the name, url and optional icon (must be a Font Awesome icon name, default is file-text-o).

The license details will be displayed at the bottom of the sidebar on every page.

Custom Styling

If any of the entries in EXTRA_PATH_METADATA have 'path's ending with '.css' they will be included in the base template, allowing the site style to be overridden as required. For example, in your pelicanconf.py:

# Static files
    'extra/custom.css': {'path': 'custom.css'},

In use

Here are few current users of Bulrush (or modified versions of it):

If you'd like to be featured here (or are and would prefer not to be), feel free to submit a pull request.




  • 1

    Rendering issue when Embedding jupyter notebook or html scripts

    I have been enjoying this theme for quite a time until I tried to embed a Jupyter notebook or a Python trinket. Only a small portion of the notebook or code is rendered and the rest is cut. I tried to solve this but have no luck yet. I tried in other themes and it works perfectly but I don't want to switch to another theme again. Can anyone solve this issue?

  • 2

    document way to change colors

    As a user who hasn't touched front end development for a couple years and picked this theme off the shelf because I liked its looks, I would like to be able to quickly and easily change the colors, starting with the most obvious ('primary') color. It would be really great if the words 'npm install' were not within a light year of a viable solution to this.

    I saw issue #12 but don't really understand it as I am not familiar with the (evidently teeming) ecosystem of programs involved in generating CSS these days - I just want to change the default color on my blog.

    (Overriding with the example of content/extra/custom.css I do understand, but either I'm looking in the wrong places, or the Bulma docs are lacking on which classes would be best overridden.)

  • 3

    License somewhat misleading

    This project is licensed under ISC, but has a hard requirement on pelican-plugins/asssets, which is under the viral AGPL license, and cannot (as far as I can tell) be pip installed. IANAL but I'm fairly sure that vendoring pelican-plugins/assets as is suggested in the documentation would trigger the share-alike provisions of the AGPL, and so as documented, this project is effectively under AGPL.

    Ideally either assets would be dropped (replaced or otherwise) or the documentation updated to show how to set up assets such that it does not trigger these viral provisions. In any case, it's probably worth highlighting (possibly early on) that something like this might be a problem.

  • 4

    Support more SOCIAL item icons

    Currently only the following are supported:

    • Bitbucket
    • GitHub
    • Stack Overflow
    • Twitter

    Many others are provided in Font Awesome, so the list could be extended. It's easy to add them to the mapping, but this could be extracted to a separate template to make this simpler.

  • 5

    Formatting for headings and lists in pages?


    Thanks for a great theme! I was setting up our web-space and on the pages, the various sections and lists don't seem to be formatted correctly as they are in articles:


    We're using version bulrush==0.4.0 here. Is this a known issue perhaps?


  • 6

    JINJA_FILTERS FilterError

    I have the theme set up followed the steps in Readme file, but when I use the command pelican content I have the following error: CRITICAL: FilterError: ExternalTool: subprocess returned a non-success result code: 1, stdout=b'', stderr=b"'java' is not recognized as an internal or external command,\r\noperable program or batch file.\r\n"

    My node.js version is v8.11.4 Python == 3.7.0 bulrush==0.2.1 pelican==3.7.1 webassets==0.12.1

    I also tried run bulrush.FILTERS under my python environment and I got the following result: {'images': <function extract_images at 0x00000178C165A598>, 'license': <function generate_license at 0x00000178C16BC6A8>, 'schema': <function generate_jsonld_schema at 0x00000178C16BC730>}

    Please help! Thanks a lot!

  • 7

    Easy way to change the main color?

    I was poking around the theme trying to find an easy way to change main color and came across https://github.com/textbook/bulrush/blob/master/static/css/main.less#L4

    However changing that value didn't seem to do anything.. What am I missing?

  • 8

    Layout and text of right-menu bar

    Showing "Other Pages" above "Links" and "Social" seems to be out of order, especially since most people won't use Atom/RSS.


    I'd propose a setting in pelicanconf.py that allows the user to rename these titles (aka "Other Pages" becomes "Feeds") and also change the order of items on the right-menu bar.

  • 9

    remove badge from Bulma.io that was leaving cookie

    based on this issue https://github.com/textbook/bulrush/issues/20

    I removed the link to the bulma.io hosted badge, which was leaving a cookie on the user's machine. I've replaced with "Made with Bulma" with a link to bulma.io

  • 10

    request to bulma.io is leaving a cookie

    The request to bulma.io for this image:


    Is leaving the cookie "cfduid" on the browser of website visitors:


    This cookie is from CloudFlare and is not for tracking, and is for determining unique users with a common IP. It's been discussed here.

    Is it possible to host the image locally? Or to use only text "Made with Bulma" with a link? Or to point to an image hosted on a site that doesn't leave a cookie?

  • 11

    Page menu fixes

    These commits strip the HTML tags from page titles, and has the next and previous page links point to the current page rather than the home page, when there are no further pages of articles to see

  • 12

    Ability to left-justify the menu

    Hello, I would like it if the menu was able to be left-justified and inline with the website's title in the top-left.

    Something like this (please ignore the bizarre name): image

    Do I have to use custom CSS for this? Would this be appropriate as a config option? If so, I'd be willing to try and contribute it.

  • 13

    Pagination implies you've already reached the end

    When you look at a paginated view of the articles (e.g. tag page), it always looks like you've reached the end because the articles don't fill up the space available.

    This is due to a combination of:

    • the DEFAULT_PAGINATION = 5 setting on the example blog, the documentation should recommend a multiple of 6 be used (to neatly fit the 3 -> 2 -> 1 responsive layout); and
    • on the first page (arguably the worst place to imply you've reached the end!) one article is taken out to be the larger preview.

    The latter is handled by:


    I'm not sure of the best way to do that - the page sizes are always going to be consistent, I don't see a way to say "x + 1 for the first page and x thereafter" - that leaves either repeating the first item (once in the preview, once in the list) or simply omitting the expanded preview entirely.

    First page

    Screenshot 2021-07-23 at 11 39 59

    Nth page

    Screenshot 2021-07-23 at 11 40 08