Table Of Contents

getPage(pagePath)

Get page by its path

This is going to replace site.root.pages.<pageName>

{$ set about_page = getPage("about.md") %}
<a href="{{ about_page.url }}">{{ about_page.title }}</a>

getPages(folderPath)

Get list of pages by their folder path

This is going to replace site.root.folders.<folderName>

.
├── content
│   ├── jobs
│   │   ├── full-stack.md
│   │   ├── designer.md
│   │   └── product.md
│   └── index.md
.
{$ set job_pages = getPages("jobs") %}
{% for job_page in job_pages %}
<ul>
    <li><a href="{{ job_page.url }}">{{ job_page.title }}</a></li>
</ul>
{% forend %}

range(start, stop)

If you need to iterate over a fixed set of numbers, range generates the set for you. The numbers begin at start and increment by 1 until it reaches stop, not including it.

{% for pageNumber in range(0, 5) %}
    {{ i }},
{% endfor %}

The above outputs 0,1,2,3,4.

Note: Nunjucks range also support stop parameter. We do not support it.

paginate(items, itemsPerPage)

Splits list of items into chunks of itemsPerPage and generates pages for every chunk. A template including this function is executed multiple times, once for every generated page. Each execution it returns a "page" object with list of chunked items for the generated page. The first page will be generated with a usual URL, and the rest of the pages will be generated at ./page{N}/index.html, where N are numbers beginning at 2. The returned "page" object has the following structure:

  • pageNumber - number of the page starting at 1 to N.
  • items - chunked items for the current page
  • itemsCount - number of items for the current page
  • itemsPerPage - number of items per page (same one that was passed to the function)
  • allItems - list of all the items
  • allItemsCount - number of all the items
  • pages - list of page objects. The current object is pages[pageNumber - 1]
  • pagesCount - number of generated pages (including the first page)
  • url - the URL of the current page
  • hasPrev - boolean value indicating if there is a previous page
  • prev - previous page, same as pages[pageNumber - 2]
  • hasNext - boolean value indicating if there is a next page
  • next - next page, same as pages[pageNumber]
  • first - first page, same as pages[0]
  • last - last page, same as pages[pagesCount - 1]

Example:

{% set paginator = paginate(pages, 5) %}
{% set posts = paginator.items %}
<ul>
{% for post in posts %}
    <li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
<p>page {{ paginator.pageNumber }} of {{ paginator.pagesCount }}</p>
<p>
    {% if paginator.hasPrev %}
        <a href="{{ paginator.prev.url }}">previous page</a>
    {% else %}
        <span class="disabled">previous page</span>
    {% endif %} |
    {% if paginator.hasNext %}
        <a href="{{ paginator.next.url }}">next page</a>
    {% else %}
        <span class="disabled">next page</span>
    {% endif %}
</p>

The above example will generate following HTML for the second page located at page2/index.html (assuming there are more than 10 posts):

<ul>
  <li><a href="/posts/post5.html">Post 5</a></li>
  <li><a href="/posts/post6.html">Post 6</a></li>
  <li><a href="/posts/post7.html">Post 7</a></li>
  <li><a href="/posts/post8.html">Post 8</a></li>
  <li><a href="/posts/post9.html">Post 9</a></li>
</ul>
<p>page 2 of 3<p>
<p>
  <a href="/index.html">previous page</a> |
  <a href="/page3/index.html">previous page</a>
</p>

cycler(item1, item2, ...itemN)

An easy way to rotate through several values is to use cycler, which takes any number of arguments and cycles through them.

{% set cyc = cycler("odd", "even") %}
{% for row in rows %}
  <div class="{{ cyc.next() }}">{{ row.name }}</div>
{% endfor %}

In the above example, odd rows have the class "odd" and even rows have the class "even".

This method is native Nunjucks cycler.

classNames(...args)

Same as https://github.com/JedWatson/classnames

Note: arrays are not aupported

<div {{ classNames('foo', {bar: false, baz: 4 == 4}) }}></div>

The above outputs:

<div class="foo baz"></div>

attribute(name, value[, condition])

This function can be used in several cases:

  1. As a syntactic sugar when the attribute value needs to be a variable:

    <div {{ attribute("id", element_id) }}></div>
    

    is same as writing

    <div id="{{ element_id }}"></div>
    
  2. When the attribute and its value should be rendered depending on some condition

    <div {{ attribute("id", element_id, has_id) }}></div>
    

    is same as writing

    <div {% if has_id %}id="{{ element_id }}"{% endif %}></div>
    

    In the example above, the id attribute will not be rendered if has_id is falsy - an empty string, null, not defined, etc.

  3. If an empty attribute needs to be rendered depending on some condition, such as the disabled attribute of an input tag, then the value parameter can be set to null.

    <input type="text" {{ attribute("disabled", null, is_disabled) }} />
    

    is same as writing

    <div {% if is_disabled %}disabled{% endif %}></div>
    

    In the above example, if is_disabled is true, the following output will be generated:

    <input type="text" disabled /> 
    
  4. When the attribute name depends on some variable

    {% set name = "name" %}
    {% set value = "author" %}
    <meta {{ attribute(name, author) }} content="John Doe">
    

    will generate:

    <meta name="author" content="John Doe">
    

    Don't use tokens to render attribute names. Stackbit will not be able to transpile that into React-based sites.

    <meta ~~{{ name }}="{{ author }}"~~ content="John Doe">