Skip to main content

How to use Liquid with NationBuilder

NationBuilder uses the open source liquid template language to access objects and variables. Liquid allows our customers complete design freedom while maintaining the integrity of our servers. There are two basic types of markup in liquid: Output and Tags.

Table of Contents



Liquid Tags

Tags are surrounded by {% a curly bracket and a percent %} and drive the logic of templates. They are responsible for loops and branching logic.

Logic Tags

  • {% comment %} - Comments will be hidden.
  • Comments

    {% comment %}Remove the code below when ready{% endcomment %}

    Messages contained within a comment tag will not display. They will also be hidden from the page's HTML source code.

  • {% raw %} - No liquid will be parsed within these tags.
  • Raw

    The raw tag prevents the {{ output_tag }} from executing.

  • {% if %} - Conditional statement to determine if something is true or not.
  • If

    {% if page.is_homepage? == true %}
    	<h2>Welcome to my homepage!</h2>
    {% endif %}

    This conditional will check if the page is the homepage, and if it is, it will display the welcome message.


    {% if page.is_homepage? == true %}
    	<h2>Welcome to my homepage!</h2>
    {% elsif page.slug == "blog" %}
    	<h2>Welcome to my blog!</h2>
    {% endif %}

    This conditional uses {% elsif %} for multiple if statements.

  • {% else %} - Indicates everything else that was not included in conditional statement.
  • Else

    {% if page.is_homepage? == true %}
    	<h2>Welcome to my homepage!</h2>
    {% else %}
    	<h2>Welcome to my NON homepage!</h2>
    {% endif %}

    This will check if the page is the homepage, and if it is, it will display the welcome message. Everything else will see a different message.

  • {% unless %} - Conditional statement to determine if not true, then it will do something.
  • Unless

    {% unless signup.first_name == 'john' %}Hello non-john{% endunless %}

    This will check if the signup first name is not john, and if it is not, it will display the welcome message.

  • {% case %} - If you need more than one condition you can use the Case Statement.
  • Case

    {% case page.slug %}
    {% when 'europe_main' %}
    	{% include "europe_nav" %}
    {% when 'asia_main' %}
    	{% include "asia_nav" %}
    {% else %}
    	{% include "nav" %}
    {% endcase %}

    This will display a different partial template for navigation depending on the page slug.

  • {% for %} - Use "for loops" if you want to display an array of objects in a group.
  • For loops

    {% for signup in site.recent_supporters_with_pictures %}{{ signup.profile_image }}{% endfor %}

    This will display an array of recent supporters with images.


    Attributes to influence objects you receive from loop:

    • limit:# - lets you restrict how many objects you get in an array.
    • offset:# - lets you start the array with the nth item.
    {% for post in page.blog.most_recent_blog_posts limit:10 offset:0 %}

    Limits the number of recent blog posts to 10, starting from 0.


    Reversing the loop:

    {% for post in page.blog.most_recent_blog_posts reversed %}

    Reverses the order of the most recent blog posts, showing the oldest in the forloop first.


    Helper variables for extra styling:

    • forloop.length - length of the entire for loop
    • forloop.index - index of the current iteration
    • forloop.index0 - index of the current iteration (zero based)
    • forloop.rindex - how many objects are still left?
    • forloop.rindex0 - how many objects are still left? (zero based)
    • forloop.first - is this the first iteration?
    • forloop.last - is this the last iteration?
    {% for feature in page.features %}{% if forloop.index == 1 %}first slide{% elsif forloop.index == 2 %}second slide{% endif %}{% endfor %}

    'index == 1' means the first slide in the page features forloop (slider).

  • {% tablerow %} - Generates table rows/cells for a loop of objects in array.
  • Table Row

    • limit:# - lets you restrict how many objects you get in an array.
    • cols:# - lets you set the number of columns.
    <table>
    {% tablerow event in page.calendar.events_past cols: 2 %}
    	 <td><a href="{{ event.url }}">{{ event.name }}</a></td>
    {% endtablerow %}
    </table>

    This will generate a 2 column table of linked past event names.


    Helper variables for extra styling:

    • tablerowloop.length - length of the entire table row
    • tablerowloop.index - index of the current iteration
    • tablerowloop.index0 - index of the current iteration (zero based)
    • tablerowloop.rindex - how many items are still left?
    • tablerowloop.rindex0 - how many items are still left? (zero based)
    • tablerowloop.first - is this the first iteration?
    • tablerowloop.last - is this the last iteration?
    • tablerowloop.col - index of column in the current row
    • tablerowloop.col0 - index of column in the current row (zero based)
    • tablerowloop.col_first - is this the first column in the row?
    • tablerowloop.col_last - is this the last column in the row?

  • {% cycle %} -Usually used within a loop to alternate between values.
  • Cycle

    <table>
    {% tablerow event in page.calendar.events_past cols: 1 %}
    	<td style="background:{% cycle '#FF0000', '#00FF00' %};">
    	<a href="{{ event.url }}">{{ event.name }}</a></td>
    {% endtablerow %}
    </table>

    This will generate a single column table listing past event names in alternating red and green rows.

  • {% capture %} - Block tag that captures text into a new variable.
  • Capture

    {% capture fullurl %}http://yournationslug.nationbuilder.com{{ request.url_path }}{% endcapture %}

    This newly-created output of {{ fullurl }} will now produce the URL of the page you are on.

  • {% assign %} - Assigns some value to a variable.
  • Assign

    {% assign thermo_width = 370 %}

    This assigns the thermo_width a value of 370px.

  • {% include %} - Insert a partial template into your layout.
  • Include

    {% include "features" %}

    This will insert the _features.html partial template wherever the tag is placed.

  • {% subpage %} - Associate a page slug with an HTML snippet for display.
  • Subpage

    {% subpage "page_slug" with "html_snippet" %}

    This will display the content of the HTML snippet with the settings of the page_slug in question. More detailed instructions on this method and on creating an HTML snippet can be found here.

  • {% tag %} - Associate pages with a specific page tag with an HTML snippet for display.
  • Tag

    {% tag "page_tag_slug" with "html_snippet" %}

    This will display the content of the HTML snippet with the settings of pages tagged with the specific page tag's slug. More detailed instructions on this method can be found here.

    Liquid logic tags use comparison and logic operators to test for true or false. Comparison operators are used to determine equality or difference between variables or values, while logical operators are used to determine the logic between them .

    Comparison & Logic Operators

  • == equal.
  • Equal

    {% if page.slug == "blog" %}{% include "banner" %}{% endif %}

    This conditional statement checks to see if the page slug equals blog. If it is true, it will display the include "banner."

  • != not equal.
  • Not Equal

    {% if page.slug != "blog" %}{% include "blog-ad" %}{% endif %}

    This conditional statement checks to see if the page slug is not blog. If it is not, it will display the include "blog-ad."

  • > bigger than.
  • Bigger Than

    {% if page.headline.size > 0 %}
    	<div id="headline"><h2>{{ page.headline }}</h2></div>
    {% endif %}

    This conditional statement checks to see if the page headline is bigger than 0 characters. If it is true, it will display it.

  • < less than.
  • Less Than

    {% if page.donations_count < 1 %}
    	JUST STARTED
    {% else %}
    	{{ page.donations_amount_format  }} raised
    {% endif %}

    This conditional statement checks to see if the page has less than 1 donation. For everything else, it will display the words "JUST STARTED." If it has more, it will display the amount raised.

  • >= bigger or equal.
  • Bigger or Equal

    {% if page.petition.signatures_with_images.size >= 4 %}
    	<div class="padtop">
    		{% for signature in page.petition.signatures_with_images %}
    			<img src="{{ signature.large_square_image_url }}" border="0" width="140" height="140">
    		{% endfor %}
    	</div>
    {% endif %}

    This conditional statement checks to see if the page has petition signatures with images. If it is true, it will display petition images in a forloop.

  • <= less or equal.
  • Less or Equal

    {% if event.event.rsvps_count <= 1 %}
    	{{ event.event.rsvps_count }} rsvp{% if event.event.rsvps_count > 1 %}s{% endif %}
    {% endif %}

    These conditional statements check to see if there are 1 or less than 1 RSVPs to an event. If true, it will display "rsvp" and if there are more than 1, it will display "rsvps".

  • or this or that.
  • Or

    {% if page.slug == 'europe_signup' or page.slug == 'asia_signup' or page.slug == 'australia_signup' %}
    	{% include "signup_header" %}
    {% else %}

    This conditional statement checks to see if the page slug is any of those, if any are true it will display the "signup_header" on those pages.

  • and must be this and that.
  • And

    {% if page.petition.is_image? and page.petition.signatures_with_images.size >= 4 %}
    	<div class="padtop">
    	{% for signature in page.petition.signatures_with_images %}
    		<img src="{{ signature.large_square_image_url }}" border="0" width="140" height="140">
    	{% endfor %}
    	</div>
    {% endif %}

    This conditional statement checks to see if the page has signatures with images, and if there are 4 or more. If both are true, it will display petition images in a forloop.

  • contains includes the substring if used on a string, or element if used on an array.
  • Contains

    {% if request.current_signup.tags contains "Regional Organizer" %}
    	{% include "admin_nav" %}
    {% endif %}

    This conditional statement checks if a logged-in user is tagged as "Regional Organizer." If that is true, it will display the special admin nav.


    Liquid Output and Object Reference Guide

    Outputs are surrounded by {{ two curly brackets }} and are replaced with the data they reference. You can use these output variables to display dynamic content.

    Output Variables and objective reference guide

  • nation settings - Output variables for website settings and overall nation stats.
  • Website Setting Output Variables

  • site
  • settings
  • election
  • All of these links go to separate pages.

  • user & account variables - Output variables for user sessions, profiles and account settings.
  • page variables - Output variables for different page-type templates.
  • Special Outputs

  • theme['filename'] - Generates absolute link to a file in theme directory.
  • <script type="text/javascript" src="{{ theme['jquery.fancybox.pack.js'] }}"></ script>

    Produces a direct link to the javascript file: jquery.fancybox.pack.js, located under Pages>Theme>Files.

  • now - Displays the current date and time.
  • Now

    {{ "now" | date: "%A, %B %d, %Y" }} = Saturday, April 20, 2024

    Use the date filters below to customize the output of the {{ "now" }} drop

    Filters

    Filters are simple methods used in Output markup, and run from left to right. When there are no more filters, the template will receive the resulting string.

    String Filters

  • append - Append characters to a string.
  • Append

    {{ page.headline | append: ''}}

    Appends an image at the end of the Page Headline output.

    {{ page.headline | append: ' by Author'}}

    Appends the words 'by Author' to the end of the Page Headline output.

  • capitalize - Capitalizes the first word in a string.
  • Capitalize

    {{ page.headline | capitalize }}

    Capitalizes the first words in a page's headline field.

  • date - Reformat a date syntax reference.
  • Date

    • %a - The abbreviated weekday name ("Sun'')
    • %A - The full weekday name ("Sunday'')
    • %b - The abbreviated month name ("Jan'')
    • %B - The full month name ("January'')
    • %c - The preferred local date and time representation
    • %d - Day of the month (01..31)
    • %H - Hour of the day, 24-hour clock (00..23)
    • %I - Hour of the day, 12-hour clock (01..12)
    • %j - Day of the year (001..366)
    • %m - Month of the year (01..12)
    • %M - Minute of the hour (00..59)
    • %p - Meridian indicator ("AM'' or "PM'')
    • %S - Second of the minute (00..60)
    • %U - Week number of the current year, starting with the first Sunday as the first day of the first week (00..53)
    • %W - Week number of the current year, starting with the first Monday as the first day of the first week (00..53)
    • %w - Day of the week (Sunday is 0, 0..6)
    • %x - Preferred representation for the date alone, no time
    • %X - Preferred representation for the time alone, no date
    • %y - Year without a century (00..99)
    • %Y - Year with century
    • %Z - Time zone name
    • %% - Literal "%'' character
    {{ event.event.local_start_at | date: '%A, %B %d, %Y at %I:%M %p' }}{% if page.event.is_multi_day? %} through {{ page.event.local_end_at | event_date }}{% endif %}

    Will display the date in this format: "Sunday, September 29, 2012 at 6:30pm through October 01, 2012"

  • default - Displays a default value for an empty variable.
  • Default

    {{ '' | default: "Default Text" }} = Default Text

    The default value is returned if the variable resolves to nil or an empty string "". A string containing whitespace characters will not resolve to the default value.

  • downcase - Convert an input string to lowercase.
  • Downcase

    {{ page.headline | downcase }}

    Converts the page headline output into all lowercase letters.

  • escape - Escapes a string without rendering HTML tags
  • Escape

    {{ "

    test

    " | escape }}

    HTML tags are not rendered: <p>test</p>

  • prepend - Prepend characters to a string.
  • Prepend

    {{ page.headline | prepend: ''}}

    Adds an image in front of the Page Headline output.

  • remove - Removes all occurrences of the substring from the input.
  • Remove

    {{ post.blog_post.content | remove: 'the' }}

    Removes all occurrences of 'the' in the output for the blog post content tag.

  • remove_first - Removes only the first occurrence of the substring from the input.
  • Remove First

    {{ post.blog_post.content | remove_first: 'the' }}

    Removes only the first occurrence of 'the' in the output for the blog post content tag.

  • replace - Replaces one thing from the input with another.
  • Replace

    {{ "polar bears and polar ice caps" | replace: 'polar', 'brown' }}

    The resulting text would be "brown bears and brown ice caps"

  • replace_first - Replaces only the first instance of a string from the input with another.
  • Replace_first

    {{ "polar bears and polar ice caps" | replace_first: 'polar', 'brown' }}

    The resulting text would be: "brown bears and polar ice caps"

  • slice - Returns a substring.
  • Slice

    {{ "hello" | slice: 0 }} = h
    {{ "hello" | slice: 1 }} = e
    {{ "hello" | slice: 1,3 }} = ell

    The slice filter returns a substring, starting at the specified index. An optional second parameter can be passed to specify the length of the substring. If no second parameter is given, a substring of one character will be returned.

  • split - Divides a string into an array based on a substring.
  • Split

    {% assign split_pieces = "these-are-words-with-a-split-character" | split: '-' %}
    {{ split_pieces[0] }} = these
    {{ split_pieces[1] }} = are
    {{ split_pieces[2] }} = words
    {{ split_pieces[3] }} = with
    {{ split_pieces[4] }} = a
    {{ split_pieces[5] }} = split
    {{ split_pieces[6] }} = character

    The split filter takes on a substring as a delimiter to divide a string into an array.

  • strip - Strips whitespace from a string.
  • Strip

    {{ '     too many spaces     ' | strip }} = "too many spaces"

    Strips tabs, spaces, and newlines (whitespace) from both the left and right sides of a string.

  • lstrip - Strips whitespace from the left side of a string.
  • Left Strip

    {{ '     too many spaces     ' | lstrip }} = "too many spaces     "

    Strips tabs, spaces, and newlines (whitespace) from only the left side of a string.

  • rstrip - Strips whitespace from the right side of a string.
  • Right Strip

    {{ '     too many spaces     ' | rstrip }} = "     too many spaces"

    Strips tabs, spaces, and newlines (whitespace) from only the right side of a string.

  • strip_html - Strips all html tags from the text passed to the block.
  • Strip HTML

    {{ post.blog_post.content | strip_html }}

    Removes all html tags from the blog post content.

  • truncatechars - Truncate a string down to x characters. (replaced truncate)
  • Truncate Characters

    {{ post.headline | truncatechars:10 }}

    Limits the amount of characters displayed from the Post Headline to 10.

  • truncatewords - Truncate a string down to x words.
  • Truncate Words

    {{ post.headline | truncatewords:10 }}

    Limits the amount of characters displayed from the Post Headline to 10.

  • paginate - Segments output into numbered pages when long.
  • Paginate

    {{ page.blog.most_recent_blog_posts | paginate }}

    Paginates the most recent blog posts.

  • uniq - Removes duplicate instances of an element.
  • Uniq

    {% assign duplicateItems = "one one two two three three four four" %}
    {{ duplicateItems | split: ' ' | uniq }} = "onetwothreefour"

    Removes any duplicate instances of an element in an array.

  • upcase - Convert an input string to uppercase.
  • Upcase

    {{ page.headline | upcase }}

    Converts the page headline output into all capital letters.

  • url_encode - Replaces all characters in a string with their escaped variants for use in URLs.
  • URL Encode

    {{ " & " | url_encode }}

    Replaces any special characters with appropriate %XX replacements, including the ampersand (&): %3Chello%3E+%26+%3Cgoodbye%3E

  • md5 - Converts a string into an MD5 hash.
  • md5

    {{ page.name | md5 }}

    Converts a string into an MD5 hash, e.g. page.name: fff5fd234956c4c841290a9c423f9a81

  • sha256 - Converts a string into a SHA-256 hash.
  • sha256

    {{ page.name | sha256 }}

    Converts a string into a SHA-256 hash, e.g. page.name: 1589bc5b0028a0281915e82ef56907632e295e77340223a72d935828713b50d1

  • hmac_sha1 - Converts a string into a SHA-1 hash using a hash message authentication code (HMAC). Pass the secret key for the message as a parameter to the filter.
  • hmac_sha1

    {% assign my_secret_string = "MySecretString" | hmac_sha1: "secret_key" %}
    My encoded string is: {{ my_secret_string }}

    Converts a string into a SHA-1 hash, e.g.
    My encoded string is: 3bd702e964f598b21130064c4c62e0779936c123

  • hmac_sha256 - Converts a string into a SHA-256 hash using a hash message authentication code (HMAC). Pass the secret key for the message as a parameter to the filter.
  • hmac_sha256

    {% assign my_secret_string = "MySecretString" | hmac_sha256: "secret_key" %}
    My encoded string is: {{ my_secret_string }}

    Converts a string into a SHA-256 hash, e.g.
    My encoded string is: 95be5b9ec4695051549e7fe35bd6191ae6e414e7e91eb5430a43d7bfffc45a8a

  • hmac_sha512 - Converts a string into a SHA-512 hash using a hash message authentication code (HMAC). Pass the secret key for the message as a parameter to the filter.
  • hmac_sha512

    {% assign my_secret_string = "MySecretString" | hmac_sha512: "secret_key" %}
    My encoded string is: {{ my_secret_string }}

    Converts a string into a SHA-512 hash, e.g.
    My encoded string is: 48252f4340451f55fdefd71b0bd5883ae88ab007d3f5210d98b0ad86ddf8682c3308bc25970ff20fbcdbd59154b02863251daa3ef25940696841e4a73e5977fb

    Math Filters

  • plus - Adding input to object.
  • Plus

    {{ '10' | plus:5 }} = 15
  • minus - Subtracting input from object.
  • Minus

    {{ '10' | minus:5 }} = 5
  • times - Multiplying object by x.
  • Times

    {{ '10' | times:5 }} = 50
  • divided_by - Dividing object by x.
  • Divided By

    {{ '20' | divided_by:5 }} = 4
  • modulo - Returns the remainder after dividing numbers.
  • Modulo

    {{ '26' | modulo:5 }} = 1

    Divides an output by a number and returns the remainder.

  • round - Rounds output to the nearest integer or specificed number of decimal places.
  • Round

    {{ '10.34' | round }} = 10

    Rounds the output to the nearest integer.

    {{ '10.345678' | round: 2 }} = 10.35

    Rounds the output to the nearest specified number of decimal places.

  • ceil - Rounds up to the nearest integer.
  • Ceil

    {{ '10.34' | ceil }} = 11

    Rounds an output up to the nearest integer.

  • floor - Rounds down to the nearest integer.
  • Floor

    {{ '10.34' | floor }} = 10

    Rounds an output down to the nearest integer.

    Array Filters

  • join - Combines the elements of an array.
  • Join

    {{ 'site.page_tags' | join: ', ' }} = tag1, tag2, tag3

    Combines the elements of an array with the character passed as the delimiter. The result is a single string.

  • first - Returns the first element of an array.
  • First

    {{ 'site.page_tags' | first }} = tag1

    Returns the first element of an array

  • last - Returns the last element of an array.
  • Last

    {{ 'site.page_tags' | last }} = tag3

    Returns the last element of an array

  • map - Creates a string from the values of one array element.
  • Map

    {% assign mapped_tags = site | map: 'page_tags' %}
    {{ mapped_tags }}= tag1tag2tag3

    Accepts an array element's attribute as a parameter and creates a string out of each array element's value.

  • size - Returns the size of a string or an array.
  • Size

    {{ 'site.page_tags' | size }} = 3

    Returns the size of a string or an array.

    Size can be used in dot notation, in cases where it needs to be used inside a tag:

    {% if array.element.size > 10 %}
    	There are 10 of this element.
    {% endif %}


    Dive into more custom theme documentation