8 Filters


8.1 Overview

You can modify variables for display by using filters.

Filters look like this: {{ name|lower }}. This displays the value of the {{ name }} variable after being filtered through the >>:tfilter:‘lower‘<< filter, which converts text to lowercase. Use a pipe (|) to apply a filter.

Filters can be “chained.” The output of one filter is applied to the next. {{ text|escape|linebreaks }} is a common idiom for escaping text contents, then converting line breaks to <p> tags.

Some filters take arguments. A filter argument looks like this: {{ bio|truncatewords:30 }}. This will display the first 30 words of the bio variable.

Filter arguments that contain spaces must be quoted; for example, to join a list with commas and spaced you’d use {{ list|join:", " }}.

Djula provides about thirty built-in template filters. You can read all about them in the built-in filter reference. To give you a taste of what’s available, here are some of the more commonly used template filters:


8.2 List of filters


8.2.1 add

Adds the argument to the value.

For example:

{{ value|add:2 }}

If value is 4, then the output will be 6.


8.2.2 addslashes

Adds slashes before quotes. Useful for escaping strings in CSV, for example.

For example:

{{ value|addslashes }}

If value is "I'm using Djula", the output will be "I\'m using Djula".


8.2.3 capfirst

Capitalizes the first character of the value. If the first character is not a letter, this filter has no effect.

For example:

{{ value|capfirst }}

If value is "djula", the output will be "Djula".


8.2.4 cut

Removes all values of arg from the given string.

For example:

{{ value|cut:" " }}

If value is "String with spaces", the output will be "Stringwithspaces".


8.2.5 date

Formats a date

Example::

{{ date-today | date }}

A LOCAL-TIME format spec can be provided:

(defvar timestamp 3752179200)
{{ timestamp | date:(:year "/" (:month 2) "/" (:day 2)) }} ;; shows 2018/11/26

8.2.6 time

Formats a time

Example:

{{ time-now | time }}

8.2.7 datetime

Formats a date and time

Example:

{{ time-now | datetime }}

8.2.8 default

If value evaluates to False, uses the given default. Otherwise, uses the value.

For example:

{{ value|default "nothing" }}

If value is "" (the empty string), the output will be nothing.


8.2.9 reverse

Takes a list and returns that list reversed.

For example:

{{ list | reverse }}

8.2.10 divisibleby

Returns True if the value is divisible by the argument.

For example:

{{ value|divisibleby:"3" }}

If value is 21, the output would be True.


8.2.11 sort

Takes a list and returns that list sorted.

For example:

{{ list | sort }}

8.2.12 first

Returns the first item in a list.

For example:

{{ value|first }}

If value is the list ("a" "b" "c"), the output will be "a".


8.2.13 join

Joins a list with a string.

For example:

{{ value|join:" // " }}

If value is the list ("a" "b" "c"), the output will be the string "a // b // c".


8.2.14 last

Returns the last item in a list.

For example:

{{ value|last }}

If value is the list ("a" "b" "c" "d"), the output will be the string "d".


8.2.15 length

Returns the length of the value. This works for both strings and lists.

For example:

{{ value|length }}

If value is ("a" "b" "c" "d") or "abcd", the output will be 4.


8.2.16 length_is

Returns True if the value’s length is the argument, or False otherwise.

For example:

{{ value|length_is:"4" }}

If value is ['a', 'b', 'c', 'd'] or "abcd", the output will be True.


8.2.17 linebreaks

Replaces line breaks in plain text with appropriate HTML; a single newline becomes an HTML line break (<br />) and a new line followed by a blank line becomes a paragraph break (</p>).

For example:

{{ value|linebreaks }}

If value is Joel\nis a slug, the output will be <p>Joel<br />is a slug</p>.


8.2.18 linebreaksbr

Converts all newlines in a piece of plain text to HTML line breaks (<br />).

For example:

{{ value|linebreaksbr }}

If value is Joel\nis a slug, the output will be Joel<br />is a slug.


8.2.19 lower

Converts a string into all lowercase.

For example:

{{ value|lower }}

If value is Still MAD At Yoko, the output will be still mad at yoko.


8.2.20 make_list

Returns the value turned into a list. For a string, it’s a list of characters. For an integer, the argument is cast into an unicode string before creating a list.

For example:

{{ value|make_list }}

