dmesg --follow
[ 67100100.000 ] posts.x: Am I in the minority using Sol as my daily driver in Codex?  |   [ 67097280.000 ] posts.x: Full talk on why MCP's context problems are a harness issue, not a protocol issue, and what MCPC does about it:  |   [ 67097280.000 ] posts.x: A lot of the AI world spent the past year calling MCP dead, Anthropic included, with Theo, Gary Tan, and Peter Levels all piling on, even as MCP…  |   [ 67037100.000 ] posts.x: @TheZachMueller Nice one! That’s a warm room, just in time for winter.  |   [ 67035060.000 ] posts.x: Full talk on turning scattered engineering judgment, feature-flag agent included, into something a coding agent can actually use:  |   [ 67035060.000 ] posts.x: A team held a recurring meeting every two weeks for one purpose: deleting feature flags nobody needed anymore. @aorobator, a Senior Software Engineer…  |   [ 67034100.000 ] posts.x: Full talk on Greptile's AI-generated PR data, agent revert rates, and the three-question framework behind merging without human review:  |   [ 67034100.000 ] posts.x: A quarter of the pull requests Greptile reviews every month are now completely or largely AI generated, up from under 1% early last year. @greptile…  |   [ 67018080.000 ] posts.x: Full talk on rumors hardening into facts inside a multi-agent village, and the auto-research loop built to catch it:  |   [ 67018080.000 ] posts.x: A rumor that one agent "might leave" can harden into "is leaving" as it spreads through a multi-agent village, with nobody noticing the shift from…  |   [ 67010820.000 ] posts.x: Full talk on building the harness, from reward hacking to bare metal tuning, behind a 3x kernel speedup:  |   [ 67010820.000 ] posts.x: GPU kernels turn out to be an unusually good match for an agent loop: there's a clear benchmark, and a result that's either faster and correct or it…  |   [ 66968520.000 ] posts.x: Full talk on pitting Claude Code, Codex, and Kimi against a human speedrun record, and why none of them found a novel optimizer to win it:  |   [ 66968520.000 ] posts.x: Two coding agents went up against a community speedrun that human researchers spent two years grinding down, and neither one found a genuinely novel…  |  
corey@gallon.me:~/til$

How to Add Custom HTML Pages to a Pelican Site

FIGURE 1 ⋅ How to Add Custom HTML Pages to a Pelican Site

Introduction

Pelican is a powerful static site generator written in Python, primarily designed for blogs. However, sometimes you need to include custom HTML pages that don't fit into Pelican's standard content model. This guide explains how to add standalone HTML pages to your Pelican site while preserving their exact formatting and functionality.

Method: Using Static Files

The most reliable method for adding custom HTML pages to a Pelican site is to use the static files approach. This method bypasses Pelican's content processing system and treats your HTML file as a static asset.

Step 1: Create a Static Directory

First, create a static directory inside your Pelican project's content folder:

mkdir -p content/static

Step 2: Add Your HTML File

Copy your custom HTML file to the static directory:

cp your-custom-page.html content/static/

Step 3: Configure Pelican

Edit your pelicanconf.py file to include the following settings:

# Include static directory in static paths
STATIC_PATHS = ['images', 'static']  # Add other paths as needed

# Exclude static directory from content processing
ARTICLE_EXCLUDES = ['static']
PAGE_EXCLUDES = ['static']

# Optional: Configure a specific URL for your page
EXTRA_PATH_METADATA = {
    'static/your-custom-page.html': {'path': 'custom-page/index.html'},
}

This configuration does three important things:

  • STATIC_PATHS tells Pelican to copy files from the static directory to the output
  • ARTICLE_EXCLUDES and PAGE_EXCLUDES prevent Pelican from trying to process the files as content
  • EXTRA_PATH_METADATA allows you to specify a custom output path for your HTML file

Step 4: Build Your Site

Now when you build your Pelican site, your custom HTML page will be copied to the output directory:

pelican content

Your page will be accessible at yourblog.com/custom-page/.

Why This Works

This approach works because:

  • Bypasses Content Processing: By excluding the static directory from content processing, Pelican won't try to parse your HTML file for metadata or apply templates to it.

  • Preserves Original HTML: Your HTML file is copied as-is to the output directory, preserving all styling, scripts, and functionality.

  • Custom URL Structure: Using EXTRA_PATH_METADATA allows you to place the file at any URL path you want, creating clean URLs without the .html extension.

Common Issues and Solutions

Issue: Pelican tries to process HTML as content
Solution: Make sure you've added the static directory to both ARTICLE_EXCLUDES and PAGE_EXCLUDES.

