🎨 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 without RSS Feeds

🎯 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)

  1. MECC Blog 📡 RSS
  2. Medialternatives 📡 RSS
  3. MuizeMesh Communities 📡 RSS
  4. Muizenberg Electricity Coop
  5. MuizenMesh
  6. 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

Visit SiteRSS Feed

Theme: Ocean

MuizenMesh

Visit Site

Theme: Sunset

MuizeMesh Communities

Visit SiteRSS Feed

Theme: Forest

Muizenberg Electricity Coop

Visit Site

Theme: Purple

MECC Blog

Visit SiteRSS Feed

Theme: Ocean

Netbones Solutions

Visit Site

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):

Medialternatives 📡 MuizenMesh MuizeMesh Communities 📡 Muizenberg Electricity Coop MECC Blog 📡 Netbones Solutions

📋 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!