If value is the string "Joel", the output would be the list ['J', 'o', 'e', 'l']. If value is 123, the output will be the list ['1', '2', '3'].


8.2.21 safe, escape

Marks a string as not requiring further HTML escaping prior to output. When autoescaping is off, this filter has no effect.

Note: If you are chaining filters, a filter applied after safe can make the contents unsafe again. For example, the following code prints the variable as is, unescaped:

{{ var|safe|escape }}

8.2.22 slice

Returns a slice of a sequence (i.e. lists, vectors, strings)

Uses the Common Lisp cl-slice library.

Syntax:

{{ seq | slice: slices }}

Each slice selects a subset of subscripts along the corresponding axis.

  • A nonnegative integer selects the corresponding index, while a negative integer selects an index counting backwards from the last index:
    {{ list | slice: 4 }}
    

if the list is (1 2 3 4 5 6) it will output (5)

  • (start . end) to select a range. When end is NIL, the last index is included.

Each boundary is resolved according to the other rules if applicable, so you can use negative integers:

{{ string | slice: (0 . 5) }}
{{ string | slice: (5 . nil) }}

if the string is "Hello world" is will output Hello and world.


8.2.23 force-escape

Forces escaping HTML characters (<, >, ', \, &):

{{ value | force-escape }}

It calls djula::escape-for-html.


8.2.24 format

Formats the variable according to the argument, a string formatting specifier. This specifier uses Common Lisp string formatting syntax

For example:

{{ value | format:"~:d" }}

If value is 1000000, the output will be 1,000,000.


8.2.25 replace … with

The replace and the with filters work together:

{{ value | replace:regexp | with:string }}

This will replace all occurences of the regexp in “value” with a new string, using ppcre:regex-replace-all.


8.2.26 rest

Returns the rest of a list (aka cdr).

For example:

{{ values|rest }}

If values is the list ("a" "b" "c"), the output will be ("b" "c").


8.2.27 scan

Extracts and displays a regexp from the value:

{{ value | scan:regexp }}

This will display only the text that matches the regexp (using ppcre:scan-to-strings).


8.2.28 time

Formats a time according to the given format.

For example:

{{ value | time }}

8.2.29 truncatechars

Truncates a string if it is longer than the specified number of characters. Truncated strings will end with the :cl:symbol:ELLISION-STRING, which defaults to “…”.

Argument: Number of characters to truncate to

For example:

{{ value|truncatechars:9 }}

If value is "Joel is a slug", the output will be "Joel i...".


8.2.30 upper

Converts a string into all uppercase.

For example:

{{ value|upper }}

If value is "Joel is a slug", the output will be "JOEL IS A SLUG".


8.2.31 urlencode

Escapes a value for use in a URL.

For example:

{{ value|urlencode }}

If value is "http://www.example.org/foo?a=b&c=d", the output will be "http%3A//www.example.org/foo%3Fa%3Db%26c%3Dd".

An optional argument containing the characters which should not be escaped can be provided.

If not provided, the ‘/’ character is assumed safe. An empty string can be provided when all characters should be escaped. For example:

{{ value|urlencode:"" }}

If value is "http://www.example.org/", the output will be "http%3A%2F%2Fwww.example.org%2F".


8.3 Custom filters

Use the def-filter macro. Its general form is:

(def-filter :myfilter-name (value arg)
   (body))

It always takes the variable’s value as argument, and it can have one required or optional argument. For example, this is how those built-in filters are defined:

(def-filter :capfirst (val)
  (string-capitalize (princ-to-string val)))

This is all there is to it. Once written, you can use it in your templates. You can define a filter wherever you want and there is no need to register it or to import it in your templates.

Here’s a filter with a required argument:

(def-filter :add (it n)
  (+ it (parse-integer n)))

and with an optional one:

(def-filter :datetime (it &optional format)
  (let ((timestamp …))))

When you need to pass a second argument, make your filter return a lambda function and chain it with the with filter:

(def-filter :replace (it regex)
   (lambda (replace)
     (ppcre:regex-replace-all regex it replace)))

(def-filter :with (it replace)
   (funcall it replace))

Now we can write:

{{ value | replace:foo | with:bar }}

Errors are handled by the macro, but you can handle them and return a template-error condition:

(def-filter :handle-error-filter (it)
   (handler-case
         (do-something)
     (condition (e)
       (template-error "There was an error executing this filter: ~A" e))))