Skip to content

Twig

Functions

ems_html

Will return a instance of EmsHtml which is an extension of Twig\Markup. You can easyly replace text, remove html tags, printUrls.

Example

This example is usefull for generating pdf's.

  • This wil replace 'example' by 'EXAMPLE' and 'searchX' by 'replaceX'
  • Remove all a tags if the attribute text contains 'mywebsite.com' and will keep the content
  • Print urls will transform the a tags based on the format (default: ':content (:href)')
twig
{% set description = ems_html(page.description) %}
{% do description
    .replace({ 'example': 'EXAMPLE', 'searchX': 'replaceX' })
    .removeTag('a', ".*?mywebsite.com.*?", true)
    .printUrls(':content (<i><u>:href</u></i>)')
%}
{{ description|emsch_routing_config(emschRoutingConfig) }}

Search all choices of a nested field, and this function will runtime cache the result.

Arguments

  • alias: name of the elasticsearch alias
  • contentTypeNames: string or array of contentType names
  • nestedFieldName: namem of the nestedField
  • search: key/value array, key is nested property name, value is search value

Example

The following example will build 3 variables by using the ems_nested_search, the choices will only build once and cached.

twig
{% set example1 = ems_nested_search('my_alias', 'structure', 'documents', {'id': 'd2214354-a946-4e60-8e1a-921a643df3ad'}) %}
{% set example2 = ems_nested_search('my_alias', 'structure', 'documents', {'id': '9d501b0f-13c1-42e1-a4ae-242650dc6dbd'}) %}
{% set example3 = ems_nested_search('my_alias', 'structure', 'documents', {'id': '0186c0ac-4d8f-4755-a8f0-afa9fb86d599'}) %}

ems_image_info

Retrieve information (size, resolution, mime type and extension) about an image, based on its hash. If the hash can not be recognized as an image or does not exist, null is returned.

Arguments

  • hash: hash(sha1) of the image

Where '4ef5796bb14ce4b711737dc44aa20bff82193cf5' is the hash of a jpg

twig
{{ ems_image_info('4ef5796bb14ce4b711737dc44aa20bff82193cf5') }}

// will return

{
    'width': 128,
    'height': 245,
    'mimeType': 'image/jpg',
    'extension': jpg,
    'heightResolution': 96,
    'widthResolution': 96
}

ems_uuid

Generate a version 4 (random) UUID. More info.

twig
{{ ems_uuid() }}

ems_store_read

Retrieve, or initialize, an associative array (a.k.a. store data) for a given key from the first Store Data Services where the key is available. See the Stora Data documentation for more details.

twig
{% set data = ems_store_read('forum') %}
<form method="post" action="{{ path('emsch_update_store') }}">
    <textarea name="data" cols="10">{{ data.get('[data]') }}</textarea>
    <input name="submit" type="submit" value="Submit">
</form>

ems_store_save

Update a store data in all store data services. This function must be called in a non-safe request (i.e. POST or PUT). See the Stora Data documentation for more details.

yaml
emsch_update_store:
    config:
        path: '/post-data'
        controller: 'emsch.controller.router::redirect'
        method: [POST]
    template_static: template/redirects/post-data.json.twig
twig
{%- block request %}
{% apply spaceless %}
  {% set data = ems_store_read('forum') %}
  {% do data.set('[data]', app.request.get('data')) %}
  {% do ems_store_save(data) %}

  {{ {
    url: path('home'),
  }|json_encode|raw }}
{% endapply %}
{% endblock request -%}

ems_store_delete

Delete a store data in all store data services. This function must be called in a non-safe request (i.e. POST or PUT). See the Stora Data documentation for more details.

yaml
emsch_delete_store:
    config:
        path: '/delete-post-data'
        controller: 'emsch.controller.router::redirect'
        method: [POST]
    template_static: template/redirects/delete-post-data.json.twig
twig
{%- block request %}
{% apply spaceless %}
  {% do ems_store_delete('forum') %}

  {{ {
    url: path('home'),
  }|json_encode|raw }}
{% endapply %}
{% endblock request -%}

ems_flash

Add a flash to the symfony request flash bag.

twig
{% do ems_flash('error', 'error.default'|trans) %}

You can use the following template for displaying the flashes (bootstrap5).

