Skip to content

API & JSON Filters

Nimbu provides filters for working with JSON data, making API calls, handling geographical data, and JWT token operations.

JSON Operations

json

Convert object to JSON string:

liquid
{{ product | json }}
<!-- Output: {"id":123,"name":"Product Name","price":29.99} -->

{{ cart.items | json }}

{% assign data = { name: "John", email: "[email protected]" } %}
{{ data | json }}

Pretty Print:

liquid
<pre>{{ product | json }}</pre>

parse_json

Parse JSON string to object:

liquid
{% assign data = '{"name":"John","age":30}' | parse_json %}
{{ data.name }}
<!-- Output: John -->

{% assign config = settings.json_config | parse_json %}
{{ config.api_key }}

Geographical Utilities

country

Convert country code to country name:

liquid
{{ "BE" | country }}
<!-- Output: Belgium -->

{{ "US" | country }}
<!-- Output: United States -->

{{ customer.country_code | country }}

distance

Calculate distance between coordinates:

liquid
{% assign dist = location1 | distance: location2 %}
<!-- Returns distance in kilometers -->

{% assign km = store.coordinates | distance: customer.coordinates %}
{{ km | round }} km away

With Unit:

liquid
{% assign miles = location1 | distance: location2, unit: 'mi' %}
{{ miles | round: 1 }} miles

Gravatar Integration

gravatar

Generate Gravatar URL from email:

liquid
{{ user.email | gravatar }}
<!-- Output: https://gravatar.com/avatar/hash -->

{{ comment.author_email | gravatar, size: 80 }}

{{ user.email | gravatar, size: 200, default: 'identicon' }}

Parameters:

  • size - Image size in pixels (default: 80)
  • default - Fallback image: 404, mp, identicon, monsterid, wavatar, retro, blank
  • rating - Maximum rating: g, pg, r, x

URL Encoding

uri_encode

Encode string for URLs:

liquid
{{ "Hello World!" | uri_encode }}
<!-- Output: Hello%20World%21 -->

<a href="/search?q={{ params.query | uri_encode }}">Search</a>

{{ product.name | uri_encode }}

uri_decode

Decode URL-encoded string:

liquid
{{ "Hello%20World%21" | uri_decode }}
<!-- Output: Hello World! -->

Practical Examples

API Response Handling

liquid
{% comment %}
  Assuming you have API response data from Cloud Code
{% endcomment %}

{% assign api_response = cloud_function_result | parse_json %}

{% if api_response.success %}
  <div class="success-message">
    <h3>{{ api_response.message }}</h3>

    <ul class="results">
      {% for item in api_response.data %}
        <li>
          <strong>{{ item.title }}</strong>
          <p>{{ item.description }}</p>
        </li>
      {% endfor %}
    </ul>
  </div>
{% else %}
  <div class="error-message">
    {{ api_response.error }}
  </div>
{% endif %}

Store Locator

liquid
<div class="store-locator">
  <h2>Find a Store Near You</h2>

  {% if customer.location %}
    {% assign customer_coords = customer.location %}

    {% assign stores_with_distance = "" | split: "" %}

    {% for store in channels.stores.all %}
      {% assign dist = customer_coords | distance: store.coordinates %}

      {% assign store_data = store | json | parse_json %}
      {% assign store_data_with_distance = store_data | add: 'distance', dist %}

      {% assign stores_with_distance = stores_with_distance | push: store_data_with_distance %}
    {% endfor %}

    {% assign sorted_stores = stores_with_distance | sort: 'distance' %}

    <div class="store-list">
      {% for store in sorted_stores limit: 5 %}
        <div class="store-card">
          <h3>{{ store.name }}</h3>
          <p class="address">{{ store.address }}</p>
          <p class="distance">
            {{ store.distance | round: 1 }} km away
          </p>
          <a href="/stores/{{ store.slug }}" class="btn">View Details</a>
        </div>
      {% endfor %}
    </div>
  {% else %}
    <p>Enable location services to find stores near you.</p>
  {% endif %}
</div>

User Comments with Gravatars

liquid
<div class="comments">
  {% for comment in article.comments %}
    <div class="comment">
      <div class="comment-avatar">
        <img
          src="{{ comment.author_email | gravatar, size: 60, default: 'identicon' }}"
          alt="{{ comment.author_name }}">
      </div>

      <div class="comment-content">
        <div class="comment-header">
          <strong>{{ comment.author_name }}</strong>
          <time>{{ comment.created_at | time_ago_in_words }}</time>
        </div>

        <div class="comment-body">
          {{ comment.body }}
        </div>
      </div>
    </div>
  {% endfor %}
</div>

JSON Data Export

liquid
<script>
// Export product data to JavaScript
window.productData = {{ product | json }};

// Export cart data
window.cartData = {{ cart | json }};

// Custom data object
window.siteConfig = {{
  {
    apiEndpoint: '/api/v1',
    locale: locale,
    currency: site.currency,
    features: {
      wishlist: true,
      quickView: true
    }
  } | json
}};
</script>

Search with Encoded Parameters

