CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pelican

Static site generator supporting Markdown and reStructuredText

Pending
Overview
Eval results
Files

cli-tools.mddocs/

Command-Line Tools

Specialized CLI utilities for site setup, content import, theme management, and plugin operations. These tools provide convenient interfaces for common Pelican workflow tasks.

Capabilities

pelican-quickstart

Interactive site setup tool that creates initial project structure, configuration files, and basic content templates.

def main() -> None:
    """
    Main entry point for pelican-quickstart command.
    
    Provides interactive prompts for:
    - Site title and author information
    - URL structure and paths
    - Timezone and language settings
    - Theme selection
    - Plugin preferences
    - Makefile and automation setup
    """

Command usage:

pelican-quickstart

Features:

  • Interactive setup wizard with sensible defaults
  • Creates project directory structure
  • Generates pelicanconf.py configuration file
  • Creates publishconf.py for production settings
  • Optional Makefile and Fabric scripts for automation
  • Sample content creation

pelican-import

Content import utility supporting multiple blog platforms and formats for migrating existing content to Pelican.

def main() -> None:
    """
    Main entry point for pelican-import command.
    
    Supports importing from:
    - WordPress XML exports
    - Blogger XML exports
    - Tumblr API
    - Medium posts
    - RSS/Atom feeds
    - Dotclear exports
    - Posterous backups
    """

Command usage:

# WordPress import
pelican-import --wordpress wordpress-export.xml -o content/

# Blogger import  
pelican-import --blogger blogger-export.xml -o content/

# RSS feed import
pelican-import --feed https://example.com/feed.xml -o content/

# Tumblr import (requires API key)
pelican-import --tumblr myblog.tumblr.com -o content/

Import Features:

  • Automatic metadata extraction and conversion
  • Image and media file downloading
  • Tag and category mapping
  • Content format conversion (HTML to Markdown optional)
  • Duplicate detection and handling
  • Custom field preservation

pelican-themes

Theme management utility for installing, removing, and listing Pelican themes.

def main() -> None:
    """
    Main entry point for pelican-themes command.
    
    Operations:
    - Install themes from local directories or Git repositories
    - Remove installed themes
    - List available and installed themes
    - Symlink themes for development
    - Theme validation and compatibility checking
    """

Command usage:

# Install theme from directory
pelican-themes --install path/to/theme/

# Install theme from Git repository
pelican-themes --install https://github.com/user/theme.git

# Install and symlink for development
pelican-themes --install --symlink path/to/theme/

# List installed themes
pelican-themes --list

# Remove theme
pelican-themes --remove theme-name

# Get theme information
pelican-themes --info theme-name

Theme Operations:

  • Theme validation and dependency checking
  • Automatic theme asset handling
  • Theme metadata extraction
  • Conflict resolution
  • Development symlink support

pelican-plugins

Plugin discovery and management utility for listing available plugins and their information.

def list_plugins() -> None:
    """
    Main entry point for pelican-plugins command.
    
    Features:
    - List all available plugins in plugin paths
    - Show plugin metadata and descriptions
    - Display plugin dependencies and requirements
    - Plugin status and compatibility information
    """

Command usage:

# List all available plugins
pelican-plugins

# Show detailed plugin information
pelican-plugins --info

# List plugins in specific path
pelican-plugins --path custom/plugins/

CLI Tool Configuration

Import Tool Settings

Configure import behavior in settings or via command-line options:

# Import-specific settings
IMPORT_WORDPRESS_POSTS_ONLY = False    # Import pages as well as posts
IMPORT_CLEAN_HTML = True               # Clean imported HTML
IMPORT_MARKDOWN_EXTENSION = '.md'      # Extension for converted Markdown
IMPORT_PRESERVE_METADATA = True        # Preserve custom metadata fields

Theme Tool Settings

Configure theme installation and management:

# Theme-specific settings
THEME_STATIC_DIR = 'theme'             # Theme static files directory
THEME_STATIC_PATHS = ['static']        # Theme static source directories
THEME_TEMPLATES_OVERRIDES = []         # Template override directories

Usage Examples

Automated Site Setup

#!/bin/bash
# Automated Pelican site setup script

# Create project directory
mkdir my-blog
cd my-blog

# Run quickstart with predefined answers
echo -e "My Blog\nJohn Doe\nen\nAmerica/New_York\nhttps://myblog.com\ny\ny\nn\ny" | pelican-quickstart

# Install a theme
pelican-themes --install https://github.com/getpelican/pelican-themes.git

# Create first post
mkdir -p content
cat > content/first-post.md << EOF
Title: My First Post
Date: $(date +%Y-%m-%d)
Category: General

This is my first post using Pelican!
EOF

# Generate site
make html

WordPress Migration Workflow

#!/bin/bash
# WordPress to Pelican migration script

# 1. Export WordPress content (done manually from WordPress admin)
# 2. Import content
pelican-import --wordpress wordpress-export.xml -o content/ --dir-cat

# 3. Convert HTML to Markdown (optional)
find content/ -name "*.html" -exec pandoc {} -f html -t markdown -o {}.md \;
find content/ -name "*.html" -delete
find content/ -name "*.md" -exec rename 's/\.html\.md$/.md/' {} \;

# 4. Download and organize images
python << EOF
import os
import re
import requests
from pathlib import Path

