Custom Filters And Tags Reference¶
Some of the features we use in pages and reports are ones we added rather than ones that came with the framework we’re using, Django. In other cases we’ve overridden built-in filters to add more functionality.
Filters in Django are typically written as {{ value|filter }}
or {{ value|filter:"arg" }}
. In other words, the filter acts on the value and may or may not take an argument (arg
).
Template tags in Django are typically written as {% tag_name argument1 argument2 ... %}
, where tag_name
is followed by zero or more arguments which may be either optional or required.
Filters¶
Arithmetic Filters¶
Many of the filters in this section were designed to act on Query Report results. Our report results that return a single value are wrapped in a <span>
html tag. For example, a variable containing a report result would actually hold <span class="query-">555</span>
not ‘555.’ While the HTML will render invisibly, built-in filters like add and subtract cannot handle a such a string. Many of our filters will strip away the HTML tag to pull out the report value.
More precisely, the filters extract the first occurrence of an integer or real number.
Note that this will extract numerals from your Query Report’s Short Name if you are using the default query template, which will give you unexpected results!
For other situations when an input must be an integer, see strip_nondigits.
add¶
The filter add
returns the sum of the argument and the value. This overrides Django’s built-in filter which works on integers only. This filter can extract a number from the value and argument and add both floats and integers, rounding results to two decimal places (for adding dollar amounts, for example).
For example:
if a is
<span class="query-">25.50</span>
and b is30
a|add:b
returns 55.25
See also:
at_least¶
The filter at_least
returns the value as long as it’s greater than or equal to the argument.
For example:
if suggested_ask is
100
and value is250
{{ suggested_ask|at_least:250 }}returns 250.
at_most¶
The filter at_most
returns the value as long as it’s less than or equal to the argument.
For example:
if suggested_ask is
3200
and value is2800
{{ suggested_ask|at_most:2800 }}returns 2800.
commify¶
The filter commify
renders a numeric value with commas as the thousands separator. This filter currently only works on integers, but like arithmetic filters above it will extract an integer from a string containing non-numeric characters.
humanize_seconds¶
The filter humanize_seconds
takes a numeric argument (as a string or an integer) of a number of seconds and converts it to a smart string of the form “X days, X hours, X minutes, X seconds” with an appropriate level of detail (no more than two units).
For example:
{{ 5982|humanize_seconds }} and {{ 200000|humanize_seconds }}return ‘1 hour, 39 minutes’ and ‘2 days, 7 hours’, respectively
mod¶
The filter mod
returns the integer remainder of the value divided by the argument. Value and argument are coerced to be integers and this essentially exposes Python’s %
operator to you.
For example:
'35'|mod:'4'
returns 3
multiply¶
The filter multiply
returns the product of the value mutiplied by the argument.
For example:
{{ suggested_ask|multiply:"2" }}returns the user’s suggested ask as defined on your page times two.
divide¶
The filter divide
returns the quotient of the value divided by the argument.
For example:
{{ suggested_ask|divide:"2" }}returns the user’s suggested ask as defined on your page, divided by two.
Hint
You can limit the number of decimal places displayed by a
divide
by using Django’s built-infloatformat
filter:{{ suggested_ask|divide:"2"|floatformat:2 }}
number¶
The filter number
returns the value as a float or integer if possible, or an empty string if the value is not a number. This can be useful when you want to ensure your values are numbers when doing comparisons, since making comparisons on text usually gives nonsense results.
For example:
{% with "23" as days %} days alone: {% if days < 366 %} Less than 366 {% else %} 366 or more {% endif %} days|number: {% if days|number < 366 %} Less than 366 {% else %} 366 or more {% endif %} {% endwith %}
In the first example, the text “23” is being compared to the number 366, which gives the nonsense answer “366 or more”. Using the |number
filter in the second example gives the correct, expected result.
percent_of¶
The filter percent_of
returns the value divided by the argument, formatted as a percentage with one decimal place.
For example:
If value is 72 and argument is 499
{{ value|percent_of:argument }}returns ‘14.4%’
See also:
percent_of2¶
The filter percent_of2
functions like percent_of but returns the percentage formatted to two decimal places.
See also:
subtract¶
The filter subtract
returns the difference of the value and the argument. Like add, this overrides Django’s filter.
See also:
Text Related Filters¶
akid¶
The filter akid
takes a string value and a user object as its argument (or anything with either an attribute or method token
) and modifies all client links in the string by appending ?akid=[token]
or &akid=[token]
if the url has a querystring. Client links are those where the top-level domain is actionkit.com or one of your hostnames. Links appearing inside a src=""
attribute, such as images, are excluded.
See also:
ak_field¶
The filter ak_field
is used to translate a field name in your page templates. For example, we could write:
{% filter ak_field:"email" %}E-mail{% endfilter %}
Django’s built-in filter
template tag ensures that ak_field
applies to the entire text contained in the tag. The text “E-mail” is replced by the translation for field_email
in the selected language for the page being viewed. If no translated text is avilable, “E-mail” will be displayed by default.
ak_text¶
The filter ak_text
works like ak_field
above and can be used to translate any custom phrases you want. First, go to Pages > Related Tools > Languages. Click Edit on the language your page will use for translation and click “Translate another piece of text” at the bottom. Enter a label in the left box and the translation into the right box.
For example, if the label is “hokey_pokey”, include this block in your template:
{% filter ak_text:"hokey_pokey" %} Do the hokey pokey and turn yourself around (that's what it's all about) {% endfilter %}
The text will be replaced by your translation, with the enclosed text being used as a default.
blank_money_field¶
The filter blank_money_field
filters a string containing a field for a donation amount so that the field is blank instead of 0.00.
break_long_words¶
The filter break_long_words
takes a string value and returns the string with a space inserted in any long stretches of non-whitespace characters. The argument specifies how many characters are left untouched before breaking up a word; it is optional and defaults to 30.
For example:
if alpha =
abcdefghijklmnopqrstuvwxyz0123456789
{{ alpha|break_long_words:15 }}yields
u'abcdefghijklmno pqrstuvwxyz0123 456789'
collapse_spaces¶
The filter collapse_spaces
takes a string value and returns the string with runs of whitespace replaced by a single space or a single new line (depending on whether the whitespace was within one line or spanned more than one line, respectively).
commify_list¶
The filter commify_list
takes a list and returns a string with list items separated using the Oxford comma.
For example:
If list is
['we', 'also', 'walk', 'dogs']
,{{ list|commify_list }}returns the string
'we, also, walk, and dogs'
If there are only two items in the list, the items are separated with the word “and” with no comma.
concatenate¶
The filter concatenate
takes a string value and a string argument and returns a longer string with the two joined together.
count_of_characters¶
The filter count_of_characters
takes a string value and a string argument and returns a count of the number of times the argument appears within the string.
For example, {{ user.email|count_of_characters:"@" }}
will return the number of @ signs in the user’s email address.
country_requires_privacy¶
The filter country_requires_privacy
takes a string value and returns whether the country is listed in your config as requiring a privacy record.
For example, {{ user.country|country_requires_privacy }}
will returns True for any countries configured to require a privacy record.
endswith¶
The filter endswith
returns True if value ends with arg. This filter exposes Python’s <string>.endswith(<string>)
method.
See also:
escapeall¶
The filter escapeall
takes a string value and escapes both accented characters and HTML-unsafe ones.
force_ssl¶
The filter force_ssl
takes a string value and replaces all http:// links with https://. This could break links if those sites do not support https://, so take care when using this.
format_phone¶
The filter format_phone
takes a ten-digit string value and formats it like a US phone number.
For example, {{ target.phone|format_phone }}
will format the target’s phone number like (333) 444-5555.
get¶
Similar to .get()
in Python, which gets a value from a dictionary if present and returns nothing if not present.
For example, {{ user.custom_fields|get:"employer" }}
will return a user’s employer if they have that information saved in the “employer” custom user field, and will be blank otherwise.
has_8bit¶
This one is confusingly named, for legacy reasons. The filter has_8bit
returns True
or False
depending on whether a string contains characters outside the range \\x00
to \\xff
. In other words, it will be True
for strings that contain multi-byte Unicode characters.
has_rtl¶
The filter has_rtl
returns True
or False
depending on whether a string contains right-to-left characters in it, e.g. Hebrew and Arabic characters.
is_defined¶
The filter is_defined
returns True
if the value is not None
.
is_nonblank¶
The filter is_nonblank
returns True
if the string does not appear blank when rendered - that is, it consists of more than just whitespace and invisible HTML.
For example the strings with spaces and \t
, and
, and <p></p><div class="lol"> </div>
would all return False
.
iso_currency_symbol¶
The filter iso_currency_symbol
returns the currency symbol associated with an ISO currency abbreviation.
For example, {{ "EUR"|iso_currency_symbol }}
will return €.
json¶
The filter json
returns the value encoded as a JSON data structure without any HTML escaping.
See also:
link_text¶
The filter link_text
checks a value to see if it begins with a URL or a URL path, and if so, returns an HTML link to that URL wrapped around the remainder of the string (or the URL itself).
For example, the below table shows conversions for the expression {{ value|link_text }}
:
value
{{ value|link_text }}
Plain text
Plain text
/dash/home AK Home Tab
<a href=”/dash/home”>AK Home Tab</a>
http://www.actionkit.com ActionKit
<a href=”http://www.actionkit.com”>ActionKit</a>
<a href=”http://www.actionkit.com”>http://www.actionkit.com</a>
Optionally, you can provide link_text with a prefix to look for, in which case links will only be converted if the string begins with that prefix.
For example, the below table shows conversions if you require a prefix of “+” with {{ value|link_text:"+" }}
:
value
{{ value|link_text:”+” }}
Plain text
Plain text
/dash/home AK Home Tab
/dash/home AK Home Tab
http://www.actionkit.com ActionKit
http://www.actionkit.com ActionKit
+/dash/home AK Home Tab
<a href=”/dash/home”>AK Home Tab</a>
+http://www.actionkit.com ActionKit
<a href=”http://www.actionkit.com”>ActionKit</a>
+http://www.actionkit.com
<a href=”http://www.actionkit.com”>http://www.actionkit.com</a>
login_string¶
The filter login_string
is used in mailings to supply the login hash for an ActionKit user to access event pages, recurring donation management pages and any other pages that require login. This goes in the links query string as ?i=[login_string]
. It expects to be passed a dict with a key id
that contains the user_id.
You can also append &l=1
to the URL when using the login_string
filter if you want to allow the user to bypass the step of creating a password.
For example, you might use this code for a link to an event host tools page:
http://docs.actionkit.com/event/{{ page_name }}/tools/?i={{ user|login_string }}&l=1
Here’s an example of how to do that for a recurring donation update page:
https://docs.actionkit.com/login/?next=/pledge/update/{{ page_name }}/&i={{ user|login_string }}&l=1
Since these URLs let anyone log in as the user, you could include a warning, like “Please don’t forward this email: the link above is personalized, and can be used to manage your event or change your account password.”
By default, login_string tokens are good for 30 days, but you can also specify a TTL, in seconds, as an argument. For example, to make a login string token only valid for 600 seconds, you could write:
https://docs.actionkit.com/login/?next=/pledge/update/{{ page_name }}/&i={{ user|login_string:600 }}&l=1
An invalid TTL or a TTL longer than 30 days will by set to 30 days.
See also:
matches¶
The filter matches
returns True
if value contains the regular expression in arg case insensitively. This filter uses Python’s re module. Further information on regular expression syntax can be found in the documentation.
See also:
no_blank_paragraphs¶
The filter no_blank_paragraphs
takes a string and removes HTML paragraphs that would render as blank (whitespace or invisible HTML).
For example:
if text is
<p class='content'> </p>
,{{ text|no_blank_paragraphs }}returns an empty string
nospam¶
The filter nospam
filters a string value by returning a blank string if the value contains HTML, links, or profanity. This can be used to remove spammy comments or other user input.
pretty_json¶
The filter pretty_json
returns the value rendered as a pretty-fied JSON structure: with indentations, sort keys in dictionaries and HTML escaping.
See also:
readable_identifier¶
The filter readable_identifier
take a string value; it replaces each underscore with a space, capitalizes the first character and puts the rest in lowercase.
redirect_links¶
The filter redirect_links
takes a string value and rewrites links as redirect urls. Links appearing inside a src=""
attribute and those with no_redirect=1
or no_akid=1
in the query string are excluded.
See also:
referring_akid¶
The filter referring_akid
takes a string value and a user object as its argument (or anything with an attribute or method of token
) and modifies all client links in the string by appending ?referring_akid=[token]
or &referring_akid=[token]
if the url has a querystring. Client links are those where the top-level domain is actionkit.com or one of your hostnames. Links appearing inside a src=""
attribute, such as images, are excluded.
See also:
remove_blank_lines¶
The filter remove_blank_lines
removes newlines from a string if there’s no non-space character on that line.
replacechar¶
The filter replacechar
takes a string value that it acts on and a two character string for an argument. The argument consists of the character to be replaced followed by the character it is replaced with. The replacement is done for every occurrence within the value.
For example:
{{ "1.2 km"|replacechar:".," }}returns 1,2 km. This filter is useful for display distance for countries that use the comma in the standard display.
single_line¶
The filter single_line
takes a string value and returns the string with newlines (and adjacent whitespace) replaced by a single space. This is useful for text-only versions of transactional mail, for instance.
spaces_to_underscores¶
The filter spaces_to_underscores
takes a string value; it replaces each space with an underscore and converts the string to lowercase.
star_required¶
The filter star_required
takes a string value containing the HTML for a field and searches for class="required"
. If found, it adds a * to show that the field is required.
startswith¶
The filter startswith
returns True if the string value begins with arg (as a substring). This filter exposes Python’s <string>.startswith(<string>)
method.
strip¶
The filter strip
returns the string value with leading and trailing whitespace removed. This exposes Python’s <string>.strip()
method.
strip_nondigits¶
The filter strip_nondigits
takes a string value and returns only the 0-9 digits contained within it. This is useful for stripping away any non-numeric formatting so that the resulting numeric string can be passed to an arithmetic tag. If you are writing a Dashboard Report that combines the integer results of several Query Reports, use this filter to remove the HTML formatting from the Query Report result like <span class="query-">555</span>
so that it can be used in intermediate computations.
suffixed¶
The filter suffixed
formats numbers like “105k” or “1.2M”, rounding to the nearest .1 or 1 for shorter output.
For example, {{ "1000000"|suffixed }}
returns 1M.
tag_links¶
The filter tag_links
takes a string value and an argument consisting of a tag. Client links (with the top-level domain of actionkit.com or one of your registered domains) in the string have ?[tag]
appended, or &[tag]
if a query string already exists. Links appearing inside an src=""
attribute, such as images, are excluded.
For example:
if text is
"Click to sign an important petition: <a href='http://docs.actionkit.com/sign/robotic_kitties'> http://docs.actionkit.com/sign/robotic_kitties</a>"then
{{ text|tag_links:'dog=yes'|safe }}returns
"Click to sign an important petition: <a href='http://docs.actionkit.com/sign/robotic_kitties?dog=yes'> http://docs.actionkit.com/sign/robotic_kitties?dog=yes</a>"
tag_links
can also be used in the email wrapper to automatically append tracking codes to all links in the mailing. For example, if you wanted to automatically append Google Analytics tracking parameters to the links in your mailings, you could wrap the mailing content body with the tag_links
filter in your email wrapper like so:
{% filter tag_links:'utm_medium=email&utm_source=email' %} {% block content %} {% endblock content %} {% endfilter %}
See also:
tag_links_if_untagged¶
Like tag_links, but does not update a link that already has the argument. Use this when you want a default value for links in a block that can be overridden for particular links. Also skips links with no_akid=1 in them.
timezone_display¶
Converts a local time zone name, as stored in the database, to a value that can be shown to end users.
This uses a dictionary of built-in conversions, which maps time zone names like “US/Eastern” to the phrase “Eastern time”, and maps “Europe/London” to “Western European time”.
To translate time zone names into other languages, add translations to your language definitions using the format “timezone_x”, where x is the lowercase equivalent of a timezone stored in the database, with slash characters replaced with underscores.
For example, in a Spanish translation you might map “timezone_us_eastern” to “hora del este”, and map “timezone_gmt-5” to “hora GMT-5”.
truncateeachword¶
The filter trunchateeachword
takes a string value and a numeric argument. If any word in the string is longer than the specified character length, that word is cut off with the ellipsis “…” appended.
For example:
if text is
reallylongword anotherendlessword
{{ text|truncateeachword:8 }}returns
u'reallylo... anothere...'
truncatehtml¶
The filter truncatehtml
takes a string value and a numeric argument. If the length of the HTML string exceeds the specified character length, the string is cut off with the ellipsis “…” appended. However, care is taken not to cut off the string in the middle of an HTML entity, and after the ellipsis any open HTML tags are closed. HTML escaping is also applied to the output.
For example:
if document is the string
<html><body><p>ActionKit is built by We Also Walk Dogs.</p></body></html>
, then{{ document|truncatehtml:20|safe }}yields
u'<html><body><p>ActionKit is built b...</p></body></html>
truncateletters¶
The filter truncateletters
takes a string value and a numeric argument. If the length of the string exceeds the number of characters in arg, the string gets truncated to that length and “…” is appended. This can be useful for keeping long page titles and mailing subjects to a manageable size.
usd_to¶
The filter usd_to
takes a numeric value and string argument of the currency ISO code you want to convert to.
For example, {{ "100"|usd_to:"EUR" }}
returns 94.02729868888855.
List Related Filters¶
columns¶
The filter columns
acts on a list to break it into sublists (rows
) of n elements (columns
) each. When the list does not divide evenly by n, this method divides the first columns evenly, leaving the remainder in the last column. In more precise mathematical terms, in the cases when n does not divide then len(value)
, it takes the columns to have length int(1 + (len(value)/n))
. The rows have length n or n-1.
For example:
if data is range(0,10):
{{ data|columns: 3 }}returns [[0, 4, 8], [1, 5, 9], [2, 6], [3, 7]]
i.e.:
[[0, 4, 8], [1, 5, 9], [2, 6], [3, 7]]
This filter is used in ActionKit in the Donate template (in the Original templateset and any others that haven’t been too heavily rewritten). We use the following code to format the donation amount choices into three columns:
<div class="ak-amount-wrapper">
{% for row in amounts|columns:3 %}
<ul class="ak-unstyled">
{% for amount in row %}
... code to display the radio buttons and the amounts ...
{% endfor %}
</ul>
{% endfor %}
</div>
We’ve set up a page illustrating this use of columns with 13 donation amounts at https://roboticdogs.actionkit.com/donate/columnexample/#1.
See also:
contains¶
The filter contains
returns true if the value contains the arg.
For example:
if zips is [‘10001’, ‘10003’, ‘10011’]
{{ zips|contains:'10001' }}would be True.
See also:
is_in¶
The filter is_in
is the reverse of contains; it returns true if the arg contains the value.
For example:
{{ '10001'|is_in:zips }}returns True.
See also:
islice¶
The filter islice
returns a slice of the list (or generator) object. This has the same syntax as Python’s list slicing. For example,
If list is [‘we’, ‘also’, ‘walk’, ‘dogs’],
{{ list|islice:"1:3" }}returns [‘also’, ‘walk’].
This filter is similar to Django’s built-in filter slice
but uses Python’s itertools.islice()
.
force_list¶
The filter force_list
treats any value as a list. For example, if you have multiple values entered for a custom field, this tag forces Django to return the value(s) as a list.
If value is a string
'wealsowalkdogs'
,{{ value|force_list }}returns
['wealsowalkdogs']
If value is
['we', 'also', 'walk', 'dogs']
, it returns the list unchanged.
join¶
The filter joins
takes a list for its value and a delimiter as its argument and returns a string of lists elements joined by the delimiter. This mirrors the functionality of Python’s delimiter.join(<list>
) method. The argument is mandatory.
For example:
If list is [‘we’, ‘also’, ‘walk’, ‘dogs’],
{{ list|join:'' }}returns the string
u'wealsowalkdogs'
limit¶
The filter limit
returns the first n items (specified by the arg) of a list (supplied as the value).
nth¶
The filter nth
returns n-th item (specified by the arg, counting from 0) of a list (supplied as the value). While Django already supports list-indexing in templates, e.g. {{ states.4 }}, our filter works in daisy chains of several filters.
For example:
if states is [‘AL’, ‘CA’, ‘CA’, ‘OR’],
{{ states|unique|nth:2 }}will return
OR
but
{{ states|unique.2 }}
does not parse.
rows¶
The filter rows
acts on a list to break it into n “rows” (sublists). When the list does not divide evenly by n, this method divides the first rows evenly, leaving the remainder in the last row. In more precise mathematical terms, in this method when n does not divide the len(value)
, it takes the rows to have length int(1 + (len(value)/n))
. This can lead to some rows being empty in cases where n is almost as big as len(value).
Note the the order of the elements in value is preserved.
For example:
if data is range(0,10)
{{ data|rows:3 }}returns [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9]]
and
{{ data|rows:9 }}returns [[0, 1], [2, 3], [4, 5], [6, 7], [8, 9], [], [], [], []]
See also:
rows_distributed¶
The filter rows_distributed
acts like rows, but breaks up the value into n rows in an intuitive manner. A list of length 10 is broken into 4 rows as 3, 3, 2, 2 not 3, 3, 3, 1.
For example:
if data is as above
{{ data|rows_distributed:9 }}gives us [[0, 1], [2], [3], [4], [5], [6], [7], [8], [9]]
See also:
shuffle¶
The filter shuffle
takes a list for a value and returns the list with its items shuffled randomly. This filter does not take an argument.
split¶
The filter splits
a string value on a given separator (default is whitespace) and returns a list. This could be useful for constructing loops. The functionality is analogous to Python’s .split()
method for strings.
For example:
If value is the string “We Also Walk Dogs”
{{ value|split:" " }}returns the list
[u'We', u'Also', u'Walk', u'Dogs']
Another example:
If months is the string “January February March April”
{% for month in months|split %} ---something involving {{month}}--- {% endfor %}creates a loop where
{{month}}
takes the values “January”, “February”, etc in turn.
unique¶
The filter unique
takes a sequence type (list, tuple, etc) and filters it to return a generator object with only distinct elements.
We limit this to the first 100 items to avoid problems with overly large inputs.
unique
accepts an optional argument, key, and if present filters the elements for distinct values of getattr(item, key, item)
for each item in value.
For example:
if value is [‘Action’, ‘Action’, ‘Kit’, ‘Action’, ‘Kit’]
value|unique
returns a generator object that yields ‘Action’ and then ‘Kit’.
Data Related Filters¶
actiontaken¶
The filter actiontaken
returns 1 or 0 depending on whether or not the user (the value) has taken an action on the page specified as the arg.
For example,
{{ user|actiontaken:1 }}returns 1 if the user took action on page_id 1.
campaign¶
The filter campaign
takes a campaign name for its value and a column in events.campaign for its arg, and returns the column’s value from the database. Columns include id
, name
, title
, starts_at
, max_event_size
, etc. See the database table reference for a complete listing.
tagged¶
The filter tagged
returns 1 or 0 depending on whether or not the user (the value) has taken an action on any of the pages associated with the tag specified as the arg.
For example,
{{ user|tagged:"dogs" }}returns 1 if the user has taken any action on dog-related pages.
in_group¶
The filter in_group
returns True
if the user is in the specified user group. The filter can take either the group name (in quotes) or the ID of the user group. For example, if there is a user group named “Wu-Tang Clan” with the ID 36 then the following snippets are identical:
{% if user|in_group:"Wu-Tang Clan" %}Wu-Tang is for the children{% endif %} {% if user|in_group:36 %}Wu-Tang is for the children{% endif %}
load_json¶
The filter load_json
loads data from a JSON string such as a custom page field. For example, this template code will output “testval” if your page has a custom field named “settings” with the value ‘{“testkey”: “testval”}’:
{% with page.custom_fields.settings|load_json as settings %} {{ settings.testkey }} {% endwith %}
load_datetime¶
The filter load_datetime
parses a date/time from a string using Python’s datetime.datetime.strptime method, documented at http://docs.python.org/2.7/library/datetime.html#strftime-and-strptime-behavior.
For example, this code would output “Tuesday, January 1st”:
{{ '2013-01-01'|load_datetime:"%Y-%m-%d"|date:"l, F jS" }}
Miscellaneous Filters¶
chart_data¶
The filter chart_data
takes a list of numeric values and returns a comma-separated string for use in the Google charts some of our built-in Dashboard Reports use. If value has more or fewer than 12 elements, items are truncated from the left or zeroes are padded onto the right.
See also:
chart_data_misc¶
The filter chart_data_misc
takes a list of numeric values and returns a comma-separated string for use in the Google charts some of our built-in Dashboard Reports use.
chart_labels¶
The filter chart_labels
takes a list of numeric values and returns a pipe (‘|’) separated string for use in the Google charts some of our built-in Dashboard Reports use.
chart_spacing and chart_scale¶
These filters are used in the Google charts in some of our built-in Dashboard Reports. They act on the chart data in order to determine an appropriate y-axis scale and y-axis spacing for the chart.
country_names¶
The filter country_names
takes a string consisting of a two-letter ISO language code, for example ‘en’ or ‘fr’ or ‘pl.’ It returns a list of tuples, with tuples of the form (<english country name>
, <country name in the given language>
) for each country.
For example:
{{ 'fr'|country_names }}returns a list with elements such as (
u'Poland', u'Pologne'
).
date_add¶
Template filter which adds the given offset to a datetime value.
Supports all the parameters of dateutil.relativedelta.
Assuming
dt = date(2016, 01, 19)
{{ dt|date_add:"months=1 days=3"|date:"Y-m-d" }} => "2016-02-22"
Note that plurals add (or subtract), while singular values replace:
Assuming
dt = date(2016, 01, 19)
{{ dt|date_add:"month=6 day=23"|date:"Y-m-d" }} => "2016-06-23"
This can be used with ActionKit’s right_now template tag (which creates a
now
variable), but not Django’s built-in now template tag.
Using all these together, the first Thursday of the next month:
Assuming
now = date(2016, 01, 19)
{% right_now %} {{ now|date_add:"months=1 day=1 weekday=3"|date:"l, Y-m-d" }} => "Thursday, 2016-02-04"
Note
In a bulk mailing context, `` event.starts_at`` is a string not a date object. To use a date
or date_add
filter on events, use the variable event.obj.starts_at
, e.g. event.obj.starts_at|date_add:"hours=3"
days_past¶
The filter days_past
can be used in your dashboard reports to generate a list of timestamps for the last several days, the number of which is specified by the argument. The value supplied to the filter must be a Python datetime object. You can use this to build a table or Google chart of data by day.
For example:
if now holds datetime.now() and the present time is ‘2013-01-15 20:00:00’,
{{ now|days_past:6 }}returns [‘2012-01-10 00:00:00’, ‘2012-01-11 00:00:00’, ‘2012-01-12 00:00:00’, ‘2013-01-13 00:00:00’, ‘2013-01-14 00:00:00’, ‘2013-01-15 00:00:00’]
See also:
make_urls_absolute¶
This filter takes an HTML string for its value and tries to convert relative URLs into absolute ones. Takes a True/False argument for whether to use SSL.
month_ago¶
The filter month_ago
acts on a MySQL style datetime value and subtracts one month.
For example:
{{ '2012-06-01 15:15:30'|month_ago }}returns ‘2012-05-01 15:15:30’
See also:
month_year¶
The filter month_year
acts on a MySQL style datetime value to return a prettified Month Year string we can use in monthly reports.
For example,
{{ "2010-06-01 01:02:03"|month_year }}returns “June 2012”.
months_past¶
The filter months_past
is used in the built-in progress report dashboards to generate a list of the last several months, the number of which is specified by the argument. The value supplied to the filter must be a Python datetime object. This can be used to build a table with a row of data for each month or to build a table for a Google chart.
For example:
if now holds datetime.now() and the present time is ‘2012-06-01 19:00:00’,
{{ now|months_past:12 }}returns [‘2011-07-01 00:00:00’, ‘2011-08-01 00:00:00’, ‘2011-09-01 00:00:00’, ‘2011-10-01 00:00:00’, ‘2011-11-01 00:00:00’, ‘2011-12-01 00:00:00’, ‘2012-01-01 00:00:00’, ‘2012-02-01 00:00:00’, ‘2012-03-01 00:00:00’, ‘2012-04-01 00:00:00’, ‘2012-05-01 00:00:00’, ‘2012-06-01 00:00:00’]
See also:
months_pastyr¶
The filter months_pastyr
has been deprecated. Please see months_past.
months_until¶
The filter months_until
has a specific use in the built-in progress report dashboards. It acts on a Python datetime object that holds the current time, and returns a list that can be iterated over with an entry for each month in the calendar year up to now.
For example:
if now holds datetime.now() and the present time is ‘2012-06-01 19:00:00’,
{{ now|months_until }}returns [‘2012-01-01 00:00:00’, ‘2012-02-01 00:00:00’, ‘2012-03-01 00:00:00’, ‘2012-04-01 00:00:00’, ‘2012-05-01 00:00:00’, ‘2012-06-01 00:00:00’]
See also:
weeks_past¶
The filter weeks_past
can be used in your dashboard reports to generate a list of timestamps for the last several weeks, the number of which is specified by the argument. The value supplied to the filter must be a Python datetime object. You can use this to build a table or Google chart of data by week.
For example:
if now holds datetime.now() and the present time is ‘2013-01-15 20:00:00’,
{{ now|weeks_past:6 }}returns [‘2012-12-11 00:00:00’, ‘2012-12-18 00:00:00’, ‘2012-12-25 00:00:00’, ‘2013-01-01 00:00:00’, ‘2013-01-08 00:00:00’, ‘2013-01-15 00:00:00’]
See also:
Template Tags¶
Fundamental Template Tags¶
include_tmpl¶
The include_tmpl
tag takes the content passed in a variable and compiles
and runs it as a Django template. For example, {% include_tmpl form.intro %}
treats the campaigner-specified intro content as a Django template. You can
also use it with page custom fields. For security, you should of course
only use include_tmpl
to include a campaigner-controlled template.
As of December 2017, the included template runs with
Django’s auto-escaping
enabled, even if the context where it’s included uses {% autoescape off %}
.
This makes it easier to avoid cross-site scripting issues: you no longer
have to know the context’s autoescape setting to know how your included
template will be interpreted.
If this isn’t the right behavior for a particular situation, you can use
Django’s built-in |safe
filter in the template content you’re including,
or, for rare use cases, pass an additional keyword to include_tmpl
to
force other behaviors:
{% include_tmpl var %} | Default: HTML-escape Django variables included by the template in var. HTML that's part of the template itself is passed through unmodified. |
{% include_tmpl var escaped %} | HTML-escape all content in var, including characters in the template itself. Useful for plain-text content (like tell-a-friend messages) in webpages. |
URL-encode all content in var. Useful for plain-text content in URLs. | |
{% include_tmpl var json %} | JSON-encode all content in var. |
{% include_tmpl var unescaped %} | Do not escape any content of var. You must wrap this tag in an escaping {% filter %}. Only useful in situations where you need to run some other filter before escaping. |
using¶
The tag using
allows you to avoid repeated references to a Python dictionary in a template or dashboard report. This is a block tag with syntax
{% using <dictionary> %} ... {% endusing %}
For example:
if the ‘targets’ variable holds a dictionary of Congressional information, write
{% using targets %} Call {{ title_last }} and tell {{ them }} that {{ they }} should vote no: {{ listing_html|safe }} {% endusing %}instead of:
Call {{ targets.title_last }} and tell {{ targets.them }} that {{ targets.they }} should vote no: {{ targets.listing_html|safe }}
Report Related Tags¶
report¶
The tag report
allows you to include a Query Report result in your Dashboard Report. You may also supply required parameters.
For example,
{% report 'progress_mail_page_clicks' with dm.id as mailing_id don.id as page_id %}
where the short_name
of the query report is in quotes.
Hint
The report result comes wrapped in some HTML, for example u'<span class="query-">555</span>'
The filter strip_nondigits can remove the HTML formatting.
A simpler way to include a report result is, for example, {{ reports.users_new }}
. However, only the template tag report can include assignments for required parameters.
cache_report¶
The tag cache_report
makes the results of a report available for use elsewhere in the dashboard; the dashboard will still refresh as usual. The report
tag is the primary tag for dashboards, and cache_report
should only be used if you need to further manipulate the results of a report.
{% cache_report 'mailing_sent_count' with dm.id as mailing_id %}
{{ progress_mail_gifts|percent_of2:mailing_sent_count }}
pivot_report¶
The tag pivot_report
is very similar to report
. It allows you to include a Query Report result in your Dashboard Report.
You may also supply required parameters.
The special feature of the pivot_report
tag is that it will transform your query report by performing a “pivot” operation.
This will group all the data by the unique values in the first column of your query report, and turning those groups into the
columns of a new report. The unique values in the second column of your query report become the headings of each row of this new report. The remaining columns of your original query report are then combined and placed into the correct intersecting cell.
For example, given the following query report output:
DATE
COLOR
COUNT
Apr 1
Blue
22
Apr 1
Red
7
Apr 1
Green
39
Apr 1
Yellow
1
Apr 2
Blue
5
Apr 2
Red
14
Apr 3
Green
1
Apr 3
Yellow
5
Apr 4
Blue
2
Apr 4
Red
2
Apr 4
Green
576
Apr 4
White
14
Apr 4
White
3
If your template contains:
{% pivot_report "colors_sold_by_day" with "sum" as pivot_mode %}
Then the following pivot table would be created:
COLOR
Apr 1
Apr 2
Apr 3
Apr 4
Blue
22
5
0
2
Green
39
0
1
576
Red
7
14
0
2
White
0
0
0
17
Yellow
1
0
5
0
The pivot_report
can combine the values in the data in four different pivot_mode
methods:
“list” : Multiple values will in newline (
\n
) delimited. This is the default if you do not specify a different mode.“sum” : Combine multiple values in a cell by adding them together (must be number fields)
“average” : Combine multiple values in a cell into an average value (must be number fields)
“count” : Return the number of “true” values (i.e.: Non-blank, non-zero, non-null; e.g.: “1”)
The pivot mode is set via the parameter pivot_mode
. For example:
{% pivot_report "colors_sold_by_day" with "list" as pivot_mode %}
{% pivot_report "colors_sold_by_day" with "sum" as pivot_mode %}
{% pivot_report "colors_sold_by_day" with "average" as pivot_mode %}
{% pivot_report "colors_sold_by_day" with "count" as pivot_mode %}
Other pivot_report
parameters:
“pivot_transpose” : If true, the rows and columns in the pivot table will be reversed:
{% pivot_report "colors_sold_by_day" with "1" as pivot_transpose %}“pivot_heading” : Override the default text which appears in the top-left cell of the pivot table:
{% pivot_report "colors_sold_by_day" with "My Stuff" as pivot_heading %}
DATA ONLY: A special Dashboard Report mode¶
Normally, a Dashboard Report will present a Query Report using the Query Template configured for the latter.
However, sometimes it is desirable to reformat an existing Query Report differently. Doing so in a
Dashboard Report may be accomplished by turning on data_only
mode:
{% report "colors_sold_by_day" with "1" as data_only %}
When invoked this way, instead of the rendered report being included in the page, the underlying data will be made accessible. This allows you to create a different template for your dashboard report without the need to create a new query template.
The query report data will be made available via a context variable with the same name as your report.
The report columns will be available via the key column_names
, and the data rows via rows
.
For example:
{% report "colors_sold_by_day" with "1" as data_only %}
My Report Columns: <br/>
{% for column in colors_sold_by_day.column_names %}
Column: {{ column }} <br/>
{% endfor %}
<h2>My Report Rows</h2>
{% for row in colors_sold_by_day.rows %}
<h3>Row #{{ forloop.counter }}:</h3>
<ul>
{% for data_col in row %}
<li>{{ data_col }}</li>
{% endfor %}
</ul>
{% endfor %}
Note that data_only
mode will work equally well with either report
or pivot_report
tags.
Hint
By using a {% with %}...{% endwith %}
block around your report
or pivot_report
tag, you can set
multiple report parameters at the same time, in an easy-to-read format. For example:
{% with data_mode=1 pivot_mode="average" pivot_heading="My Things" some_query_param="foo" another_report_param=3 %}
{% pivot_report "my_special_report" %}
{% for row in my_special_report.rows %}
......
{% endfor %}
{% endwith %}
Arithmetic Template Tags¶
divide¶
The tag divide
performs floating point division, and takes three arguments: top
, bottom
, and precision
.
For example:
{% divide 72 499 2 %}
returns “0.14”
save_sum¶
The tag save_sum
takes the sum of an arbitrary number of template variables and saves it to a new variable that you specify. The syntax is:
{% save_sum this that as those %}
If only one variable is specified, then save_sum
allows you to copy a variable.
sign_difference¶
The tag sign_difference
compares its two numeric arguments and returns a “-” string if and only if the first argument is less than the second. Otherwise it returns an empty string.
Data Related Tags¶
args¶
The {{ args }}
tag contains a dictionary of query parameters from the URL. For example, if the URL ends in ?akid=.1.23456abc&source=roboticdogs
, args would contain {'source': 'roboticdogs', 'akid': '.1.23456abc'}
.
Using this example, {{ args.source }}
returns roboticdogs
.
client_domain¶
The tag client_domain
returns the domain of your organization’s ActionKit instance. The usage is always
{% client_domain %}
not {{ client_domain }}
.
client_domain_url¶
The tag client_domain_url
returns a URL for the root of your organization’s ActionKit instance. This includes the http:// prefix, but does not include any page path. If your site has requested the “Pages Always Use HTTPS” setting be enabled, this will use an https:// prefix and the client_ssl_domain.
The usage is always
{% client_domain_url %}
not {{ client_domain_url }}
.
client_name¶
The tag client_name
returns the name of your organization. As above, the usage is
{% client_name %}
not {{ client_name }}
.
client_ssl_domain¶
The tag client_ssl_domain
returns the SSL domain of your organization’s ActionKit instance. The usage is always
{% client_ssl_domain %}
not {{ client_ssl_domain }}
.
load_quick_link_info¶
The tag load_quick_link_info
pulls a data structure of links to events by status for a specified campaign. It also includes counts by status.
For example:
{% load_quick_link_info campaign_name %}
{% using quick_link_info %}
<div><a href="{{ all.url }}">{{ all.count }} events</a></div>
<div>Counts by status:</div>
<div style="margin-left: 10px;">
<div>
<a href="{{ open.url }}">{{ open.count }} open</a>
(<a href="{{ open_public.url }}">{{ open_public.count }} public</a>,
<a href="{{ open_private.url }}">{{ open_private.count }} private</a>)
</div>
{% if campaign.require_email_confirmation %}
<div><a href="{{ unconfirmed.url }}">{{ unconfirmed.count }} waiting for host confirmation</a></div>
{% endif %}
{% if campaign.require_staff_approval %}
<div><a href="{{ unapproved.url }}">{{ unapproved.count }} waiting for staff approval</a></div>
{% endif %}
<div><a href="{{ cancelled.url }}">{{ cancelled.count }} cancelled or deleted</a></div>
</div>
{% endusing %}
withevents and the events variable¶
withevents
is a block tag to find events near a user. Since December 2018, most event mailings automatically do an event search based on targeting or other mailing data so you don’t necessarily need a withevents
tag: you can, for example, access the user’s three closest events via {% for event in events|slice:":3" %}
.
You can rely on the automatic search instead of {% withevents %}
when:
You’re sending an attendee recruit and using the “Campaign radius” targeting option, or
You’ve set up merge data with an event_ids column. (That includes mergequeries for host/attendee reminders.)
You can read on for the ways you can use events
in your mailing, and for info on withevents
you might need for customized searches or maintaining existing code.
Here’s typical code to merge in events:
{% requires_value events %}
{% for event in events|slice:":3" %}
Event: {{ event.title }}
{{ event.starts_at_dt|date:"l, F jS, G:i a" }}
{{ event.venue }}
{{ event.city }}, {{ event.state }}
https://docs.actionkit.com/event/{{ event.signup_page.name }}/{{ event.id }}/signup/?no_redirect=1
{% endfor %}
The requires_value
ensures users who don’t have any events won’t receive the mailing, and the |slice:":3"
limits to three events if there are more near the user.
And here’s how code typically looked using withevents
:
{% withevents with user as nearby_user 'campaign_name' as campaign 30 as radius 3 as limit %}
{% requires_value events %}
{% for event in events %}
Event: {{ event.title }}<br />
{{ event.starts_at_dt|date:"l, F jS, G:i a" }}<br />
{{ event.venue }}<br />
{{ event.city }}, {{ event.state }}<br />
<a href="http://docs.actionkit.com/event/{{ page_name }}/{{ event.id }}/signup/?no_redirect=1">RSVP</a>
{% endfor %}
{% endwithevents %}
If you’re using withevents
now, it may be worth testing if it works to simply remove it (and the endwithevents tag), or to remove just the withevents options like campaign
and radius
that the mailer can pull from targeting. Note that if you remove {% withevents %}
you may need to set appropriate landing pages on your mailings to keep old snippets working.
The withevents
line supports other options. The full list including filtering by event date, are in a table at the end of the section.
Whether you’re using the tag or the automatic event search, here are some of the snippets you can use in event mailings:
Location | |
---|---|
Code | Effect |
{{ event.distance }} |
Distance to the event, in miles. |
{{ event.distance_str }} |
Distance to the event as "1 mi" or "1.6 km" for non-US events. |
{{ event.starts_at_dt|date:"l, F jS, G:i a" }} |
Event start time as "Tuesday, May 7th, 1:30 p.m". Customize the format using Django date filter options. |
{{ event.distance_str }} |
Distance to the event as "1 mi" for U.S. events, or "1.6 km" for non-U.S. |
{{ event.city_etc }} |
"City, ST 12345" in the US and "City, Region, Postal, Country" outside. Blank fields are skipped. |
{{ event.city_etc_no_postal }} |
"City, ST" in the US and "City, Region, Country" outside. Blank fields are skipped. |
{{ event.title }}
{{ event.venue }}
{{ event.address1 }}
{{ event.address2 }}
{{ event.city }}
{{ event.state }}
{{ event.zip }}
{{ event.public_description }}
{{ event.directions }}
{{ event.latitude }}
{{ event.longitude }}
|
Raw value of the field stored in the events table. |
Hosts and attendees | |
{{ event.attendee_count }}
{{ event.max_attendees }} |
Current and max number of attendees.max_attendees can be 0 or None if no max.
|
{% for host in event.hosts %}
...
{% endfor %} |
Loop over users (co)hosting event. |
{% for attendee in event.attendees %}
...
{% endfor %} |
Loop over attendees, such as to generate a roster to mail the host. |
Event status | |
Code | Effect |
{{ event.is_open_for_signup }}
{{ event.is_in_past }}
{{ event.is_full }}
{{ event.is_private }}
{{ event.is_inactive }}
{{ event.is_awaiting_confirmation }}
{{ event.is_awaiting_approval }}
{{ event.is_approved }}
{{ event.host_is_confirmed }} |
Status flags; to use one you might write {% if event.is_full %} etc.is_open_for_signup excludes full, past, deleted, or moderator-flagged events,
as well as any needing host confirmation or approval before they can be shown.is_in_past currently considers if the event has started (it doesn't use end times).
|
Legacy snippets | |
Code | Effect |
{{ event.starts_at }}
{{ event.starts_at_full }}
{{ event.starts_at_ts }} |
Other date formats. starts_at has different output when
used in confirmation emails vs. event mailings, and the new snippet using
starts_at_dt|date makes it easier for you to change date format.
|
{{ event.obj.whatever }} |
Access attribute whatever on event object. Usually, you can now
just remove the .obj part.
|
{{ page_name }} |
Within withevents, finds the name of the event page, in the user's language if possible. Otherwise, returns the name of the mailing's landing page or throws an error if there is none. Using {{ event.signup_page.name }} (or
create_page for create pages) works in a confirmation
email context as well.
|
If you’re using withevents
, these are the filtering options available:
Parameter | Effect | Example |
---|---|---|
limit | The number of results to return | {% withevents with 1 as limit %}
|
event_id | Specific event, eg to be used with a merge file or merge query; cannot be used with other filters like limiting by distance or dates | {% withevents with merge.event_id as event_id %}
|
campaigns | Search for events in multiple campaigns | {% withevents with "cpn1 cpn2 cpn3" as campaigns %}
|
state | Limit results to a specific state | {% withevents with user.state as state %}
|
user_state_only | Limit results to the user's state | {% withevents with 1 as user_state_only %}
|
on_date | Limit to events on the given date | {% withevents with '2012-12-31' as on_date %}
|
on_or_after | Limit to events starting on or after the given date, or date and time | {% withevents with '2012-12-30 16:00:00' as on_or_after %}
|
before | Limit to events starting before the given date, or date and time | {% withevents with '2013-01-01' as before %}
|
days_from_today | Limit to events exactly N days away (note: value must be >= 1, a value of 0 will cause this option to be ignored.) | {% withevents with 2 as days_from_today %}
|
min_days_from_today | Limit to events at least N days away | {% withevents with 3 as min_days_from_today %}
|
max_days_from_today | Limit to events up to N days away | {% withevents with 10 as max_days_from_today %}
|
event_fields.*name* | Match only events with a matching value for a custom event field; to match any one of several values, separate them with a comma or semicolon | {% withevents with 'rally;march' as event_fields.activity %}
|
order | Set the sort order of the results: 'starts_at_utc', 'distance' | {% withevents with 'distance,starts_at_utc' as order %}
|
The event date options “on_date”, “on_or_after”, and “before” use the event’s local start date, and accept dates formatted like “2012-12-31” (or in the US date format with slashes). With “on_or_after” and “before”, you can optionally specify both date and time, not only a date. You can use “before” and “on_or_after” together. Usage might look like:
{% withevents with '2012-12-31' as on_date %}
OR
{% withevents with '2012-12-30 16:00:00' as on_or_after '2013-01-01' as before %}
You can also use “days_from_today”, “min_days_from_today”, and “max_days_from_today” to, e.g., look for events happening tomorrow, or 7 to 14 days in the future. These options also use the event’s local time zone to determine its date. The mailer decides what date to use as “today” using the time zone listed on your ActionKit config screen as the “Auto Excludes time zone”. Both these withevents tags limit to events tomorrow:
{% withevents with 1 as days_from_today %}
OR
{% withevents with 1 as min_days_from_today 1 as max_days_from_today %}
You can also optionally specify how matching events are ordered with the order option, using a value of “starts_at_utc”, “distance”, or both, “starts_at_utc,distance”.
Remember, though, that to send reminders or followups to existing hosts or attendees, you may not need date options or withevents
at all: see Reminders to hosts and attendees and Date options in the events guide.
By default, matching events are sorted by distance then starts_at_utc. Distance is calculated to a high level of precision, so starts_at_utc will only act as a tie-breaker for events in the same venue. You can order by any event column:
{% withevents with 1 as limit "starts_at_utc" as order %}
{% withevents with 1 as limit "starts_at_utc,distance" as order %}
Finally, you can specify a campaign and a single event_id. You can’t use event_id with any other filters like those limiting by distance or to open events.
{% withevents with 'cpn' as campaign merge.event_id as event_id %}
In those cases it might be preferable to use an event_id
or event_ids
column in mergefile or mergequery instead of withevents
.
Miscellaneous Template Tags¶
concatenate¶
The concatenate
tag allows you to to assemble several variables and bits of text and store the result in a new variable which is named at the end after as
.
You can optionally pass a separator
to include between each value.
For example, if the value of page.id
is currently 42, the below would output foo 42 bar
:
{% concatenate "foo" page.id "bar" separator=" " as quux %}
{{ quux }}
localtime¶
The tag localtime
formats a particular datetime value, say an updated_at column or {{ now }}
above, according to a particular format string or relative_time
which smartly picks a format from 1:30 am, Jan 31, or Jan 31 2009. For example:
{% localtime object.updated_at "m/j/y, P" %}
log_context¶
{% log_context %}
is a convenience template tag to be used when developing a mailing or page that uses context data. When included in your mailing or page, the current context is written to your browser’s Developer Console as JSON upon rendering. Note that you must be logged into your ActionKit admin, and that for pages, it’s necessary to use the templateset previewer.
Keep in mind {% log_context %}
is most useful when trying to determine what snippets are available to use on a page or mailing, and is not a key-value store of all of the data. Whenever you see a key with the value <type 'instancemethod'>
, that’s a sign that you could use a snippet to generate data from that key.
For example, see this screenshot of a (partial) log output from using {% log_context %}
on a mailing.

But what is available from {{ donations.most_recent_recurring }}
? We can use this snippet in conjunction with .as_dict
to get a representation of that object as if it were a key/value store. For example, using {{ donations.most_recent_recurring.as_dict }}
returns
{'status': u'active', 'card_num': u'4321', 'period': u'months', 'start': datetime.date(2019, 8, 1), 'amount': Decimal('5.45'), 'recurring_id': u'abcdefghi', 'exp_date': u'1220', u'id': 4}
once¶
Use the tag once
to wrap template code that will only be rendered one time.
In the below example, the “cool” text will only show up once, even if the list has multiple matching items:
{% for item in list %}
{% if item.is_cool %}
{% once %}
Here's one cool thing {{ item.name }}
{% endonce %}
{% endif %}
{% endfor %}
record¶
The tag record is
takes a specified value or variable and append it to a specified list. The list is created if necessary, and an optional argument reportresult
will tell the template tag to extract an integer result from an HTML tag. This tag can be used within a for
loop to build a series of report results at different points in time or for different pages.
For example:
{% record reportresult progress_users in series_users %}
appends the current value of {{ progress_users }}
to the list {{ series_users }}
, creating it if necessary.
remember¶
Normally, variables stored by tags such as concatenate
or store
are not available outside of the current template block. This means that a variable stored in a block, or inside an included template, can not be accessed in other blocks or included templates.
The remember
tag allows a variable’s value to be retrieved outside of the scope of the current template block.
For example, the below template will output the last value in the loop:
{% for val in values %}{% remember val as last_value %}{% endfor %}
{{ last_value }}
required_parameter¶
The tag required_parameter
is an information tag used in reports to indicate to ActionKit that a parameter is required from the user. For example, our built-in dashboard event_report
contains:
{% required_parameter "campaign_name" %}
ActionKit sees this and prompts the user to enter a value for campaign_name
. After using the above tag, the variable {campaign_name}
is available in the report (note the single braces).
For more information, see input parameters in the report .
requires_value¶
The tag requires_value
takes one argument, and raises a Template Syntax Error if the value of the argument is not available or resolves to False. This is useful in mailing snippets.
For example,
{% requires_value targets.count %}
ensures that code involving targets will display in that email.
right_now¶
The tag right_now
creates the variable {{ now }}
that contains the Python datetime object datetime.now()
. You would include this once in your template as
{% right_now %}
before using filters like now|months_until
and now|months_past
.
Right_now also adds to context a variable {{ months_for_chart }}
that is necessary to create the x-axis for our month-by-month bar graph charts used in certain dashboards.
select_index¶
The tag select_index
takes a list
, an index
, and a variable name to save list[index]
to.
For example:
{% select_index dogs 3 as dog %}
store¶
The store
tag allows you to to evaluate a block of template code and store the result in a new variable.
For example, if the value of page.id
is currently 42, the below would output foo 42 bar
:
{% store as quux %}foo {{ page.id }} bar{% endstore %}
{{ quux }}
users_near_location¶
{{ users_near_location }}
is available for use in query reports and returns the IDs of users in the specified radius around a zip code or U.S. city. It can be used like:
select first_name, last_name from core_user where core_user.id={ users_near_location }.
The person running the report is prompted for a place and a radius. The place can be entered as a single zip code or a city and state, or a list of either separated by commas or semicolons. The radius is in miles and defaults to 20 miles if no value is entered.
When querying for U.S. users {{ zip_proximity }}
is a better template tag to get at this data. {{ users_near_location }}
is useful for querying users outside the U.S. or if a user profile doesn’t contain a zip code. {{ users_near_location }}
won’t scale to many thousands of users. So if querying around a large city, like New York or San Francisco, using {{ zip_proximity }}
will work better.
We added a sample report with {{ users_near_location }}
called phone_by_zip_radius so you can see how it works.
You can also use this tag plus parameters of place (required) and radius (optional) in this format: {{ users_near_location:place=90210,radius=50 }}
to retrieve the IDs of users within a specified radius of a zip code without prompting the staff user for place and radius. For example:
select first_name, last_name, city, type, phone
from core_user
join core_phone on(core_user.id = core_phone.user_id)
where core_user.id={{ users_near_location:place=60625,radius=20 }}