twig
{%- set alertTypes = {
    'success': 'alert-success',
    'error': 'alert-danger',
    'warning': 'alert-warning',
    'info': 'alert-info'
} -%}

{%- for type, class in alertTypes -%}
    {%- for message in app.session.flashBag.get(type) -%}
        <div class="alert {{ class }} alert-dismissible fade show" role="alert">
            {{ message }}
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
    {%- endfor -%}
{%- endfor -%}

ems_file_reader_data

Use the FileReader to get CSV or MS Excel fil content.

twig
<pre>{{ ems_file_reader_data('57bcba09d6f5e06852b83b2b2ba545529f862a87', {'all_sheets': true})|json_encode(constant('JSON_PRETTY_PRINT')) }}</pre>

Options:

  • delimiter (string): For CSV file
  • encoding (string): file's charset
  • all_sheets (boolean): Extract only the active sheet (false, default) or all sheets (true)

ems_file_reader_cells

Returns a cells iterator

twig
<pre>{% set cellsIterator = ems_file_reader_cells('57bcba09d6f5e06852b83b2b2ba545529f862a87', {'exclude_rows': [0]}) }}</pre>

Options:

  • mime_type (string): File mimetype
  • delimiter (string): CSV delimiter
  • encoding (string): file's charset
  • exclude_rows (int[]): skip those rows
  • limit (int): limit to the first rows

ems_check_ip

Checks if an IPv4 or IPv6 address is contained in the list of given IPs or subnets. In order to avoid HTTP cache issues, this function must be called in a non-safe request (i.e. POST or PUT).

twig
{% set clientIp = app.request.headers.get('X-FORWARDED-FOR')|default('192.168.0.5') %}
{% set ranges =  [
    '192.168.0.0/24',
    '10.0.0.0/8',
    '203.0.113.5',
    '172.16.0.0/255.240.0.0',
    '2001:db8::/32',
    'fd00::/8',
    '2a02:26f0:10::5',
] %}

