Configuration
Introduction
MintyFlaskSSG uses a class-based Flask configuration system with intelligent path auto-discovery. The configuration handles theme resolution, content directories, photo galleries, and Markdown rendering whilst allowing you to override any setting for your specific environment.
This guide covers how to configure your MintyFlaskSSG site, from basic setup through to advanced customisation. You'll learn how the auto-discovery system works, when to override paths explicitly, and how to structure your configuration for different environments.
Why This Matters
Proper configuration is essential for MintyFlaskSSG to locate your themes, content, and assets. The auto-discovery system simplifies setup by finding common directory structures automatically, whilst the override system lets you work with custom layouts or multiple projects.
Key Concepts
Class-Based Configuration: MintyFlaskSSG uses Flask's class-based configuration pattern with a base Config class and environment-specific subclasses.
Auto-Discovery: The system automatically searches for themes, mixins, and data directories in standard locations, reducing manual configuration.
Local Overrides: A config_local.py file lets you override any setting without modifying the base configuration, perfect for development environments.
Three-Layer Template System: Configuration controls the resolution order: current theme → mixins → core theme fallback.
Configuration Files
MintyFlaskSSG uses two configuration files working together:
config.py - Base Configuration
The base configuration file defines default settings and the auto-discovery system. This file contains:
- Class definitions for different environments (
Config,DevelopmentConfig,ProductionConfig, etc.) - Auto-discovery logic for themes and data directories
- Default values for all configuration options
- Template resolution setup
You should not modify config.py directly unless you're changing system defaults. Instead, use config_local.py for your overrides.
config_local.py - Local Overrides
Create this file to override settings for your specific environment:
# config_local.py
"""Local configuration for your development environment."""
from config import Config
class LocalConfig(Config):
"""Your local development configuration."""
# Explicit theme paths (prevents auto-discovery from finding wrong location)
MINTY_THEMES_BASE_DIR = '~/code/flask/minty-flask-themes/minty_flask_themes'
THEMES_BASE_DIR = "~/code/flask/minty-flask-themes/minty_flask_themes/themes"
MIXINS_BASE_DIR = "~/code/flask/minty-flask-themes/minty_flask_themes/mixins"
# Data directory (or set to None for auto-discovery)
DATA_DIR = "../data"
# Current theme
THEME_NAME = 'blog'
The LocalConfig class inherits from Config and overrides specific settings. Python will automatically expand ~ in paths to your home directory.
Path Auto-Discovery
MintyFlaskSSG's auto-discovery system finds themes, mixins, and data directories automatically by searching common locations. This reduces configuration overhead whilst remaining flexible.
How Auto-Discovery Works
When a configuration value is set to None, the system searches a predefined list of locations:
-
Data Directory (
DATA_DIR):project_root/dataproject_root/../dataproject_root/../../data
-
Themes Base Directory (
THEMES_BASE_DIR):project_root/themesproject_root/../themesproject_root/../../themesproject_root/../../minty-flask-themes/minty_flask_themes/themes(MintyFlaskThemes location)
-
Mixins Base Directory (
MIXINS_BASE_DIR):project_root/mixinsproject_root/../mixins
The system uses the first location that exists, logging its choice during startup.
When to Use Auto-Discovery
Auto-discovery works well when:
- Your directory structure follows standard conventions
- You have a single MintyFlaskSSG project
- Themes and data are in predictable locations relative to the app
When to Override Paths
Set explicit paths in config_local.py when:
- Working with multiple MintyFlaskSSG projects that might conflict
- Using a custom directory structure
- Themes or data are in non-standard locations
- You want absolute certainty about which directories are being used
# Explicit configuration prevents auto-discovery ambiguity
class LocalConfig(Config):
THEMES_BASE_DIR = "/home/user/my-themes/themes"
DATA_DIR = "/var/www/site-content"
Core Configuration Options
General Settings
class Config:
# Site metadata
SITE_DESCRIPTION = "Your default site description"
# Content directories (relative to DATA_DIR)
POSTS_DIR = "articles" # Blog posts location
PAGES_DIR = "pages" # Static pages location
# Internationalisation
LANGUAGES_DEFAULT = "en"
# Flask debugging
FLASK_DEBUG = True
Theme System Configuration
The theme system requires three main path configurations:
class Config:
# Set to None for auto-discovery
MINTY_THEMES_BASE_DIR = None # MintyFlaskThemes root
THEMES_BASE_DIR = None # Themes directory
MIXINS_BASE_DIR = None # Mixins directory (optional)
# Active theme
THEME_NAME = "blog"
# Core fallback theme
CORE_THEME_NAME = "_core"
MINTY_THEMES_BASE_DIR: Root of the MintyFlaskThemes package (typically minty_flask_themes/)
THEMES_BASE_DIR: Directory containing theme folders (typically minty_flask_themes/themes/)
MIXINS_BASE_DIR: Directory containing mixin folders (typically minty_flask_themes/mixins/)
THEME_NAME: The currently active theme, determines which theme templates load first
CORE_THEME_NAME: The fallback core theme, typically _core, provides base templates
Data Directory Configuration
class Config:
# Main data directory (auto-discover if None)
DATA_DIR = None
# Site configuration YAML
SITE_YAML_FILEPATH = None # Auto-discovers to DATA_DIR/yaml/site.yaml
When DATA_DIR is set (either explicitly or via auto-discovery), the system automatically derives related paths:
SITE_YAML_FILEPATH→{DATA_DIR}/yaml/site.yamlFLATPAGES_ROOT→{DATA_DIR}/markdownPHOTOS_LIBRARY_ROOT→{DATA_DIR}/photos/photos_originalPHOTOS_OUTPUT_DIR→{DATA_DIR}/photos/photos_processed
You can override any of these individually if needed:
class LocalConfig(Config):
DATA_DIR = "../data"
FLATPAGES_ROOT = "../content/markdown" # Override default
Flask-FlatPages Configuration
MintyFlaskSSG uses Flask-FlatPages for Markdown content rendering:
class Config:
# Content root (auto-discovers to DATA_DIR/markdown)
FLATPAGES_ROOT = None
# File extension for content files
FLATPAGES_EXTENSION = '.md'
# Auto-reload in development
FLATPAGES_AUTO_RELOAD = True
# HTML renderer (custom photo-enhanced renderer)
FLATPAGES_HTML_RENDERER = 'app.extensions.photo_enhanced_renderer'
# Markdown extensions
FLATPAGES_MARKDOWN_EXTENSIONS = [
'meta', 'tables', 'fenced_code', 'codehilite', 'toc',
'attr_list', 'def_list', 'abbr', 'footnotes',
'admonition', 'smarty', 'sane_lists',
'app.extensions.markdown.admonition' # Custom extension
]
# Extension-specific configuration
FLATPAGES_MARKDOWN_EXTENSION_CONFIGS = {
'codehilite': {
'css_class': 'highlight',
'linenums': False
},
'toc': {
'anchorlink': True
}
}
Photo Gallery Configuration
class Config:
# Photo directories (auto-discover if None)
PHOTOS_LIBRARY_ROOT = None # Original photos
PHOTOS_OUTPUT_DIR = None # Processed photos
# Photo hover overlay behaviour
PHOTOS_SHOW_HOVER_INFO = False # Show info overlay on hover
PHOTOS_SHOW_INFO_TOGGLE = False # Show toggle button
PHOTOS_INFO_DEFAULT_STATE = False # Default toggle state
Pagination Settings
class Config:
PER_PAGE = 10 # Items per page
LINK_SIZE = "sm" # Pagination link size
SHOW_SINGLE_PAGE = False # Hide pagination on single page
Reading Time Calculation
class Config:
READING_SPEED_WPM = 225 # Words per minute for reading time estimates
Configuration Patterns
Pattern: Development Configuration
Standard development setup with auto-discovery:
# config_local.py
from config import Config
class LocalConfig(Config):
"""Development configuration with auto-discovery."""
# Let auto-discovery find everything
DATA_DIR = None
THEMES_BASE_DIR = None
MIXINS_BASE_DIR = None
# Just specify which theme to use
THEME_NAME = 'blog'
# Enable auto-reload
FLATPAGES_AUTO_RELOAD = True
Pattern: Explicit Path Configuration
Development setup with explicit paths (multiple projects):
# config_local.py
from config import Config
class LocalConfig(Config):
"""Development with explicit paths."""
# Explicit paths prevent ambiguity
MINTY_THEMES_BASE_DIR = '~/code/flask/minty-flask-themes/minty_flask_themes'
THEMES_BASE_DIR = "~/code/flask/minty-flask-themes/minty_flask_themes/themes"
MIXINS_BASE_DIR = "~/code/flask/minty-flask-themes/minty_flask_themes/mixins"
# Project-specific data directory
DATA_DIR = "../data"
# Active theme
THEME_NAME = 'minimal'
Pattern: Production Configuration
For deployment or static site generation:
# config_production.py
from config import Config
class ProductionConfig(Config):
"""Production configuration."""
DEBUG = False
FLASK_DEBUG = False
# Explicit paths for production
THEMES_BASE_DIR = "/var/www/themes"
DATA_DIR = "/var/www/site-data"
# Disable auto-reload
FLATPAGES_AUTO_RELOAD = False
# Production theme
THEME_NAME = 'blog'
Pattern: Custom Content Structure
Override content directory paths:
# config_local.py
from config import Config
class LocalConfig(Config):
"""Custom content structure."""
DATA_DIR = "../content"
# Override default paths
POSTS_DIR = "blog-posts" # Instead of "articles"
PAGES_DIR = "static-content" # Instead of "pages"
FLATPAGES_ROOT = "../content/md" # Custom markdown location
Pattern: Photo Gallery Only
Configure for a photo gallery site:
# config_local.py
from config import Config
class LocalConfig(Config):
"""Photo gallery focused configuration."""
DATA_DIR = "../photos-data"
# Photo-specific settings
PHOTOS_LIBRARY_ROOT = "/mnt/photo-archive/originals"
PHOTOS_OUTPUT_DIR = "../photos-data/processed"
# Enable hover info and toggle
PHOTOS_SHOW_HOVER_INFO = True
PHOTOS_SHOW_INFO_TOGGLE = True
PHOTOS_INFO_DEFAULT_STATE = False
# Photo gallery theme
THEME_NAME = 'gallery'
Configuration Profiles
MintyFlaskSSG includes several pre-built logging profiles for different use cases. These are handled by run.py and selected using the --config flag when running the application.
Available Profiles
The logging profiles are defined in run.py and control subsystem logging levels:
development - Standard development with INFO-level logging (default)
production - Production deployment with minimal logging
photos - DEBUG-level logging for photo subsystem only
blog - DEBUG-level logging for blog subsystem only
routes - DEBUG-level logging for route resolution only
quiet - WARNING-level logging for clean output
all - DEBUG-level logging for all subsystems
Using Configuration Profiles
Select a profile when starting the application:
# Standard development
python run.py
# Debug photo processing
python run.py --config photos
# Debug blog functionality
python run.py --config blog
# Full debug output
python run.py --config all
# Production mode
python run.py --config production
See the "Running the Application" guide for complete details on configuration profiles.
Environment Detection
MintyFlaskSSG sets the ENVIRONMENT configuration key based on the selected profile:
# Set automatically in Config.init_app()
environment = os.environ.get('ENVIRONMENT', 'development')
app.config['ENVIRONMENT'] = environment
app.config['SHOW_DEV_NOTES'] = (environment == 'development')
The SHOW_DEV_NOTES flag controls whether development notes render in templates. Production configuration sets ENVIRONMENT = 'production', hiding dev notes automatically.
Template Resolution
Configuration controls MintyFlaskSSG's three-layer template resolution system. During initialisation, the system builds a template directory list in priority order:
- Current Theme (highest priority):
{THEMES_BASE_DIR}/{THEME_NAME}/templates - Mixins (middle priority):
{MIXINS_BASE_DIR}/*/templates - Core Theme (fallback):
{THEMES_BASE_DIR}/{CORE_THEME_NAME}/templates
When you request a template, Jinja2 searches these directories in order, using the first match found. This allows themes to override mixin templates, and mixins to override core templates.
Theme Resolution Example
With this configuration:
THEMES_BASE_DIR = "/themes"
THEME_NAME = "blog"
CORE_THEME_NAME = "_core"
A request for page.html searches:
/themes/blog/templates/page.html← Custom theme version/themes/blog/templates/mixins/*/page.html← Mixin versions/themes/_core/templates/page.html← Core fallback
Explicit Theme References
Templates can reference specific themes using prefix notation:
{# Always use core base template #}
{% extends "_core/base.html" %}
{# Use blog theme header #}
{% include "blog/components/header.html" %}
The ThemeAwareLoader class handles these prefixed references, making cross-theme template composition possible.
Logging Configuration
MintyFlaskSSG configures Python logging in Config.init_app():
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s %(levelname)-5s [%(name)s] %(message)s',
datefmt='%H:%M:%S'
)
# Subsystem logging levels
logging.getLogger('app.photos').setLevel(logging.WARNING)
logging.getLogger('app.blog').setLevel(logging.INFO)
logging.getLogger('app.home').setLevel(logging.INFO)
logging.getLogger('werkzeug').setLevel(logging.WARNING)
Override these in your configuration class:
class LocalConfig(Config):
@staticmethod
def init_app(app):
Config.init_app(app)
# Enable detailed photo logging
import logging
logging.getLogger('app.photos').setLevel(logging.DEBUG)
Note
Logging levels are managed through run.py's apply_logging_profile() function rather than config classes. This approach allows dynamic logging configuration without reloading the entire config, which would reset resolved paths.
The --config flag selects a logging profile:
python run.py --config photos # DEBUG logging for photos only
Config classes like PhotosDebugConfig are no longer needed—profiles handle this more efficiently.
Best Practices
Configuration Management
Do:
✓ Create config_local.py for development overrides
✓ Use auto-discovery for standard directory layouts
✓ Set explicit paths when working with multiple projects
✓ Document why you override default values
✓ Use environment-specific configuration classes
Don't:
✗ Modify config.py directly for local changes
✗ Commit config_local.py to version control
✗ Hardcode absolute paths that won't work on other machines
✗ Override paths unnecessarily when auto-discovery works
✗ Use development configuration in production
Path Configuration
Do:
✓ Use ~ for home directory in paths (auto-expands)
✓ Use relative paths where possible (../data)
✓ Check logs to see which paths auto-discovery selected
✓ Test path resolution in development before deploying
✓ Use Path.expanduser().resolve() for path validation
Don't:
✗ Use absolute paths like /home/username/projects/...
✗ Assume auto-discovery will find non-standard structures
✗ Mix Windows and Unix path separators
✗ Forget to create directories that configuration references
✗ Use paths with spaces without proper quoting
Theme Configuration
Do:
✓ Keep THEME_NAME and CORE_THEME_NAME in sync with available themes
✓ Verify theme directories exist before running
✓ Use consistent theme naming conventions
✓ Test template resolution with debug configuration
✓ Document theme dependencies in your configuration
Don't:
✗ Reference non-existent themes (causes template errors)
✗ Change CORE_THEME_NAME unless you have a custom core
✗ Assume themes are portable without checking paths
✗ Mix theme versions with incompatible template structures
✗ Deploy with development themes
Troubleshooting
Problem: Themes Not Found
Symptoms:
- Application starts but templates fail to load
- Logs show "Theme templates not found" warnings
- Template resolution falls back to core only
Diagnosis: Check the startup logs for theme path resolution:
WARNING: Theme templates not found: /path/to/themes/blog/templates
Solution:
Set explicit THEMES_BASE_DIR in config_local.py:
class LocalConfig(Config):
THEMES_BASE_DIR = "~/code/flask/minty-flask-themes/minty_flask_themes/themes"
Problem: Wrong Theme Directory Selected
Symptoms:
- Auto-discovery finds themes in unexpected location
- Multiple MintyFlaskSSG projects interfere with each other
- Templates from wrong project load
Diagnosis: Check startup logs for auto-discovery selection:
INFO: Found themes directory at fallback location: ../../other-project/themes
Solution: Use explicit paths to prevent auto-discovery ambiguity:
class LocalConfig(Config):
MINTY_THEMES_BASE_DIR = '~/code/flask/this-project/minty_flask_themes'
THEMES_BASE_DIR = "~/code/flask/this-project/minty_flask_themes/themes"
Problem: Data Directory Not Found
Symptoms:
- Content pages return 404
- Photo galleries are empty
- YAML configuration files not loading
Diagnosis:
Check if DATA_DIR auto-discovery succeeded:
INFO: Data directory found: ../data
Solution: Create the expected directory structure or set explicit path:
mkdir -p ../data/markdown
mkdir -p ../data/photos
mkdir -p ../data/yaml
Or configure explicitly:
class LocalConfig(Config):
DATA_DIR = "/path/to/content"
Problem: Configuration Changes Not Applied
Symptoms:
- Modified
config_local.pybut changes not reflected - Still using default values
Diagnosis:
Check if config_local.py is being imported and LocalConfig class exists.
Solution:
Ensure your config_local.py follows this structure:
from config import Config
class LocalConfig(Config):
# Your overrides here
THEME_NAME = 'blog'
Restart the application to reload configuration.
Problem: Template Resolution Issues
Symptoms:
- Templates loading from unexpected themes
- Mixin templates not found
- Core templates used when theme templates should apply
Diagnosis: Run with route debugging:
python run.py --config routes
Check template resolution order in logs.
Solution: Verify your template hierarchy configuration:
class LocalConfig(Config):
THEMES_BASE_DIR = "/correct/path/themes"
MIXINS_BASE_DIR = "/correct/path/mixins"
THEME_NAME = "blog" # Must exist in THEMES_BASE_DIR
CORE_THEME_NAME = "_core" # Must exist in THEMES_BASE_DIR
Common Use Cases
Use Case 1: Fresh Installation
You're setting up MintyFlaskSSG for the first time with standard directory structure:
# config_local.py - Minimal configuration
from config import Config
class LocalConfig(Config):
# Let auto-discovery handle everything
THEME_NAME = 'blog'
Start the application and check logs to verify auto-discovery:
python run.py --config all
Look for successful path detection messages.
Use Case 2: Multiple Projects
You're working on several MintyFlaskSSG sites simultaneously:
# config_local.py - Explicit paths prevent conflicts
from config import Config
class LocalConfig(Config):
# Project-specific theme location
MINTY_THEMES_BASE_DIR = '~/code/flask/project-a/themes-package'
THEMES_BASE_DIR = "~/code/flask/project-a/themes-package/themes"
# Project-specific data
DATA_DIR = "~/code/flask/project-a/content"
THEME_NAME = 'blog'
Use Case 3: Shared Theme Library
Your themes are in a separate shared repository:
# config_local.py - Point to shared themes
from config import Config
class LocalConfig(Config):
# Shared theme library
THEMES_BASE_DIR = "~/code/themes-library/themes"
MIXINS_BASE_DIR = "~/code/themes-library/mixins"
# Project-specific content
DATA_DIR = "../site-content"
THEME_NAME = 'corporate'
Use Case 4: Custom Content Structure
Your content doesn't follow the default layout:
# config_local.py - Custom paths
from config import Config
class LocalConfig(Config):
DATA_DIR = "../content"
# Custom content locations
FLATPAGES_ROOT = "../content/pages"
POSTS_DIR = "posts"
PAGES_DIR = "docs"
# Photos in separate location
PHOTOS_LIBRARY_ROOT = "/mnt/photos/library"
PHOTOS_OUTPUT_DIR = "../content/processed-photos"
THEME_NAME = 'docs'
Configuration Checklist
Initial Setup
For New Installation:
- Create
config_local.pyfrom template - Set
THEME_NAMEto desired theme - Verify theme exists in themes directory
- Test auto-discovery with
python run.py --config all - Check startup logs for path detection messages
- Verify content loads correctly
For Custom Structure:
- Set explicit
THEMES_BASE_DIRpath - Set explicit
DATA_DIRpath - Override content directory paths if needed
- Create required directory structure
- Test path resolution
- Verify all content types load
Pre-Deployment
Before Going Live:
- Create production configuration class
- Set
DEBUG = FalseandFLASK_DEBUG = False - Use explicit paths (no auto-discovery)
- Set
FLATPAGES_AUTO_RELOAD = False - Verify
ENVIRONMENT = 'production' - Test with production configuration locally
- Check logs are at WARNING level
- Generate static site if not using dynamic Flask
Conclusion
MintyFlaskSSG's configuration system balances simplicity and flexibility. Auto-discovery reduces setup overhead for standard layouts, whilst explicit configuration provides precise control for complex deployments.
Key takeaways:
-
Use
config_local.pyfor overrides: Never modifyconfig.pydirectly; create local configuration to preserve upgrade path. -
Auto-discovery is your friend: Let the system find standard directories automatically unless you have specific requirements.
-
Explicit beats ambiguous: When working with multiple projects or custom structures, set paths explicitly to avoid conflicts.
-
Test before deploying: Use debug configurations during development to verify path resolution and template loading.
-
Profiles over classes: Use logging profiles via
--configflag rather than creating separate config classes—it's more flexible and maintains resolved paths.
Start with minimal configuration and add overrides only when needed. The logging output will guide you if path resolution fails or templates don't load correctly.