Swiftpack.co - Package - stencilproject/Stencil


Build Status

Stencil is a simple and powerful template language for Swift. It provides a syntax similar to Django and Mustache. If you're familiar with these, you will feel right at home with Stencil.


There are {{ articles.count }} articles.

  {% for article in articles %}
    <li>{{ article.title }} by {{ article.author }}</li>
  {% endfor %}
import Stencil

struct Article {
  let title: String
  let author: String

let context = [
  "articles": [
    Article(title: "Migrating from OCUnit to XCTest", author: "Kyle Fuller"),
    Article(title: "Memory Management with ARC", author: "Kyle Fuller"),

let environment = Environment(loader: FileSystemLoader(paths: ["templates/"]))
let rendered = try environment.renderTemplate(name: "article_list.html", context: context)



Stencil follows the same philosophy of Django:

If you have a background in programming, or if you’re used to languages which mix programming code directly into HTML, you’ll want to bear in mind that the Django template system is not simply Python embedded into HTML. This is by design: the template system is meant to express presentation, not program logic.

The User Guide

Resources for Stencil template authors to write Stencil templates:

Resources to help you integrate Stencil into a Swift project:

Projects that use Stencil

Sourcery, SwiftGen, Kitura, Weaver, Genesis


Stencil is licensed under the BSD license. See LICENSE for more info.


Stars: 1708
Help us keep the lights on


0.13.0 - Sep 25, 2018



  • You can now use parentheses in boolean expressions to change operator precedence.
    Ilya Puchka #165
  • Added method to add boolean filters with their negative counterparts.
    Ilya Puchka #160
  • Now you can conditionally render variables with {{ variable if condition }}, which is a shorthand for {% if condition %}{{ variable }}{% endif %}. You can also use else like {{ variable1 if condition else variable2 }}, which is a shorthand for {% if condition %}{{ variable1 }}{% else %}{{ variable2 }}{% endif %}
    Ilya Puchka #243
  • Now you can access string characters by index or get string length the same was as if it was an array, i.e. {{ 'string'.first }}, {{ 'string'.last }}, {{ 'string'.1 }}, {{ 'string'.count }}.
    Ilya Puchka #245

Bug Fixes

  • Fixed the performance issues introduced in Stencil 0.12 with the error log improvements.
    Ilya Puchka #230
  • Now accessing undefined keys in NSObject does not cause runtime crash and instead renders empty string.
    Ilya Puchka #234
  • for tag: When iterating over a dictionary the keys will now always be sorted (in an ascending order) to ensure consistent output generation.
    David Jennes #240

Internal Changes

0.12.1 - Aug 30, 2018

Internal Changes

  • Updated the PathKit dependency to 0.9.0 in CocoaPods, to be in line with SPM.
    David Jennes #227

0.12.0 - Aug 26, 2018


  • Added an optional second parameter to the include tag for passing a sub context to the included file.
    Yonas Kolb #214
  • Variables now support the subscript notation. For example, if you have a variable key = "name", and an object item = ["name": "John"], then {{ item[key] }} will evaluate to "John".
    David Jennes #215
  • Adds support for using spaces in filter expression.
    Ilya Puchka #178
  • Improvements in error reporting.
    Ilya Puchka #167

Bug Fixes

0.11.0 - Apr 5, 2018


  • Added support for resolving superclass properties for not-NSObject subclasses
  • The {% for %} tag can now iterate over tuples, structures and classes via their stored properties.
  • Added split filter
  • Allow default string filters to be applied to arrays
  • Similar filters are suggested when unknown filter is used
  • Added indent filter
  • Allow using new lines inside tags
  • Added support for iterating arrays of tuples
  • Added support for ranges in if-in expression
  • Added property forloop.length to get number of items in the loop
  • Now you can construct ranges for loops using a...b syntax, i.e. for i in 1...array.count

Bug Fixes

  • Fixed rendering {{ block.super }} with several levels of inheritance
  • Fixed checking dictionary values for nil in default filter
  • Fixed comparing string variables with string literals, in Swift 4 string literals became Substring and thus couldn't be directly compared to strings.
  • Integer literals now resolve into Int values, not Float
  • Fixed accessing properties of optional properties via reflection
  • No longer render optional values in arrays as Optional(..)
  • Fixed subscription tuples by value index, i.e. {{ tuple.0 }}

0.10.1 - Nov 17, 2017


  • Add support for Xcode 9.1.