Skip to content

Special Purpose Filters

Nimbu provides specialized filters for QR code generation, analytics integration, query parameter handling, color manipulation, and various utility functions.

QR Code Generation

qr

Generate QR code as inline image:

liquid
{{ product.url | qr }}
<!-- Generates: <img src="data:image/png..." alt="QR Code"> -->

{{ page.url | qr, alt: "Scan to visit", class: "qr-code" }}

{{ "https://example.com" | qr, size: 300 }}

Parameters:

  • size - QR code size in pixels (default: 200)
  • alt - Alt text (default: "QR Code")
  • class - CSS class
  • id - Element ID

qr_svg

Generate QR code as SVG:

liquid
{{ contact.vcard | qr_svg }}

{{ wifi_credentials | qr_svg, size: 250 }}

qr_png_url

Get QR code image URL:

liquid
<img src="{{ product.url | qr_png_url }}" alt="Product QR">

<img src="{{ event.url | qr_png_url, size: 400 }}" alt="Event QR">

qr_svg_url

Get QR code SVG URL:

liquid
<img src="{{ page.url | qr_svg_url }}" alt="Page QR">

Analytics Integration

google_analytics

Add Google Analytics tracking:

liquid
{{ 'UA-XXXXX-Y' | google_analytics }}
<!-- Inserts GA tracking code -->

gtm

Add Google Tag Manager:

liquid
{{ 'GTM-XXXXX' | gtm }}
<!-- Inserts GTM container code -->

Query Parameters

add_query_param

Add parameter to URL:

liquid
{{ page.url | add_query_param: 'ref', 'email' }}
<!-- Output: /page?ref=email -->

{{ product.url | add_query_param: 'variant', variant.id }}

{{ url | add_query_param: 'utm_source', 'newsletter' }}

remove_query_param

Remove parameter from URL:

liquid
{{ request.url | remove_query_param: 'page' }}

{{ url | remove_query_param: 'utm_source' }}

query_params

Extract all query parameters:

liquid
{% assign params = request.url | query_params %}

{% for param in params %}
  {{ param[0] }}: {{ param[1] }}
{% endfor %}

Color Utilities

hex_to_rgb

Convert hex color to RGB:

liquid
{{ "#FF5733" | hex_to_rgb }}
<!-- Output: rgb(255, 87, 51) -->

{{ product.color_hex | hex_to_rgb }}

rgb_to_hex

Convert RGB to hex color:

liquid
{{ "rgb(255, 87, 51)" | rgb_to_hex }}
<!-- Output: #FF5733 -->

lighten

Lighten color by percentage:

liquid
{{ "#336699" | lighten: 20 }}
<!-- Output: Lighter version of color -->

{{ brand_color | lighten: 10 }}

darken

Darken color by percentage:

liquid
{{ "#336699" | darken: 20 }}

{{ theme_color | darken: 15 }}

Weight Conversions

to_kg

Convert weight to kilograms:

liquid
{{ product.weight | to_kg }}
<!-- If weight is in grams: 1000 → 1 -->

{{ 2500 | to_kg }}
<!-- Output: 2.5 -->

to_g

Convert weight to grams:

liquid
{{ product.weight | to_g }}

{{ 1.5 | to_g }}
<!-- Output: 1500 -->

to_lb

Convert weight to pounds:

liquid
{{ product.weight | to_lb }}

{{ 1000 | to_lb }}
<!-- 1000g → 2.2 lb -->

to_oz

Convert weight to ounces:

liquid
{{ product.weight | to_oz }}

Utility Filters

random

Generate random number:

liquid
{{ 100 | random }}
<!-- Random number 0-99 -->

{{ 10 | random: 50 }}
<!-- Random number 10-50 -->

modulo

Modulo operation:

liquid
{{ 7 | modulo: 3 }}
<!-- Output: 1 -->

{% if forloop.index | modulo: 2 == 0 %}
  <!-- Even rows -->
{% endif %}

underscore

Convert to snake_case:

liquid
{{ "Hello World" | underscore }}
<!-- Output: hello_world -->

{{ product.name | underscore }}

dasherize

Convert to kebab-case:

liquid
{{ "Hello World" | dasherize }}
<!-- Output: hello-world -->

{{ category.name | dasherize }}

Practical Examples

Product QR Codes for Print

liquid
<div class="product-label">
  <h3>{{ product.name }}</h3>

  <div class="qr-section">
    <p>Scan for more info:</p>
    {{ product.url | qr, size: 150, alt: "Product details" }}
  </div>

  <p class="price">{{ product.price | money_with_currency }}</p>
  <p class="sku">SKU: {{ product.sku }}</p>
</div>

Event Tickets with QR Codes

liquid
<div class="ticket">
  <div class="ticket-header">
    <h2>{{ event.title }}</h2>
    <p class="date">{{ event.start_date | localized_date: "full" }}</p>
  </div>

  <div class="ticket-details">
    <p><strong>Ticket #:</strong> {{ ticket.number }}</p>
    <p><strong>Name:</strong> {{ ticket.attendee_name }}</p>
  </div>

  <div class="qr-code-section">
    <p>Scan at entrance:</p>
    {{ ticket.verification_url | qr_svg, size: 200 }}
  </div>
</div>

WiFi QR Code

liquid
<div class="wifi-access">
  <h3>Guest WiFi</h3>

  {% capture wifi_string %}WIFI:T:WPA;S:{{ site.wifi_ssid }};P:{{ site.wifi_password }};;{% endcapture %}

  <div class="qr-code">
    {{ wifi_string | qr, size: 250, alt: "Scan to connect to WiFi" }}
  </div>

  <div class="manual-info">
    <p><strong>Network:</strong> {{ site.wifi_ssid }}</p>
    <p><strong>Password:</strong> {{ site.wifi_password }}</p>
  </div>
</div>

Contact vCard QR Code

liquid
{% capture vcard %}
BEGIN:VCARD
VERSION:3.0
FN:{{ contact.name }}
EMAIL:{{ contact.email }}
TEL:{{ contact.phone }}
URL:{{ site.url }}
END:VCARD
{% endcapture %}

<div class="contact-card">
  <h3>{{ contact.name }}</h3>
  <p>{{ contact.role }}</p>

  <div class="qr-vcard">
    <p>Scan to save contact:</p>
    {{ vcard | qr, size: 200 }}
  </div>
</div>

URL Tracking with UTM Parameters

liquid
<div class="social-sharing">
  <h4>Share this product:</h4>

  {% assign fb_url = product.url | add_query_param: 'utm_source', 'facebook' | add_query_param: 'utm_medium', 'social' %}

  {% assign tw_url = product.url | add_query_param: 'utm_source', 'twitter' | add_query_param: 'utm_medium', 'social' %}

  {% assign em_url = product.url | add_query_param: 'utm_source', 'email' | add_query_param: 'utm_campaign', 'share' %}

  <a href="https://facebook.com/sharer.php?u={{ fb_url | uri_encode }}" target="_blank">
    Share on Facebook
  </a>

  <a href="https://twitter.com/intent/tweet?url={{ tw_url | uri_encode }}" target="_blank">
    Share on Twitter
  </a>

  <a href="mailto:?body={{ em_url | uri_encode }}">
    Share via Email
  </a>
</div>

Alternating Row Colors

liquid
<table class="data-table">
  {% for item in items %}
    <tr class="{% if forloop.index | modulo: 2 == 0 %}even{% else %}odd{% endif %}">
      <td>{{ item.name }}</td>
      <td>{{ item.value }}</td>
    </tr>
  {% endfor %}
</table>