# Process all content files
for md_file in Path('content').glob('**/*.md'):
    content = md_file.read_text()
    
    # Find image URLs
    img_urls = re.findall(r'!\[.*?\]\((https?://[^)]+)\)', content)
    
    for url in img_urls:
        # Download image
        img_name = os.path.basename(url.split('?')[0])
        img_path = Path('content/images') / img_name
        img_path.parent.mkdir(exist_ok=True)
        
        response = requests.get(url)
        img_path.write_bytes(response.content)
        
        # Update content with local path
        content = content.replace(url, f'/images/{img_name}')
    
    md_file.write_text(content)
EOF

# 5. Generate site
pelican content

Theme Development Workflow

#!/bin/bash
# Theme development and testing workflow

# Create theme directory
mkdir -p themes/my-theme/templates
mkdir -p themes/my-theme/static/css

# Create basic theme files
cat > themes/my-theme/templates/base.html << EOF
<!DOCTYPE html>
<html>
<head>
    <title>{{ SITENAME }}</title>
    <link rel="stylesheet" href="{{ SITEURL }}/{{ THEME_STATIC_URL }}/css/style.css">
</head>
<body>
    {% block content %}{% endblock %}
</body>
</html>
EOF

# Install theme for development (symlinked)
pelican-themes --install --symlink themes/my-theme/

# Test theme with sample content
pelican content -t my-theme -o output-test/

# Serve for testing
cd output-test
python -m http.server 8000

Plugin Management Script

#!/usr/bin/env python3
"""Plugin management helper script."""

import subprocess
import sys
from pathlib import Path

def list_available_plugins():
    """List all available plugins."""
    result = subprocess.run(['pelican-plugins'], capture_output=True, text=True)
    return result.stdout.split('\n')

def install_recommended_plugins():
    """Install commonly used plugins."""
    recommended = [
        'https://github.com/getpelican/pelican-plugins.git',
    ]
    
    plugins_dir = Path('plugins')
    plugins_dir.mkdir(exist_ok=True)
    
    for plugin_repo in recommended:
        plugin_name = plugin_repo.split('/')[-1].replace('.git', '')
        plugin_path = plugins_dir / plugin_name
        
        if not plugin_path.exists():
            subprocess.run(['git', 'clone', plugin_repo, str(plugin_path)])
            print(f"Installed plugin: {plugin_name}")
        else:
            print(f"Plugin already exists: {plugin_name}")

def update_plugins():
    """Update all git-based plugins."""
    plugins_dir = Path('plugins')
    
    for plugin_path in plugins_dir.iterdir():
        if plugin_path.is_dir() and (plugin_path / '.git').exists():
            print(f"Updating {plugin_path.name}...")
            subprocess.run(['git', 'pull'], cwd=plugin_path)

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: plugin-manager.py [list|install|update]")
        sys.exit(1)
    
    command = sys.argv[1]
    
    if command == 'list':
        plugins = list_available_plugins()
        for plugin in plugins:
            if plugin.strip():
                print(plugin)
    elif command == 'install':
        install_recommended_plugins()
    elif command == 'update':
        update_plugins()
    else:
        print(f"Unknown command: {command}")
        sys.exit(1)

Content Import Automation

#!/usr/bin/env python3
"""Automated content import with processing."""

import subprocess
import sys
import re
from pathlib import Path
from datetime import datetime

def import_content(source_type, source_path, output_dir='content'):
    """Import content using pelican-import."""
    cmd = ['pelican-import', f'--{source_type}', source_path, '-o', output_dir]
    
    if source_type == 'wordpress':
        cmd.extend(['--dir-cat', '--strip-raw'])
    
    result = subprocess.run(cmd, capture_output=True, text=True)
    
    if result.returncode == 0:
        print(f"Successfully imported {source_type} content")
        return True
    else:
        print(f"Import failed: {result.stderr}")
        return False

def post_process_content(content_dir='content'):
    """Post-process imported content."""
    content_path = Path(content_dir)
    
    for md_file in content_path.glob('**/*.md'):
        content = md_file.read_text()
        modified = False
        
        # Fix common import issues
        # 1. Clean up WordPress shortcodes
        content = re.sub(r'\[caption[^\]]*\](.*?)\[/caption\]', r'\1', content, flags=re.DOTALL)
        content = re.sub(r'\[gallery[^\]]*\]', '', content)
        
        # 2. Fix image references
        content = re.sub(r'!\[\]\(([^)]+)\)', r'![](\1)', content)
        
        # 3. Clean up extra whitespace
        content = re.sub(r'\n\s*\n\s*\n', '\n\n', content)
        
        # 4. Ensure proper metadata formatting
        lines = content.split('\n')
        if lines and not lines[0].startswith(('Title:', 'Date:')):
            # Add basic metadata if missing
            title = md_file.stem.replace('-', ' ').title()
            date = datetime.now().strftime('%Y-%m-%d')
            metadata = f"Title: {title}\nDate: {date}\n\n"
            content = metadata + content
            modified = True
        
        if modified:
            md_file.write_text(content)
            print(f"Post-processed: {md_file}")

if __name__ == '__main__':
    if len(sys.argv) < 3:
        print("Usage: import-content.py <source_type> <source_path>")
        print("Example: import-content.py wordpress export.xml")
        sys.exit(1)
    
    source_type = sys.argv[1]
    source_path = sys.argv[2]
    
    # Import content
    success = import_content(source_type, source_path)
    
    if success:
        # Post-process content
        post_process_content()
        print("Content import and processing complete!")
    else:
        print("Content import failed!")
        sys.exit(1)

Install with Tessl CLI

npx tessl i tessl/pypi-pelican

docs

cli-tools.md

content-generation.md

content-management.md

content-reading.md

index.md

main-application.md

plugin-system.md

settings-configuration.md

utilities.md

tile.json