Issue: CSS or JavaScript paths are broken
Solution: If your HTML file references relative paths for CSS or JavaScript, you may need to adjust them to work with your site's URL structure.

Issue: HTML file not showing up in output
Solution: Verify that you've added the static directory to STATIC_PATHS and that the file exists in the correct location.

Advanced: Linking to Your Custom Page

To link to your custom page from your Pelican site's navigation menu, you'll need to modify your theme's templates. Most themes use a variable like MENUITEMS in the pelicanconf.py file:

MENUITEMS = [
    ('Home', '/'),
    ('Blog', '/blog/'),
    ('Custom Page', '/custom-page/'),
]

Integrating Custom Pages with Site Navigation

After adding your custom HTML page to your Pelican site, you'll likely want to make it accessible through your site's navigation menu. There are several ways to accomplish this, depending on your theme and navigation preferences.

Using MENUITEMS for Basic Navigation

The simplest approach is to use Pelican's built-in MENUITEMS configuration variable, which most themes support. In your pelicanconf.py file, add or modify the MENUITEMS list:

MENUITEMS = [
    ('Home', '/'),
    ('Blog', '/blog/'),
    ('Custom Page', '/custom-page/'),  # This links to your custom HTML page
]

Each tuple contains two elements: 1. The display name that will appear in your menu 2. The URL path to the page (which should match what you configured in EXTRA_PATH_METADATA)

If your theme automatically displays categories in the navigation menu, you'll need to consider how static menu items and dynamic category links will interact. Here are some common configurations:

Option 1: Disable Category Menu Items

If you prefer to manually control all menu items, you can disable automatic category links:

# Disable automatic category links in menu
DISPLAY_CATEGORIES_ON_MENU = False

# Define your custom menu structure
MENUITEMS = [
    ('Home', '/'),
    ('Blog', '/blog/'),
    ('Categories', '/categories/'),  # Link to category index if available
    ('Custom Page', '/custom-page/'),
]

Option 2: Keep Both Systems

Many themes will gracefully handle both static menu items and dynamic category links, placing MENUITEMS first, followed by category links:

# Keep automatic category links enabled (default behavior)
# DISPLAY_CATEGORIES_ON_MENU = True  # This is usually the default

# Define static menu items
MENUITEMS = [
    ('Home', '/'),
    ('Blog', '/blog/'),
    ('Custom Page', '/custom-page/'),
]

Theme-Specific Navigation

Some themes implement custom navigation systems that don't rely solely on MENUITEMS. In these cases, consult your theme's documentation or examine its template files to understand how to integrate custom pages.

For example, the popular theme "Flex" uses a variable called MAIN_MENU with a more complex structure:

MAIN_MENU = True
MENUITEMS = (
    ('Home', '/'),
    ('Custom Page', '/custom-page/'),
    ('Categories', (
        ('Category 1', '/category/category-1/'),
        ('Category 2', '/category/category-2/'),
    )),
)

Testing Your Navigation

Whenever you modify your menu configuration, test your site by regenerating it:

pelican content

Then check the navigation links in your local development server to ensure they work as expected.

Troubleshooting Common Issues

Issue: Menu items don't appear
Check if your theme supports MENUITEMS or requires a different variable. Some themes require MAIN_MENU = True to be set as well.

Issue: Links don't work correctly
Verify that your URL paths match the structure defined in EXTRA_PATH_METADATA. Remember that if you're using RELATIVE_URLS = True for development, your paths will be relative.

Issue: Unexpected menu order
If categories are appearing between your static menu items, you may need to override your theme's template files to control the precise ordering.

Conclusion

Using the static files approach is the most straightforward way to add custom HTML pages to your Pelican site. It preserves the original HTML without modification, allows for custom URL structures, and integrates seamlessly with the rest of your site.

This method is particularly useful for: - Interactive pages with complex JavaScript - HTML generated by other tools - Pages with custom styling that shouldn't be affected by your site's theme - Embedding third-party applications or widgets

By following these steps, you can extend your Pelican site beyond its standard blog functionality while maintaining full control over your custom HTML content.

corey@gallon.me:~$ tail -f /writing Attach to the stream. An email when I have something worth sending. Replies encouraged!
corey@gallon.me:~$ ls -lt /til ↑2025-03-18 Founders #383: Todd Graves' $10B Chicken Finger Dream
▸2025-02-27 How to Add Custom HTML Pages to a Pelican Site ⋅ you are here
↓2025-02-22 AI Engineer Summit 2025: Agents at Work