Understanding Mixins
Mixins are self-contained feature packages that you can add to your MintyFlask site. Think of them as building blocks that provide specific functionality—like blog posts, photo galleries, or contact forms—without requiring you to write everything from scratch.
What Are Mixins?
A mixin is a collection of templates, styles, and scripts organised around a specific feature. For example, the blog mixin provides everything you need to run a blog: post listings, category pages, tag filtering, and archive views.
Each mixin is independent and can be combined with others, giving you the flexibility to build exactly the site you need.
Key Characteristics
Self-Contained
Each mixin includes its own templates, CSS, and JavaScript. You don't need to hunt for dependencies or worry about missing files.
Reusable
Once a mixin is created, it can be used across multiple themes and projects. You might use the same blog mixin for a personal blog and a corporate news section.
Composable
Mixins work together seamlessly. You can combine a blog mixin with a photos mixin to create a travel blog with integrated photo galleries.
Theme-Independent
Mixins provide functionality without enforcing specific styling. Your theme controls the visual appearance whilst the mixin handles the features.
Available Mixins
MintyFlaskThemes currently includes these mixins:
Blog Mixin
The blog mixin provides comprehensive blogging functionality:
- Post Management: Individual post pages with metadata, reading time, and navigation
- Organisation: Categories and tags for content taxonomy
- Archives: Date-based browsing by year and month
- Listings: Flexible post listing layouts (list or grid views)
- Special Views: Draft posts and review queues for content workflow
- Navigation: Blog-specific navigation components
Quick Start:
{# Import blog components in your template #}
{% from "blog-components.html" import blog_post_list, post_card_actions %}
{# Display a list of posts #}
{{ blog_post_list(posts, layout='grid', columns=3) }}
Photos Mixin
Using Mixins in Your Theme
Basic Integration
To use a mixin in your theme, you need to:
- Import the components you want to use
- Call the macros where you need them
- Pass the required data from your Flask routes
Here's a practical example using the blog mixin:
{# themes/your-theme/templates/blog/index.html #}
{% extends "base.html" %}
{% from "blog-components.html" import blog_post_list %}
{% block content %}
<div class="container">
<h1>Latest Articles</h1>
{# Display posts in a 2-column grid #}
{{ blog_post_list(
posts=posts,
layout='grid',
columns=2,
show_excerpt=true,
show_meta=true
) }}
</div>
{% endblock %}
Template Resolution
MintyFlaskThemes uses a three-layer system to find templates:
1. Your Theme (themes/your-theme/templates/)
↓ if not found
2. Mixin Layer (mixins/blog/templates/)
↓ if not found
3. Core Layer (themes/_core/templates/)
This means you can:
- Use mixin templates as-is for quick setup
- Override specific templates in your theme when you need customisation
- Fall back to core templates for essential functionality
Example:
{# Your theme can override the default post layout #}
{# themes/your-theme/templates/pages/post-single.html #}
{% extends "layouts/single.html" %}
{# Add custom styling for your brand #}
{% block article_class %}blog-post our-brand-style{% endblock %}
Importing Mixin Components
Mixins expose their functionality through macros defined in component files. Here's how to import and use them:
{# Import specific macros you need #}
{% from "blog-components.html" import
blog_post_list,
post_metadata_enhanced,
post_tag_cloud
%}
{# Use them in your templates #}
<article class="post">
<header>
{{ post_metadata_enhanced(post, show_reading_time=true) }}
</header>
<div class="content">
{{ post.html | safe }}
</div>
<footer>
{{ post_tag_cloud(post, style='badges') }}
</footer>
</article>
Configuration Options
Most mixin macros accept parameters that let you customise their behaviour:
{# Minimal configuration #}
{{ blog_post_list(posts) }}
{# Fully customised #}
{{ blog_post_list(
posts=recent_posts,
layout='grid', # 'list' or 'grid'
columns=3, # Grid columns (2 or 3)
show_excerpt=true, # Display post summaries
show_meta=true, # Show date, category, etc.
show_featured_image=true, # Display post images
limit=6 # Maximum posts to display
) }}
Combining Multiple Mixins
One of the most powerful features of the mixin system is composition. You can combine multiple mixins to create rich, feature-packed sites.
Example: Blog + Photos
{# themes/travel-blog/templates/home.html #}
{% extends "base.html" %}
{# Import from multiple mixins #}
{% from "blog-components.html" import blog_post_list %}
{% from "gallery-components.html" import gallery_featured %}
{% block content %}
{# Hero section with featured gallery #}
<section class="hero">
{{ gallery_featured(gallery=latest_photos, limit=5) }}
</section>
{# Blog posts below #}
<section class="recent-posts">
<h2>Recent Adventures</h2>
{{ blog_post_list(posts=recent_posts, layout='grid', columns=3) }}
</section>
{% endblock %}
Data Flow
When combining mixins, your Flask routes provide the data:
# app/routes/main.py
from flask import Blueprint, render_template
main_bp = Blueprint('main', __name__)
@main_bp.route('/')
def home():
# Fetch data for both mixins
recent_posts = get_recent_posts(limit=6)
latest_photos = get_latest_gallery()
# Pass to template
return render_template('home.html',
recent_posts=recent_posts,
latest_photos=latest_photos
)
Customising Mixin Behaviour
Overriding Templates
If you need to customise how a mixin renders, you can override its templates in your theme:
themes/your-theme/templates/
├── pages/
│ └── post-single.html # Overrides blog mixin's post layout
├── partials/
│ └── post-card.html # Overrides blog mixin's card component
└── base.html # Your theme's base layout
The template resolution system will use your override first, falling back to the mixin's original if you don't provide one.
Extending Mixin Templates
You can also extend mixin templates to add functionality whilst keeping the original structure:
{# themes/your-theme/templates/pages/post-single.html #}
{% extends "mixins/blog/templates/pages/post-single.html" %}
{# Add a new block for social sharing #}
{% block post_footer %}
{{ super() }} {# Keep original footer content #}
<div class="social-sharing">
{# Your custom social sharing buttons #}
</div>
{% endblock %}
Custom Styling
Each mixin includes its own CSS, but you can override styles in your theme:
/* themes/your-theme/static/css/custom.css */
/* Override blog mixin's card styling */
.card-base.card-intent-content {
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
/* Customise post metadata appearance */
.post-metadata {
font-family: "Your Custom Font", sans-serif;
color: var(--brand-primary);
}
Best Practises
Choose the Right Level of Customisation
Use mixin defaults when:
- You're prototyping quickly
- The default styling fits your needs
- You want to focus on content first
Override selectively when:
- You need specific brand styling
- Certain components need different behaviour
- You're refining the user experience
Create custom mixins when:
- You need completely unique functionality
- You're building reusable features for multiple projects
- You want to share components with the community
Keep Mixins Focused
When working with mixins, maintain clear separation:
{# Good: Each mixin handles its own domain #}
{% from "blog-components.html" import blog_post_list %}
{% from "gallery-components.html" import gallery_grid %}
{# Avoid: Mixing concerns #}
{# Don't try to make blog components handle gallery data #}
Document Your Overrides
If you override mixin templates, document why:
{# themes/your-theme/templates/pages/post-single.html #}
{#
# Custom Post Layout
#
# Overrides: mixins/blog/templates/pages/post-single.html
# Reason: Add custom social sharing and newsletter signup
# Modified: 2025-11-24
#}
{% extends "layouts/single.html" %}
...
Creating Custom Mixins
Whilst this user guide focuses on using existing mixins, you might eventually want to create your own. Custom mixins follow the same structure and patterns as the built-in ones.
Quick Preview:
A basic mixin structure looks like this:
mixins/your-feature/
├── templates/
│ ├── your-feature-components.html # Macro definitions
│ ├── layouts/ # Page layouts
│ └── partials/ # Reusable fragments
├── static/
│ ├── css/
│ │ └── your-feature.css
│ └── js/
│ └── your-feature.js
└── README.md # Documentation
Next Steps
Now that you understand mixins, explore these related topics:
- Template Resolution - Understand how the three-layer template system finds and loads mixin templates
- Component Development - Learn the patterns for creating reusable components that work with mixins
- CSS Architecture - Understand how mixin styles integrate with the five-layer CSS cascade
- Theme Creation - Build custom themes that leverage mixins effectively
- Static Assets Organisation - Manage CSS, JS, and vendor files for your mixin-powered themes
Common Questions
Q: Can I use multiple versions of the same mixin?
A: No, the template resolution system will always use the first match it finds. If you need different behaviours, create theme-level overrides or customise via parameters.
Q: Do mixins slow down my site?
A: No. Mixins are resolved at template render time, just like any other Jinja2 template. Flask's built-in template caching keeps performance high.
Q: Can I disable a mixin I'm not using?
A: Yes. Simply remove it from your Flask app's template loader configuration. If you're not importing from a mixin, it has no impact on your site.
Q: How do I know what parameters a macro accepts?
A: Each mixin includes documentation comments in its component files. You can also refer to the API Reference for complete parameter lists.
Q: Can I contribute my own mixin?
A: Absolutely! See the Contributing Guide for information on sharing your mixins with the community.