Tips

Here are some tips about Pelican that you might find useful.

Custom 404 Pages

When a browser requests a resource that the web server cannot find, the web server usually displays a generic “File not found” (404) error page that can be stark and unsightly. One way to provide an error page that matches the theme of your site is to create a custom 404 page (not an article), such as this Markdown-formatted example stored in content/pages/404.md:

Title: Not Found
Status: hidden
Save_as: 404.html

The requested item could not be located. Perhaps you might want to check
the [Archives](/archives.html)?

The next step is to configure your web server to display this custom page instead of its default 404 page. For Nginx, add the following to your configuration file’s location block:

error_page 404 /404.html;

For Apache:

ErrorDocument 404 /404.html

For Amazon S3, first navigate to the Static Site Hosting menu in the bucket settings on your AWS console. From there:

Error Document: 404.html

Publishing to GitHub Pages

If you use GitHub for your Pelican site you can publish your site to GitHub Pages for free. Your site will be published to https://<username>.github.io if it’s a user or organization site or to https://<username>.github.io/<repository> if it’s a project site. It’s also possible to use a custom domain with GitHub Pages.

There are two ways to publish a site to GitHub Pages:

  1. Publishing from a branch: run pelican locally and push the output directory to a special branch of your GitHub repo. GitHub will then publish the contents of this branch to your GitHub Pages site.

  2. Publishing with a custom GitHub Actions workflow: just push the source files of your Pelican site to your GitHub repo’s default branch and have a custom GitHub Actions workflow run pelican for you to generate the output directory and publish it to your GitHub Pages site. This way you don’t need to run pelican locally. You can even edit your site’s source files using GitHub’s web interface and any changes that you commit will be published.

Publishing a Project Site to GitHub Pages from a Branch

To publish a Pelican site as a Project Page you need to push the content of the output dir generated by Pelican to a repository’s gh-pages branch on GitHub.

The excellent ghp-import, which can be installed with pip, makes this process really easy.

For example, if the source of your Pelican site is contained in a GitHub repository, and if you want to publish that Pelican site in the form of Project Pages to this repository, you can then use the following:

$ pelican content -o output -s pelicanconf.py
$ ghp-import output -b gh-pages
$ git push origin gh-pages

The ghp-import output command updates the local gh-pages branch with the content of the output directory (creating the branch if it doesn’t already exist). The git push origin gh-pages command updates the remote gh-pages branch, effectively publishing the Pelican site.

Note

The github target of the Makefile (and the gh_pages task of tasks.py) created by the pelican-quickstart command publishes the Pelican site as Project Pages, as described above.

Publishing a User Site to GitHub Pages from a Branch

To publish a Pelican site in the form of User Pages, you need to push the content of the output dir generated by Pelican to the main branch of your <username>.github.io repository on GitHub.

Again, you can take advantage of ghp-import:

$ pelican content -o output -s pelicanconf.py
$ ghp-import output -b gh-pages
$ git push git@github.com:elemoine/elemoine.github.io.git gh-pages:main

The git push command pushes the local gh-pages branch (freshly updated by the ghp-import command) to the elemoine.github.io repository’s main branch on GitHub.

Note

To publish your Pelican site as User Pages, feel free to adjust the github target of the Makefile.

Another option for publishing to User Pages is to generate the output files in the root directory of the project.

For example, your main project folder is <username>.github.io and you can create the Pelican project in a subdirectory called Pelican. Then from inside the Pelican folder you can run:

$ pelican content -o .. -s pelicanconf.py

Now you can push the whole project <username>.github.io to the main branch of your GitHub repository:

$ git push origin main

(assuming origin is set to your remote repository).

Publishing to GitHub Pages Using a Custom GitHub Actions Workflow