liquid
<form action="/search" method="get" class="search-form">
  <input
    type="text"
    name="q"
    value="{{ params.q }}"
    placeholder="Search products...">

  {% if params.category %}
    <input type="hidden" name="category" value="{{ params.category }}">
  {% endif %}

  <button type="submit">Search</button>
</form>

{% if params.q %}
  <div class="search-results">
    <h2>Results for "{{ params.q }}"</h2>

    {% assign search_query = params.q | uri_encode %}

    <!-- Share search URL -->
    <a href="{{ request.url }}" class="share-search">
      Share this search
    </a>

    <!-- Results -->
    {% for product in products %}
      <div class="product-result">
        <h3>{{ product.name | highlight: params.q }}</h3>
        <p>{{ product.description | excerpt: params.q, radius: 100 }}</p>
      </div>
    {% endfor %}
  </div>
{% endif %}

Country Selector

liquid
<div class="country-selector">
  <label for="country">Select Your Country:</label>

  <select name="country" id="country">
    {% assign countries = "US,GB,CA,AU,DE,FR,BE,NL" | split: "," %}

    {% for code in countries %}
      <option value="{{ code }}" {% if customer.country_code == code %}selected{% endif %}>
        {{ code | country }}
      </option>
    {% endfor %}
  </select>
</div>

International Shipping Calculator

liquid
<div class="shipping-calculator">
  <h3>Calculate Shipping Cost</h3>

  <form>
    <label>Your Country:</label>
    <select name="country">
      {% for code in shipping_countries %}
        <option value="{{ code }}">
          {{ code | country }}
        </option>
      {% endfor %}
    </select>

    <button type="submit">Calculate</button>
  </form>

  {% if params.country %}
    {% assign country_name = params.country | country %}

    <div class="shipping-result">
      <p>Shipping to {{ country_name }}:</p>

      {% assign rate = shipping_rates[params.country] %}
      {% if rate %}
        <p class="rate">{{ rate | money_with_currency }}</p>
      {% else %}
        <p class="unavailable">Shipping not available to this country.</p>
      {% endif %}
    </div>
  {% endif %}
</div>

Structured Data with JSON-LD

liquid
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": {{ product.name | json }},
  "description": {{ product.description | strip_html | json }},
  "image": {{ product.images.first.url | json }},
  "brand": {
    "@type": "Brand",
    "name": {{ product.brand | json }}
  },
  "offers": {
    "@type": "Offer",
    "price": {{ product.price | json }},
    "priceCurrency": {{ site.currency | json }},
    "availability": "{{ product.available | if: 'https://schema.org/InStock', 'https://schema.org/OutOfStock' }}"
  }
}
</script>

Delivery Zone Checker

liquid
<div class="delivery-checker">
  <h3>Check Delivery Availability</h3>

  <form method="get">
    <input
      type="text"
      name="address"
      placeholder="Enter your address"
      value="{{ params.address }}">

    <button type="submit">Check</button>
  </form>

  {% if params.address and customer.coordinates %}
    {% assign warehouse_location = site.warehouse_coordinates %}
    {% assign distance = customer.coordinates | distance: warehouse_location %}

    {% if distance <= 50 %}
      <div class="delivery-available">
        <p>✓ We deliver to your area!</p>
        <p>You are {{ distance | round: 1 }} km from our warehouse.</p>
        <p>Estimated delivery: 1-2 business days</p>
      </div>
    {% else %}
      <div class="delivery-unavailable">
        <p>Sorry, we don't currently deliver to your area.</p>
        <p>Distance: {{ distance | round }} km (max 50 km)</p>
      </div>
    {% endif %}
  {% endif %}
</div>

Best Practices

1. Validate JSON Data

liquid
<!-- ✅ Good: Check before parsing -->
{% if api_response %}
  {% assign data = api_response | parse_json %}
  {% if data %}
    {{ data.value }}
  {% endif %}
{% endif %}

<!-- ❌ Bad: No validation -->
{% assign data = api_response | parse_json %}
{{ data.value }}

2. Escape User Input in URLs

liquid
<!-- ✅ Good: Encode user input -->
<a href="/search?q={{ params.query | uri_encode }}">Search</a>

<!-- ❌ Bad: Unencoded user input -->
<a href="/search?q={{ params.query }}">Search</a>

3. Use Appropriate Gravatar Defaults

liquid
<!-- ✅ Good: Professional default -->
{{ email | gravatar, size: 80, default: 'mp' }}

<!-- ⚠️ Consider context -->
{{ email | gravatar, default: 'monsterid' }}

4. Cache Distance Calculations

liquid
<!-- ✅ Good: Calculate once, reuse -->
{% assign dist = store.coords | distance: customer.coords %}
{{ dist | round: 1 }} km
Approximately {{ dist | divided_by: 1.5 | round }} minutes

<!-- ❌ Bad: Recalculate multiple times -->
{{ store.coords | distance: customer.coords | round: 1 }} km
{{ store.coords | distance: customer.coords | divided_by: 1.5 }} minutes

Next Steps

Work with APIs and structured data effectively in Nimbu!