🎨 Nunjucks Templating Demo
This page demonstrates advanced Nunjucks templating features using our MuizenMesh Webring data. Nunjucks is much more than basic templating - it's a powerful template engine!
📊 Basic Data & Statistics
View Code: Statistics Calculations
<!-- Member count -->
{{ members | length }}
<!-- Members with feeds -->
{% set membersWithFeeds = members | selectattr('feed') | list %}
{{ membersWithFeeds | length }}
<!-- Percentage calculation -->
{% set feedPercentage = ((membersWithFeeds | length) / (members | length) * 100) | round %}
{{ feedPercentage }}%
<!-- Pattern matching -->
{% set southAfricanSites = members | selectattr('url', 'match', '.*\\.co\\.za.*') | list %}
{{ southAfricanSites | length }}6
Total Members
3
With RSS Feeds
50%
Feed Coverage
6
.co.za Sites
🔄 Loops & Conditionals
View Code: Conditional Loops
<!-- Loop with conditional -->
{% for member in members %}
{% if member.feed %}
<li>{{ member.title }} - Has RSS Feed</li>
{% else %}
<li>{{ member.title }} - No RSS Feed</li>
{% endif %}
{% endfor %}
<!-- Alternative: Filter first, then loop -->
{% for member in members | selectattr('feed') %}
<li>{{ member.title }} - {{ member.feed }}</li>
{% endfor %}Members by Feed Status
✅ Members with RSS Feeds
- Medialternatives
https://medialternatives.com/feed.xml - MuizeMesh Communities
https://muizenmesh.wordpress.com/feed.xml - MECC Blog
https://electromesh.wordpress.com/feed.xml
📝 Members without RSS Feeds
- MuizenMesh
https://muizenmesh.co.za - Muizenberg Electricity Coop
https://umbane.netlify.app - Netbones Solutions
https://netbones.co.za
🎯 Advanced Filtering & Sorting
View Code: Sorting and Filtering
<!-- Sort by attribute -->
{% for member in members | sort(attribute='title') %}
<li>{{ member.title }}</li>
{% endfor %}
<!-- Filter and sort combined -->
{% for member in members | selectattr('feed') | sort(attribute='title') %}
<li>{{ member.title }} - {{ member.feed }}</li>
{% endfor %}
<!-- Reverse sorting -->
{% for member in members | sort(attribute='title', reverse=true) %}
<li>{{ member.title }}</li>
{% endfor %}Members Sorted by Title (A-Z)
- MECC Blog 📡 RSS
- Medialternatives 📡 RSS
- MuizeMesh Communities 📡 RSS
- Muizenberg Electricity Coop
- MuizenMesh
- Netbones Solutions
Domain Analysis
Sites by Domain:
- muizenmesh.co.za: 2 sites 🔥
- medialternatives.com: 1 site
- mecc.org.za: 1 site
- netbones.co.za: 1 site
Note: Domain analysis simplified for demo purposes
🧮 Mathematical Operations
View Code: Mathematical Calculations
<!-- Basic math -->
{{ members | length * 2 }}
<!-- Growth projections -->
{% for month in range(1, 7) %}
{% set projected = (members | length * (1.2 ** month)) | round %}
Month {{ month }}: ~{{ projected }} members
{% endfor %}
<!-- Percentage calculations -->
{% set percentage = (value / total * 100) | round(2) %}
{{ percentage }}%
<!-- Complex calculations -->
{% set average = (total_value / count) | round(1) %}
Average: {{ average }}📈 Community Growth Projections
Current members: 6
If we grow 20% monthly:
- Month 1: ~7 members
- Month 2: ~9 members
- Month 3: ~10 members
- Month 4: ~12 members
- Month 5: ~15 members
- Month 6: ~18 members
🎨 Dynamic Styling
View Code: Dynamic Theme Generation
<!-- Define theme array -->
{% set themes = [
{name: 'ocean', bg: '#e3f2fd', border: '#1976d2'},
{name: 'sunset', bg: '#fff3e0', border: '#ff9800'}
] %}
<!-- Apply themes cyclically -->
{% for member in members %}
{% set themeIndex = loop.index0 % 2 %}
{% set theme = themes[themeIndex] %}
<div style="background: {{ theme.bg }}; border: 2px solid {{ theme.border }};">
{{ member.title }}
</div>
{% endfor %}
<!-- Conditional styling -->
{% if member.feed %}
<span style="color: green;">Has RSS</span>
{% else %}
<span style="color: orange;">No RSS</span>
{% endif %}Member Cards with Dynamic Themes
Medialternatives
Theme: OceanMuizenMesh
Theme: SunsetMuizeMesh Communities
Theme: ForestMuizenberg Electricity Coop
Theme: PurpleMECC Blog
Theme: OceanNetbones Solutions
Theme: Sunset🔤 String Manipulation
View Code: String Transformations
<!-- Text case transformations -->
{{ title | upper }} <!-- UPPERCASE -->
{{ title | lower }} <!-- lowercase -->
{{ title | title }} <!-- Title Case -->
<!-- String manipulation -->
{{ title | truncate(15) }} <!-- Truncated text... -->
{{ title | replace(' ', '-') | lower }} <!-- URL slug -->
<!-- Advanced string operations -->
{{ url | replace('https://', '') | split('/')[0] }} <!-- Extract domain -->
{{ text | wordcount }} <!-- Count words -->
{{ text | reverse }} <!-- Reverse string -->
<!-- Chaining filters -->
{{ member.title | lower | replace(' ', '-') | replace('&', 'and') }}Text Transformations:
Original: MuizenMesh Webring
UPPERCASE: MUIZENMESH WEBRING
lowercase: muizenmesh webring
Title Case: Muizenmesh Webring
Truncated (15 chars): MuizenMesh...
Slug: muizenmesh-webring
Original: Medialternatives
UPPERCASE: MEDIALTERNATIVES
lowercase: medialternatives
Title Case: Medialternatives
Truncated (15 chars): Medialternative...
Slug: medialternatives
Original: Muizenberg Electricity CC
UPPERCASE: MUIZENBERG ELECTRICITY CC
lowercase: muizenberg electricity cc
Title Case: Muizenberg Electricity Cc
Truncated (15 chars): Muizenberg...
Slug: muizenberg-electricity-cc
Live Member Data Examples:
Medialternatives: slug = "medialternatives"
MuizenMesh: slug = "muizenmesh"
📅 Conditional Logic
View Code: Complex Conditionals
<!-- Multi-level conditionals -->
{% if members | length >= 10 %}
<p>Large Community! {{ members | length }} members</p>
{% elif members | length >= 5 %}
<p>Growing Community! {{ members | length }} members</p>
{% else %}
<p>Small but Mighty! {{ members | length }} members</p>
{% endif %}
<!-- Conditional with calculations -->
{% set feedPercentage = ((membersWithFeeds | length) / (members | length) * 100) | round %}
{% if feedPercentage >= 70 %}
<p>Excellent RSS adoption! {{ feedPercentage }}%</p>
{% elif feedPercentage >= 40 %}
<p>Good RSS adoption at {{ feedPercentage }}%</p>
{% else %}
<p>Low RSS adoption ({{ feedPercentage }}%)</p>
{% endif %}
<!-- Inline conditionals -->
<span class="{{ 'has-feed' if member.feed else 'no-feed' }}">
{{ member.title }}
</span>Community Size Assessment:
🌱 Growing Community! 6 members and counting!
Feed Adoption Rate:
📊 Good RSS adoption at 50%. Room for improvement!
🔧 Custom Macros
View Code: Custom Macro Definition
<!-- Define a reusable macro -->
{% macro memberBadge(member, style='default') %}
{% if style == 'success' %}
{% set bg = '#e8f5e8' %}
{% set color = '#4caf50' %}
{% elif style == 'warning' %}
{% set bg = '#fff3e0' %}
{% set color = '#ff9800' %}
{% else %}
{% set bg = '#e3f2fd' %}
{% set color = '#1976d2' %}
{% endif %}
<span style="background: {{ bg }}; color: {{ color }}; padding: 0.25rem 0.5rem; border-radius: 1rem;">
{{ member.title }}
{% if member.feed %}📡{% endif %}
</span>
{% endmacro %}
<!-- Use the macro -->
{{ memberBadge(member, 'success') }}
{{ memberBadge(member, 'warning') }}Member Badges (Using Custom Macro):
📋 Summary
🎯 What This Demo Shows:
- Data Processing: Filtering, sorting, and mathematical operations
- Conditional Logic: Complex if/else statements and comparisons
- Loops & Iteration: Advanced looping with counters and context
- String Manipulation: Text transformations and formatting
- Dynamic Styling: CSS generation based on data
- Custom Macros: Reusable template components
- Mathematical Operations: Calculations and projections
- Advanced Filters: Built-in and custom data filtering
Nunjucks is much more than basic templating - it's a full-featured template engine that can handle complex data processing, dynamic content generation, and sophisticated presentation logic!