Template Filters in Sandhill
Sandhill makes extensive use of the Jinja2 templating engine as included with Flask. Jinja expression are allowed in template files and many Sandhill config files.
In addition to filters available from Flask, and the ability to define your own filters, Sandhill provides a number of additional filters ready for use, all of which are listed below.
- Flask Built-in Filters
- Creating a Custom Filter
- Sandhill Provided Filters
Creating a Custom Filter
Sandhill has an easy way to integrate your own instance specific filters. Define your custom filters
and save them in instance/filters/
. Sandhill will automatically load all files placed there and
any filtered defined will be available to your instance next time it's restarted.
To create a custom filter is no different than any other filter in Sandhill. Lets create an example filter to ensure an exclamation point is at the end of a string.
First we'll create a file to put it in: instance/filters/myfilters.py
.
Then we can proceed to write our filter:
from sandhill import app
@app.template_filter('exclam')
def exclam(value):
"""Returns the given value as a string, appending an exclamation mark if it
doesn't already end with one."""
value = str(value)
if not value.endswith("!"):
return f"{value}!"
return value
That is all there is to it! The new filter is ready to use in Sandhll, for example you can use:
{{ myval | exclam }}
within your template.
Take a peek at the code for other Sandhill filters if you'd like to see more examples.
General Purpose Filters
datepassed(value)
Checks if the embargoed date is greater than the current date
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
Date in the format yyy-mm-dd that needs to be checked |
required |
Returns:
Type | Description |
---|---|
bool
|
If the given date is less than the current date or not |
Source code in sandhill/filters/filters.py
deepcopy(obj)
Returns the deepcopy of the input object.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
obj |
dict | list | tuple
|
The value to deepcopy. |
required |
Returns:
Type | Description |
---|---|
dict | list | tuple
|
The new copy of the variable. |
Source code in sandhill/filters/filters.py
getdescendant()
Gets key values from the dictionary/list if they exist;
will check recursively through the obj
.
Args:
obj (dict|list): A dict/list to check, possibly containing nested dicts/lists.
list_keys (list|str): List of descendants to follow (or . delimited string)
default (Any): Default value to return if no match found. Default of None.
Returns:
(Any): The last matching value from list_keys, or default value if not match found.
Source code in sandhill/filters/filters.py
getextension(value)
For a given mimetype, return the appropriate file extension.
Use: "image/jpeg" | getextension
= "jpg"
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
A mimetype string |
required |
Returns:
Type | Description |
---|---|
str
|
The matching filetype extension (without leading |
Source code in sandhill/filters/filters.py
head(value)
Returns the head of the list if value is a non-empty list, otherwise returns the orig value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any
|
Possible list from which to remove the first item from. |
required |
Returns:
Type | Description |
---|---|
Any
|
The first item from the list, or the original value if it was not a list. |
Source code in sandhill/filters/filters.py
islist(value)
Check if given value is a list.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
Any
|
The value to type check against. |
required |
Returns:
Type | Description |
---|---|
bool
|
True if value is a list. |
regex_match(value, pattern)
Match the pattern in the value.
Args:
value (str): value that the pattern will compare against
pattern (str): regex pattern that need to be checked
Returns:
The regular expression match, as returned by re.match()
Source code in sandhill/filters/filters.py
regex_sub(value, pattern, substitute)
Substitute a pattern in the value. Args: value (str): value that need the substitution pattern (str): regex pattern that need to be checked substitute (str): regex pattern that need to be substituted Returns: (str): The value with patterns substituted
Source code in sandhill/filters/filters.py
sandbug()
Writes a variable to the Sandhill debug logs.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
Variable to write to the log. |
required |
comment |
str | None
|
Optional comment to add to the log. |
None
|
Returns:
Type | Description |
---|---|
str
|
Always returns an empty string. |
Source code in sandhill/filters/filters.py
setchildkey(parent_dict, parent_key, key, value)
Take dictionary of url components, and update 'key' with 'value'.
Use: {'a': {'x': '1'}} | setchildkey('a', 'y', '2')
= {'a': {'x': '1', 'y': '2'}}
Parameters:
Name | Type | Description | Default |
---|---|---|---|
parent_dict |
dict
|
dictionary to add parent_key to |
required |
parent_key |
str|int|other hashable type
|
parent key to add to the parent_dict |
required |
key |
str|int|other hashable type
|
key to put under parent_key |
required |
value |
any
|
value to give that key |
required |
Returns:
Name | Type | Description |
---|---|---|
parent_dict |
dict
|
The updated parent dictionary |
Source code in sandhill/filters/filters.py
todict(input_list: list)
Convert a list into a dictionary, alternating key and value to create pairs. Args: input_list (list): list with values to be converted into a dictionary Returns: (dict): The new dictionary
Source code in sandhill/filters/filters.py
totuples(input_list: list, tuple_length: int)
Convert a list into tuples of length tuple_length Args: input_list (list): list with values to be converted into tuples tuple_length (int): length of tuples in the list Returns: (list): A list of tuples
Source code in sandhill/filters/filters.py
Encoding/Formatting Filters
commafy(value)
Take a number and format with commas.
Use: 1234567 | commafy
= "1,234,567"
Args:
value (int): Integer value to comma format
Returns:
(str): Comma-fied representation
Source code in sandhill/filters/filters.py
formatbinary(value)
Format bytes size to JEDEC standard binary file size.
Use: 4096 | formatbinary
= "4 KB"
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str | int
|
Number of bytes. |
required |
Returns:
Type | Description |
---|---|
str
|
The formatted bytesize or |
Source code in sandhill/filters/filters.py
formatedate(value, default='Indefinite')
Format the provided embargo end date as a human readable string.
If the date year is 9999, it will show the default value.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
A date string in the format YYYY-MM-DD |
required |
default |
str
|
The default string (Default: "Indefinite") |
'Indefinite'
|
Returns:
Type | Description |
---|---|
str
|
Formatted end date |
Source code in sandhill/filters/filters.py
unescape(value)
Unescape special characters in a string of HTML.
Use: "Moon & ***" | unescape
= "Moon & ***"
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
The string to unescape. |
required |
Returns:
Type | Description |
---|---|
str
|
The unescaped string, or empty string if passed a non-string value. |
Source code in sandhill/filters/filters.py
urlquote(url_str)
Fully escapes all characters (including slash) in the given string with URL percent escapes
Parameters:
Name | Type | Description | Default |
---|---|---|---|
url_str |
str
|
The string to escape |
required |
Returns:
Type | Description |
---|---|
str
|
The fully escaped string |
Source code in sandhill/filters/filters.py
Solr Filters
solr_addfq(query: dict, field: str, value: str)
Adds the field and value to the filter query.
Also removes the start
query param if it exists under the
assumption that a user removing facets would want to return
to the first page.
Args:
query (dict): Solr query (e.g. {"q": "frogs", "fq": "dc.title:example_title"}
)
field (str): field that needs to be checked in the filter query (e.g. dc.creator
)
value (str): value that needs to be checked in the filter query (e.g. example_creator
)
Returns:
(dict): The updated query dict
Source code in sandhill/filters/filters.py
solr_decode(value, escape_wildcards=False)
Filter to decode a value previously encoded for Solr.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
string with Solr escapes to be decoded |
required |
escape_wildcards |
bool
|
If Solr's wildcard indicators (* and ?) should be encoded Default: |
False
|
Returns:
Type | Description |
---|---|
str
|
same string after being decoded |
Source code in sandhill/filters/filters.py
solr_encode(value, escape_wildcards=False, preserve_quotes=False)
Filter to encode a value being passed to Solr
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
string to escape Solr characters |
required |
escape_wildcards |
bool
|
If Solr's wildcard indicators (* and ?) should be encoded Default: |
False
|
preserve_quotes |
bool
|
If set to True, will prevent quotes on outside of the string from being encoded |
False
|
Returns:
Type | Description |
---|---|
str
|
same string but with Solr characters encoded |
Source code in sandhill/filters/filters.py
solr_encodequery(query, escape_wildcards=False)
Parses and encode a Solr query arguments (the part after the colon).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
query |
str
|
Solr query argument to encode. |
required |
escape_wildcards |
bool
|
If Solr's wildcard indicators (* and ?) should be encoded (Default: False) |
False
|
Returns:
Type | Description |
---|---|
str
|
The Solr query with appropriate characters encoded. |
Source code in sandhill/filters/filters.py
solr_getfq(query: dict)
Extract and returns the filter queries from a Solr query.
Example input:
{"q":"frogs", "fq":["dc.title:example_title1", "dc.title:example_title2",
"dc.creator:example_creator1", "dc.creator:example_creator2"]}
Example output:
{"dc.title": ["example_title1", "example_title2"], "dc.creator":
["example_creator1", "example_creator2"]}
Parameters:
Name | Type | Description | Default |
---|---|---|---|
query |
dict
|
A Solr query. |
required |
Returns:
Type | Description |
---|---|
dict
|
The extracted filter queries. |
Source code in sandhill/filters/filters.py
solr_hasfq(query: dict, field: str, value: str)
Check if filter query has the given field and value.
Args:
query (dict): Solr query (e.g. {"q": "frogs", "fq": "dc.title:example_title"}
)
field (str): field that needs to be checked in the filter query (e.g. dc.title
)
value (str): value that needs to be checked in the filter query (e.g. example_title
)
Returns:
(bool): True if the filter query was found.
Source code in sandhill/filters/filters.py
solr_removefq(query: dict, field: str, value: str)
Removes the filter query and returns the revised query.
Also removes the 'start' query param if it exists under the
assumption that a user removing facets would want to return
to the first page.
Args:
query (dict): Solr query (e.g. {"q": "frogs", "fq": "dc.title:example_title"}
)
field (str): field that needs to be removed from the filter query (e.g. dc.title
)
value (str): value that needs to be removed from the filter query (e.g. example_title
)
Returns:
(dict): The updated query dict
Source code in sandhill/filters/filters.py
Specialty Filters
assembleurl(urlcomponents)
Take urlcomponents (derived from Flask Request object) and returns a url.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
urlcomponents |
dict
|
components of the URL to build |
required |
Returns:
Type | Description |
---|---|
str
|
fully combined URL with query arguments |
Source code in sandhill/filters/filters.py
getconfig()
Get the value of the given config name. It will first check in the environment for the variable name, otherwise look in the app.config, otherwise use the default param Args: name (str): Name of the config variable to look for default (str): The defaut value if not found elsewhere Returns: (str): Value of the config variable, default value otherwise
Source code in sandhill/filters/filters.py
sandhill.filters.filters.filtertags(value, *args)
Filter out all HTML tags except for the ones specified and marks the output as safe to render.
Use: <i><b>Hello</b></i> | filtertags('b')
= <b>Hello</b>
Parameters:
Name | Type | Description | Default |
---|---|---|---|
value |
str
|
A string potentially containing HTML tags. |
required |
*args |
str
|
Tag names which are safe and will not be removed. |
()
|
Returns:
Type | Description |
---|---|
str
|
A string with tags removed (excluding those passed as *args). This string is marked |
Source code in sandhill/filters/filters.py
xpath()
Perform an XPath query against an XML source Args: value (str): XML source xpath (str): An XPath query Returns: (list): A list of matching lxml.etree._Elements
Source code in sandhill/filters/filters.py
xpath_by_id()
Perform an XPath query against an XML source and returns matched elements as a dict, where the key is the 'id' attribute of the element and the value is the XML content inside the element as a string. Args: value (str): XML source xpath (str): An XPath query Returns: (dict): A mapping of element 'id' to a string of XML for its children
Source code in sandhill/filters/filters.py
render(context, value, **kwargs)
Renders a given string using Jinja.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context |
Jinja2 context
|
context information and variables to use when evaluating the provided template string. Passed automatically. |
required |
value |
str
|
Jinja2 template string to evaluate given the provided context. |
required |
**kwargs |
dict
|
Additional key-value pairs to add to the render context. |
{}
|
Returns:
Type | Description |
---|---|
str
|
the rendered string |
Source code in sandhill/filters/filters.py
renderliteral(context, value, fallback_to_str=True)
Renders string via Jinja and attempts to perform a literal_eval on the result.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
context |
Jinja2 context
|
context information and variables to use when evaluating the provided template string. |
required |
value |
str
|
Jinja2 template string to evaluate given the provided context |
required |
fallback_to_str |
bool
|
If function should return string value on a failed attempt to literal_eval |
True
|
Returns:
Type | Description |
---|---|
Any | None
|
The literal_eval result, or string if fallback_to_str, or None on render failure |
Raises:
Type | Description |
---|---|
ValueError
|
If content is valid Python, but not a valid datatype |
SyntaxError
|
If content is not valid Python |