<style>
.data-table tr.even { background: #f5f5f5; }
.data-table tr.odd { background: #ffffff; }
</style>

Grid Layout with Modulo

liquid
<div class="product-grid">
  {% for product in products %}
    <div class="product-card">
      <!-- Product content -->
    </div>

    {% assign index_plus_one = forloop.index | plus: 1 %}
    {% if index_plus_one | modulo: 4 == 0 %}
      </div><div class="product-grid">
      <!-- Start new row every 4 items -->
    {% endif %}
  {% endfor %}
</div>

Dynamic Color Theming

liquid
<style>
:root {
  --primary-color: {{ site.primary_color }};
  --primary-light: {{ site.primary_color | lighten: 20 }};
  --primary-dark: {{ site.primary_color | darken: 20 }};

  --secondary-color: {{ site.secondary_color }};
  --secondary-rgb: {{ site.secondary_color | hex_to_rgb }};
}

.btn-primary {
  background: var(--primary-color);
  border-color: var(--primary-dark);
}

.btn-primary:hover {
  background: var(--primary-dark);
}

.alert-info {
  background: var(--primary-light);
}
</style>

Shipping Weight Display

liquid
<div class="shipping-info">
  <h4>Shipping Details</h4>

  <p>
    <strong>Weight:</strong>
    {{ product.weight | to_kg }} kg
    ({{ product.weight | to_lb | round: 1 }} lb)
  </p>

  <p>
    <strong>Dimensions:</strong>
    {{ product.length }}cm × {{ product.width }}cm × {{ product.height }}cm
  </p>

  {% if product.weight | to_kg > 5 %}
    <p class="notice">Heavy item - may require special shipping</p>
  {% endif %}
</div>
liquid
<section class="featured-product">
  <h2>Featured Today</h2>

  {% assign random_index = products.size | random %}
  {% assign featured = products[random_index] %}

  <div class="product-showcase">
    <img src="{{ featured.images.first.url | filter, width: '600px' }}" alt="{{ featured.name }}">
    <h3>{{ featured.name }}</h3>
    <p>{{ featured.description }}</p>
    <p class="price">{{ featured.price | money_with_currency }}</p>
    <a href="{{ featured.url }}" class="btn">View Product</a>
  </div>
</section>

Clean URL Parameters

liquid
<!-- Pagination with clean URLs -->
{% if params.page %}
  {% assign prev_page = params.page | minus: 1 %}
  {% assign next_page = params.page | plus: 1 %}

  {% if prev_page > 0 %}
    {% assign prev_url = request.url | remove_query_param: 'page' | add_query_param: 'page', prev_page %}
    <a href="{{ prev_url }}">Previous</a>
  {% endif %}

  {% if next_page <= total_pages %}
    {% assign next_url = request.url | remove_query_param: 'page' | add_query_param: 'page', next_page %}
    <a href="{{ next_url }}">Next</a>
  {% endif %}
{% endif %}

Best Practices

1. QR Code Sizing

Use appropriate sizes for different contexts:

liquid
<!-- ✅ Good: Appropriate sizes -->
{{ url | qr, size: 150 }}  <!-- Print materials -->
{{ url | qr, size: 300 }}  <!-- Posters -->
{{ url | qr, size: 500 }}  <!-- Large displays -->

<!-- ❌ Bad: Too small -->
{{ url | qr, size: 50 }}   <!-- Difficult to scan -->

2. URL Parameter Hygiene

liquid
<!-- ✅ Good: Build clean URLs -->
{% assign clean_url = base_url | add_query_param: 'source', 'email' %}

<!-- ❌ Bad: Manual concatenation -->
{% assign url = base_url | append: '?source=email' %}

3. Color Accessibility

liquid
<!-- ✅ Good: Ensure contrast -->
{% assign bg = "#336699" %}
{% assign text = bg | lighten: 70 %}  <!-- Light text on dark bg -->

<!-- ⚠️ Check contrast ratios -->

4. Random Number Usage

liquid
<!-- ✅ Good: Use for variety, not security -->
{% assign random_index = items.size | random %}

<!-- ❌ Bad: Don't use for security/tokens -->
{% assign token = 1000000 | random %}  <!-- Not cryptographically secure -->

Next Steps

Enhance your themes with special-purpose utilities!