{% if ems_check_ip(clientIp, ranges) %}
 {# display sensitive contents here #}
{% endif %}

Twig filters

ems_anti_spam

For obfuscation of pii on your website when the user agent is a robot.

Implementation details are based on http://www.wbwip.com/wbw/emailencoder.html using ems_html_encode. The following data can be obfuscated (even inside a wysiwyg field):

  • emailadress no_reply@example.com
twig
{{- 'no_reply@example.com'|ems_anti_spam -}}
  • phone number in <a href="tel:____">
twig
{{- '<a href="tel:02/123.50.00">repeated here, the number will not be encoded</a>'|ems_anti_spam -}}
  • custom selection of pii using a span with class "pii"
twig
{{- '<span class="pii">02/123.50.00</span>'|ems_anti_spam -}}

See unit test for more examples.

Note: Phone numbers are only obfuscated if they are found inside "tel:" notation. When a phone is used outside an anchor, the custom selection of pii method should be used.

Note: When using custom selection of pii, make sure that no HTML tags are present inside the pii span.

Note: the custom selection pii span is only present in the backend. The obfuscation method removes the span tag from the code that is sent to the browser.

ems_html_encode

You can transform any text to its equivalent in html character encoding.

twig
{{- 'text and téxt'|ems_html_encode -}}

See unit test for more examples.

ems_markdown

Filter converting a Markdown text into an HTML text following the GitHub standards.

twig
{{ source.body|ems_markdown }}

ems_stringify

Filter converting any scalar value, array or object into a string.

twig
{{ someObject|ems_stringify }}
{{ someArray|ems_stringify }}

ems_asset_average_color

Filter returning the average color, in CSS rgb format, of a passed hash.

I.e.

twig
{{ 'ed266b89065e74483248da7ff71cb80e3cca40a5'|ems_asset_average_color}}

Will return #666666. It might be useful in order to define a background color:

twig
{{ ems_asset_path({
    filename: 'avatar.jpg',
    sha1: avatarHash,
    mimetype: 'image/jpeg',
}, {
    _config_type: 'image',
    _resize: 'fill',
    _background: avatarHash|ems_asset_average_color,
    _width: 400,
    _height: 600,
    _quality: 80,
    _get_file_path: localPath,
}) }}
twig
style="background-color: {{ avatarHash|ems_asset_average_color }}"

ems_replace_regex

Apply php preg_replace function on a text string. All possible exceptions are catched and logged as warning.

Example replace all ems links by a span tag.

twig
{% set text %}
    <h1>Example</h1>
    <p><a href="ems://object:page:dabc33113a53866fe1a1443b42a4c16d1f4bc138">Homepage</a></p>
    <p><a href="ems://object:page:7cc6310cc57818bb571e706ede0a4c10623b430c">News</a></p>
    <p>the end</p>
{% endset %}
{{ text|ems_replace_regex('/<a.*?href="ems:\\/\\/\\S+".*?>(.*?)<\\/a>', '<span>$1</span>')|raw }}

ems_html_decode

Convert HTML entities to their corresponding characters

The following example will generate a è :

twig
{{ '&grave;'|ems_html_decode|json_encode|raw }}

Other parameters:

ems_hash

Generate a hash value from the message. See the PHP hash function.

twig
{{ 'foobar'|ems_hash }}
{{ 'foobar'|ems_hash('sha1') }} {# outputs 8843d7f92416211de9ebb963ff4ce28125932878 #}

Other parameters:

ems_format_bytes

Useful to generate a human readable file size from an interger.

twig
{{ 21666|ems_format_bytes }} {# displays: 21.16 KB #}

A second 'precision' parameter can be defined:

twig
{{ 21666|ems_format_bytes(1) }} {# displays: 21.2 KB #}

ems_ascii_folding

Convert UTF-8 characters in string by their equivalent in the "old" ascii table:

twig
{{ 'Chemin d''accès: î$]&²'|ems_ascii_folding }} {# displays: Chemin d acces: i$]&² #}

It's useful if you want to sort an array regardless accented characters:

twig
{% set sortedArray = notSortedArray|sort((a, b) => a|ems_ascii_folding <=> b|ems_ascii_folding) %}

ems_template_exists

Test if a template exists or not. This function works with all kind of templates:

twig
{% if not ems_template_exists("@EMSCH/template/page/#{name}.html.twig") %}
  {% do emsch_http_error(404, 'Page not found') %}
{% endif %}

ems_analyze

Analyze an input string using the elasticsearch Analyze API:

twig
<p>{{ ems_analyze('― — – ‒ ‹ › ′ ‵ ‘ ’ ‚ ‛ ″ ‴ ‶ ‷ “ ” „ ‟ «  » ü Ü ß ẞ ä ö Ä Ö', {
  'filter': ['asciifolding'],
  'tokenizer': 'keyword'
}) }}</p>
{# ― - - - ' ' ' ' ' ' ' ' " ‴ " ‷ " " " ‟ " " u U ss SS a o A O #}

Arguments:

  • text: the text to analyze (string)
  • parameters: the Analyze API parameters (check the elasticsearch Analyze API documentation) (array)
  • index: an optional index name (string)

ems_json_decode

Call the PHP \json_decode method with those default values: public function jsonDecode(string $json, bool $assoc = true, int $depth = 512, int $options = 0)

twig
{% set config = 'con

ems_array_key

Use the value of the parameter identified by the given name as array index

twig
{% set paths = rawData.paths|default([])|filter(p => p.locale == locale)|ems_array_key('uid') %}

ems_ouuid

Extract a OUUID from an ElasticMS link

twig
    {%  set categories = emsch_search('category', {
        "size": 1000,
        "query": { "terms": { "_id": query.aggregations.categories.buckets|map(p => p.key|ems_ouuid) }},
        "sort": [
            {("title_#{locale}.alpha_order"): {"order": "asc"}}
        ],
        "_source": ["#{app.request.locale}.title"]
    }).hits.hits|default([])|ems_array_key('_id')|map(p => attribute(p._source, app.request.locale).title) %}

ems_md5

Calculate the md5 hash of a string

twig
{{ app.user.email|lower|md5 }}

ems_luma

Calculate the luminance of a color(string)

twig
{% set luminance = '#FF56DD'|ems_luma %}

ems_contrast_ratio

Calculate the contrast ratio between 2 colors (string)

twig
{% if '#FF56DD'|ems_contrast_ratio('black') > '#FF56DD'|ems_contrast_ratio('white') %}#000000{% else %}#ffffff{% endif %}

ems_color

Convert a color (string) into a EMS\Helpers\Standard\Color

twig
{% set color = '#FF56DD'|ems_color %}

ems_slug

Convert a string into an url friendly string

twig
{{ 'How do you do ?'|ems_slug }}
{# how-do-you-do #}

Arguments:

  • locale: default value en
  • separator: default value -
  • lower: default value true
twig
{{ 'Wie fährst du deinen großen LKW ?'|ems_slug('de', '/', false) }}
{# Wie/faehrst/du/deinen/grossen/LKW #}

ems_file_from_archive

Returns a path to a temporary asset extracted from an archive (a zip file). Useful to get local path to an asset (e.g. in case of PDF generation)

twig
    {% set path = ems_file_from_archive('253b903b1fb3ac30975ae9844a0352a65cdcfa3d', 'img/logos/full-logo.svg') %}

This function also accept extra options:

  • extract: Specify that the function can not try to re-extract the archive if the searched path is missing. If disabled the function won't throw an error but null. Default value: true.
  • asTempFile: Returns a EMS\Helpers\File\TempFile object when activated, a path to the temporary file instead. A TempFile is useful to get file's contents with the member function getContents(). Default value false

Example:

twig
{% set tempFile = ems_file_from_archive(hash, "#{path}/index.php", {
    extract: false,
    asTempFile: true,
}) %}

ems_files_in_archive

Returns the list of files present in an archive (EMS archive or Zip file)

twig
{% set files = ems_files_in_archive(hash) %}

This method returns an array like this:

json
{
    "0693f7c7e26507b5d464a99f6a03b9309560abf3.json": {
        "filename": "0693f7c7e26507b5d464accf6a03b9309560abf3.json",
        "hash": "0693f7c7e26507b5d464accf6a03b9309560abf3",
        "type": "application/json",
        "size": 3561
    },
    "crm-export.xlsx": {
        "filename": "crm-export.xlsx",
        "hash": "dd2650a9d4537c5127b9907e83f1e508523d3c18",
        "type": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
        "size": 167352
    },
    "2025-09 Facture Service 1113975398.PDF": {
        "filename": "2025-09 Facture Service 1113975398.PDF",
        "hash": "2ddf565c90bb89b0d860a538828f1dd7bb8b37a5",
        "type": "application/pdf",
        "size": 32640
    }
}

Return the EMSLink object

twig
{% set emsLink = 'page:064efcc7751ee8b0915416a717e2db46d15c77eb'|ems_link %}

ems_valid_mail

Returns true if the input is a valid email

twig
{%- if _source.email|ems_valid_mail -%}{% endif %}

ems_uuid filter

Generate a version 5 UUID from a value. More info.

twig
{{ 'my_unique_id_value'|ems_uuid }}

ems_date

Generate a \DateTimeImmutable object from a value.

twig
{% set date = '31/12/1998 0:00:00'|ems_date('j/m/Y H:i:s') %}

{{ date.format('d-m-Y') }}
{{ date.timezone }}

ems_int

Use php \intval function on input

twig
{% set size = app.request.query.get('size', 0)|ems_int %}

ems_clear_http_caches

Calls the configured reverse proxy services to invalidate part or all of their caches.

It accepts one optional argument:

  • URL or Tags (optional):
    • If it contains an empty array (default value), a full cache purge will be sent.
    • If it is a string starting with /, a cache clear by URL will be sent.
    • Otherwise, a cache clear by tags will be sent.

Example of a cache clear route

The URL is triggered by a clear-cache webhook event, at the endpoint //localhost/_clear_cache.

Depending on the event data:

  • If it contains a tags attribute (string or array of strings), a tag-based cache clear will be sent.
  • If it contains a url attribute (string), a URL-based cache clear will be sent.
  • Otherwise, a full cache purge will be sent.

The emsch_clear_cache route:

yaml
emsch_clear_cache:
    config:
        path: '/_clear_cache'
        method: [POST]
        host: 'localhost'
    template_static: template/admin/clear-cache.html.twig

The template/admin/clear-cache.html.twig twig:

twig
{%- set event = emsch_webhook_event() -%}
{%- if event.name == 'clear-cache' -%}
    {%- do ems_clear_http_caches(event.data.tags|default(event.data.url|default([]))) -%}
    {%- set success = true -%}
{%- endif -%}
{{- { success: success|default(false) }|json_encode|raw -}}