Pelican-powered sites can be published to GitHub Pages via a custom workflow. To use it:

  1. Enable GitHub Pages in your repo: go to Settings → Pages and choose GitHub Actions for the Source setting.

  2. Commit a .github/workflows/pelican.yml file to your repo with these contents:

    name: Deploy to GitHub Pages
    on:
      push:
        branches: ["main"]
      workflow_dispatch:
    jobs:
      deploy:
        uses: "getpelican/pelican/.github/workflows/github_pages.yml@main"
        permissions:
          contents: "read"
          pages: "write"
          id-token: "write"
        with:
          settings: "publishconf.py"
    

    You may want to replace the @main with the ID of a specific commit in this repo in order to pin the version of the reusable workflow that you’re using: uses: getpelican/pelican/.github/workflows/github_pages.yml@<COMMIT_ID>. If you do this you might want to get Dependabot to send you automated pull requests to update that commit ID whenever new versions of this workflow are published, like so:

    # .github/dependabot.yml
    version: 2
    updates:
      - package-ecosystem: "github-actions"
        directory: "/"
        schedule:
          interval: "monthly"
    

    See GitHub’s docs about using Dependabot to keep your actions up to date.

  3. Go to the Actions tab in your repo (https://github.com/<username>/<repository>/actions) and you should see a Deploy to GitHub Pages action running.

  4. Once the action completes you should see your Pelican site deployed at your repo’s GitHub Pages URL: https://<username>.github.io for a user or organization site or https://<username>.github.io/<repository>> for a project site.

Notes:

  • You don’t need to set SITEURL or FEED_DOMAIN in your Pelican settings: the workflow will set them correctly for you

  • You don’t need to commit your --output / OUTPUT_PATH directory (output/) to git: the workflow will run pelican to build the output directory for you on GitHub Actions

See GitHub’s docs about reusable workflows for more information.

A number of optional inputs can be added to the with: block when calling the workflow, for example:

with:
  settings: "publishconf.py"
  requirements: "pelican[markdown] typogrify"
  theme: "https://github.com/seanh/sidecar.git"
  python: "3.12"

Here’s the complete list of workflow inputs:

Name

Required

Description

Type

Default

settings

Yes

The path to your Pelican settings file (pelican’s --settings option), for example: "publishconf.py"

string

requirements

No

The Python requirements to install, for example to enable markdown and typogrify use: "pelican[markdown] typogrify" or if you have a requirements file: "-r requirements.txt"

string

"pelican"

output-path

No

Where to output the generated files (pelican’s --output option)

string

"output/"

theme

No

The GitHub repo URL of a custom theme to use, for example: "https://github.com/seanh/sidecar.git"

string

""

python

No

The version of Python to use to build the site, for example: "3.12" (to use the most recent version of Python 3.12, this is faster) or "3.12.1" (to use an exact version, slower)

string

"3.12"

siteurl

No

The base URL of your web site (Pelican’s SITEURL setting). If not passed this will default to the URL of your GitHub Pages site, which is correct in most cases.

string

The URL of your GitHub Pages site.

feed_domain

No

The domain to be prepended to feed URLs (Pelican’s FEED_DOMAIN setting). If not passed this will default to the URL of your GitHub Pages site, which is correct in most cases.

string

The URL of your GitHub Pages site.

deploy

No

This is used to determine whether you will deploy the site or not to GitHub Pages. This is most useful if you want to test a change to your website in a pull request before deploying those change.

bool

true

Testing Your Build in a GitHub Pull Request

If you want to test your build in a pull request before deploying to GitHub, your workflow might look something like this:

name: Build and Deploy Site
on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]
  workflow_dispatch:
    inputs:
      deploy:
        required: false
        default: true
        description: "Whether to deploy the site. If checked, then build the site and deploy it. If not checked, then just test that the site builds successfully but don't deploy anything."
        type: boolean
jobs:
  deploy:
    uses: "getpelican/pelican/.github/workflows/github_pages.yml@main"
    permissions:
      id-token: write
      contents: read
      pages: write
    with:
      settings: "publishconf.py"
      requirements: "-r requirements.txt"
      deploy: ${{ (github.event_name == 'workflow_dispatch' && inputs.deploy == true) || (github.event_name == 'push' && github.ref_type == 'branch' && github.ref_name == github.event.repository.default_branch) }}

The on section of the workflow defines the events that will trigger the workflow. In this example, the workflow will run on pushes to the main branch, pull requests to the main branch, and manual runs of the workflow.

workflow_dispatch defines the deploy boolean to be true by default. This means that if you run the workflow manually, it will deploy the site.

The deploy input for the job is using a set of standard GitHub workflow variables to control when deploy will either be true or false (you can customize this to your needs).

In this example, the deploy will be true if the event is a push to the main branch (or merging into main from a PR) or a manual run of the workflow. If the event is a pull request, the deploy will be false and it will only build an artifact for the site.

“Insecure content” warnings from browsers

If your site uses https:// and is broken because the browser is blocking network requests (for example for CSS files) due to “insecure content” this may be because GitHub Pages is generating http:// URLs for your site.

To fix this go into your site repo’s settings and enable the Enforce HTTPS setting: go to Settings → Pages and check Enforce HTTPS. Then re-run the workflow to re-deploy your site. Alternatively, you can use the workflow’s siteurl and feed_domain settings.

Custom 404 Pages

GitHub Pages will display the custom 404 page described above, as noted in the relevant GitHub docs.

Update your site on each commit

To automatically update your Pelican site on each commit, you can create a post-commit hook. For example, you can add the following to .git/hooks/post-commit:

pelican content -o output -s pelicanconf.py && ghp-import output && git push origin gh-pages

Copy static files to the root of your site

To use a custom domain with GitHub Pages, you need to put the domain of your site (e.g., blog.example.com) inside a CNAME file at the root of your site. To do this, create the content/extra/ directory and add a CNAME file to it. Then use the STATIC_PATHS setting to tell Pelican to copy this file to your output directory. For example:

STATIC_PATHS = ['images', 'extra/CNAME']
EXTRA_PATH_METADATA = {'extra/CNAME': {'path': 'CNAME'},}

Note: use forward slashes, /, even on Windows.

You can also use the EXTRA_PATH_METADATA mechanism to place a favicon.ico or robots.txt at the root of any site.

How to add YouTube or Vimeo Videos

The easiest way is to paste the embed code of the video from these sites directly into your source content.

Alternatively, you can also use Pelican plugins like liquid_tags, pelican_youtube, or pelican_vimeo to embed videos in your content.

Moreover, markup languages like reST and Markdown have plugins that let you embed videos in the markup. You can use reST video directive for reST or mdx_video plugin for Markdown.

Develop Locally Using SSL

Here’s how you can set up your local pelican server to support SSL.

First, create a self-signed certificate and key using openssl (this creates cert.pem and key.pem):

$ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes

And use this command to launch the server (the server starts within your output directory):

python -m pelican.server 8443 --key=../key.pem --cert=../cert.pem

If you are using develop-server.sh, add this to the top:

CERT="$BASEDIR/cert.pem"
KEY="$BASEDIR/key.pem"

and modify the pelican.server line as follows:

$PY -m pelican.server $port --ssl --cert="$CERT" --key="$KEY" &