Linguistic Template Features

This guide covers VIBE's powerful linguistic features, which go beyond simple variable replacement. These tools help you correctly handle plurals, possessives, complex list formatting, and number-to-word conversions. It assumes you are familiar with the basics from the Jinja Essentials guide.

Supported Languages: English (en), Swedish (sv), German (de), French (fr), Spanish (es)

Locale-Specific Aliases: Each language provides native-language aliases for filters and tags, making templates more readable when written in that language. See the Locale-Specific Aliases section at the end of this guide.

Core Concept: The Linguistic Object

Behind the scenes, these filters work by passing a special Linguistic object between them. When you apply the first filter in a chain (like | plural), VIBE converts your string into this object. Subsequent filters then modify the object's properties (like its number or definiteness) before it's finally converted back to a string for printing.

This allows for powerful, context-aware transformations, such as | plural | definite correctly applying the plural definite form.

Basic Linguistic Filters

These filters can be applied to any string variable or literal.

| plural

Converts a word to its plural form based on the current language.

Arguments:

  • "overrides" (optional, first positional): Override irregular forms using "singular->plural" syntax. Multiple overrides can be comma-separated.
  • if_=variable (optional): Prevents pluralization if variable has a value of 1.
{# English #}
You have {{ num_items }} {{ "renewal period" | plural(if_=num_items) }}.
{# num_items=1: "You have 1 renewal period." #}
{# num_items=2: "You have 2 renewal periods." #}

{# Swedish (alias: plural) #}
Det finns {{ antal }} {{ "avtal" | plural(if_=antal) }}.
{# antal=1: "Det finns 1 avtal." #}
{# antal=2: "Det finns 2 avtal." #}

{# German (alias: plural) #}
Es gibt {{ anzahl }} {{ "Vertrag" | plural(if_=anzahl) }}.
{# anzahl=1: "Es gibt 1 Vertrag." #}
{# anzahl=2: "Es gibt 2 Verträge." #}

{# French (alias: pluriel) #}
Il y a {{ nombre }} {{ "contrat" | pluriel(if_=nombre) }}.
{# nombre=1: "Il y a 1 contrat." #}
{# nombre=2: "Il y a 2 contrats." #}

{# Spanish (alias: plural) #}
Hay {{ cantidad }} {{ "contrato" | plural(if_=cantidad) }}.
{# cantidad=1: "Hay 1 contrato." #}
{# cantidad=2: "Hay 2 contratos." #}

Overriding Irregular Plurals

When a word has an irregular plural form not in the built-in lexicon, you can provide an override:

{# Swedish - override for uncommon words #}
{{ "gås" | plural("gås->gäss") }}
{# Output: "gäss" #}

{# Multiple overrides #}
{{ djur | plural("gås->gäss,åsna->åsnor") }}

{# English - override for domain-specific terms #}
{{ "vertex" | plural("vertex->vertices") }}
{# Output: "vertices" (also in built-in lexicon) #}

{# German #}
{{ "Virus" | plural("Virus->Viren") }}
{# Output: "Viren" #}

{# French #}
{{ "festival" | plural("festival->festivals") }}
{# Output: "festivals" (exception to -al -> -aux rule) #}

{# Spanish #}
{{ "curriculum" | plural("curriculum->curricula") }}
{# Output: "curricula" #}

The override takes precedence over both built-in irregular forms and heuristic rules.

| definite

Converts a word or phrase to its definite form. In English, this adds "the". In Swedish, it adds a suffix. In German/French/Spanish, it adds the appropriate article.

Arguments:

  • "overrides" (optional, first positional): Override irregular forms using "word->definite_form" syntax. Primarily useful for Swedish where definiteness is a suffix.
{# English #}
The subject of the agreement is {{ item | definite }}.
{# item="opportunity" -> "the opportunity" #}

{# Swedish (alias: bestamd) #}
Avtalet avser {{ item | bestamd }}.
{# item="verksamhet" -> "verksamheten" #}
{# item="avtal" -> "avtalet" #}

{# Swedish - override for uncommon words #}
{{ "test" | bestamd("test->testet") }}
{# Output: "testet" #}

{# German (alias: bestimmt) #}
Der Gegenstand ist {{ item | bestimmt }}.
{# item="Vertrag" -> "der Vertrag" #}
{# item="Vereinbarung" -> "die Vereinbarung" #}

{# French (alias: defini) #}
L'objet est {{ item | defini }}.
{# item="contrat" -> "le contrat" #}
{# item="partie" -> "la partie" #}
{# item="accord" -> "l'accord" #}

{# Spanish (alias: definido) #}
El objeto es {{ item | definido }}.
{# item="contrato" -> "el contrato" #}
{# item="parte" -> "la parte" #}

Note: Overrides are most useful for Swedish, where definiteness is expressed as a suffix with complex rules. For German, French, and Spanish, the definite article is determined by grammatical gender, which is looked up in the noun lexicon or guessed from word endings.

| possessive

Converts a word or phrase to its possessive/genitive form.

  • possessive(subject="..."): A special argument that can rephrase the entire expression.
{# English #}
This marks {{ "the contract" | possessive(subject="end") }}.
{# Output: "the end of the contract" #}
{{ "Company" | possessive }}
{# Output: "Company's" #}

{# Swedish (alias: genitiv) #}
{{ "Bolaget" | genitiv(subject="åtaganden") }}
{# Output: "Bolagets åtaganden" #}
{{ "Förlängningsperiod" | bestamd | genitiv }}
{# Output: "Förlängningsperiodens" #}

{# German (alias: genitiv) #}
{{ "Vertrag" | genitiv }}
{# Output: "des Vertrags" #}
{{ "Vereinbarung" | genitiv }}
{# Output: "der Vereinbarung" #}

{# French (alias: possessif) #}
{{ "contrat" | possessif }}
{# Output: "du contrat" #}
{{ "accord" | possessif }}
{# Output: "de l'accord" #}

{# Spanish (alias: posesivo) #}
{{ "contrato" | posesivo }}
{# Output: "del contrato" #}
{{ "parte" | posesivo }}
{# Output: "de la parte" #}

| indefinite

Adds an indefinite article to a word. In English, this correctly handles "a" vs "an" based on pronunciation.

{# English #}
This is {{ "agreement" | indefinite }}.
{# Output: "an agreement" #}
This is {{ "contract" | indefinite }}.
{# Output: "a contract" #}
This is {{ "university" | indefinite }}.
{# Output: "a university" (sounds like "yoo") #}
This is {{ "hour" | indefinite }}.
{# Output: "an hour" (silent h) #}

{# Swedish (alias: obestamd) #}
Detta är {{ "avtal" | obestamd }}.
{# Output: "ett avtal" (neuter) #}
Detta är {{ "kund" | obestamd }}.
{# Output: "en kund" (common) #}

{# German (alias: unbestimmt) #}
Das ist {{ "Vertrag" | unbestimmt }}.
{# Output: "ein Vertrag" (masculine) #}
Das ist {{ "Vereinbarung" | unbestimmt }}.
{# Output: "eine Vereinbarung" (feminine) #}
Das ist {{ "Dokument" | unbestimmt }}.
{# Output: "ein Dokument" (neuter) #}

{# French (alias: indefini) #}
C'est {{ "contrat" | indefini }}.
{# Output: "un contrat" (masculine) #}
C'est {{ "partie" | indefini }}.
{# Output: "une partie" (feminine) #}

{# Spanish (alias: indefinido) #}
Es {{ "contrato" | indefinido }}.
{# Output: "un contrato" (masculine) #}
Es {{ "parte" | indefinido }}.
{# Output: "una parte" (feminine) #}

| itemize

Handles phrases with multiple items, like "goods and services". It controls the conjunction word used when the phrase is finally printed.

{# English #}
{{ "goods, support and services" | definite | itemize(conjunction="or") }}
{# Output: "the goods, the support, or the services" #}

{# Swedish (alias: upprakning) #}
{{ "varor, stöd och tjänster" | bestamd | upprakning(konjunktion="eller") }}
{# Output: "varorna, stödet eller tjänsterna" #}

{# German (alias: auflistung) #}
{{ "Waren, Support und Dienstleistungen" | bestimmt | auflistung(konjunktion="oder") }}
{# Output: "die Waren, der Support oder die Dienstleistungen" #}

{# French (alias: enumerer) #}
{{ "biens, support et services" | defini | enumerer(conjonction="ou") }}
{# Output: "les biens, le support ou les services" #}

{# Spanish (alias: enumerar) #}
{{ "bienes, soporte y servicios" | definido | enumerar(conjuncion="o") }}
{# Output: "los bienes, el soporte o los servicios" #}

Number-to-Word Conversion Filters

For legal and formal documents, it's often necessary to write out numbers as words. These filters handle the conversion automatically based on the current locale.

| cardinal

Converts a number into its cardinal word form (e.g., one, two, three).

  • cardinal(cutoff=number): An optional argument. If the input number is greater than the cutoff, the filter will return the number as digits instead of words.
{# English #}
The term is {{ years | cardinal }} years.
{# years=3: "The term is three years." #}
{{ amount | cardinal(cutoff=100) }} dollars
{# amount=95: "ninety-five dollars" #}
{# amount=101: "101 dollars" #}

{# Swedish (alias: kardinal) #}
Avtalet gäller i {{ ar | kardinal }} år.
{# ar=3: "Avtalet gäller i tre år." #}
{# ar=21: "Avtalet gäller i tjugoett år." #}

{# German (alias: kardinal) #}
Der Vertrag gilt für {{ jahre | kardinal }} Jahre.
{# jahre=3: "Der Vertrag gilt für drei Jahre." #}
{# jahre=21: "Der Vertrag gilt für einundzwanzig Jahre." #}

{# French (alias: cardinal) #}
Le contrat dure {{ annees | cardinal }} ans.
{# annees=3: "Le contrat dure trois ans." #}
{# annees=80: "Le contrat dure quatre-vingts ans." #}

{# Spanish (alias: cardinal) #}
El contrato dura {{ anos | cardinal }} años.
{# anos=3: "El contrato dura tres años." #}
{# anos=21: "El contrato dura veintiuno años." #}

| ordinal

Converts a number into its ordinal word form (e.g., first, second, third).

{# English #}
This is the {{ count | ordinal }} amendment.
{# count=1: "the first amendment" #}
{# count=22: "the twenty-second amendment" #}

{# Swedish (alias: ordinal) #}
Detta är det {{ nummer | ordinal }} tillägget.
{# nummer=1: "det första tillägget" #}
{# nummer=3: "det tredje tillägget" #}

{# German (alias: ordinal) #}
Dies ist die {{ nummer | ordinal }} Änderung.
{# nummer=1: "die erste Änderung" #}
{# nummer=3: "die dritte Änderung" #}

{# French (alias: ordinal) #}
C'est le {{ numero | ordinal }} amendement.
{# numero=1: "le premier amendement" #}
{# numero=2: "le deuxième amendement" #}

{# Spanish (alias: ordinal) #}
Esta es la {{ numero | ordinal }} enmienda.
{# numero=1: "la primera enmienda" #}
{# numero=2: "la segunda enmienda" #}

| doublet

Creates a "doublet" format common in legal documents, showing both the word and digit form.

  • doublet(unit="..."): An optional argument to append a unit to the end.
{# English #}
{{ days | doublet }} days
{# days=30: "thirty (30) days" #}
{{ days | doublet(unit="business days") }}
{# days=30: "thirty (30) business days" #}

{# Swedish (alias: dublett) #}
{{ dagar | dublett }} dagar
{# dagar=30: "trettio (30) dagar" #}
{{ dagar | dublett(unit="arbetsdagar") }}
{# dagar=30: "trettio (30) arbetsdagar" #}

{# German (alias: wort_und_zahl) #}
{{ tage | wort_und_zahl }} Tage
{# tage=30: "dreißig (30) Tage" #}
{{ tage | wort_und_zahl(unit="Werktage") }}
{# tage=30: "dreißig (30) Werktage" #}

{# French (alias: doublet) #}
{{ jours | doublet }} jours
{# jours=30: "trente (30) jours" #}
{{ jours | doublet(unit="jours ouvrables") }}
{# jours=30: "trente (30) jours ouvrables" #}

{# Spanish (alias: doblete) #}
{{ dias | doblete }} días
{# dias=30: "treinta (30) días" #}
{{ dias | doblete(unit="días hábiles") }}
{# dias=30: "treinta (30) días hábiles" #}

| roman

Converts a number to Roman numerals. Useful for legal section numbering.

  • roman(case="upper") (default): Uppercase numerals (I, II, III)
  • roman(case="lower"): Lowercase numerals (i, ii, iii)
{# All languages - Roman numerals are universal #}

{# English #}
Article {{ section | roman }}
{# section=4: "Article IV" #}
{# section=1999: "Article MCMXCIX" #}

{# Swedish (alias: romersk) #}
Avsnitt {{ avsnitt | romersk }}
{# avsnitt=4: "Avsnitt IV" #}
{{ avsnitt | romersk(case="lower") }}
{# avsnitt=4: "iv" #}

{# German (alias: romisch) #}
Abschnitt {{ abschnitt | romisch }}
{# abschnitt=4: "Abschnitt IV" #}

{# French (alias: romain) #}
Section {{ section | romain }}
{# section=4: "Section IV" #}

{# Spanish (alias: romano) #}
Sección {{ seccion | romano }}
{# seccion=4: "Sección IV" #}

Note: Values outside 1-3999 are returned unchanged.

| alpha

Converts a number to an alphabetical label (1=A, 2=B, ..., 26=Z). Useful for list item markers.

  • alpha(case="upper") (default): Uppercase letters (A, B, C)
  • alpha(case="lower"): Lowercase letters (a, b, c)
{# All languages - alphabetical labels are universal #}

{# English #}
Exhibit {{ num | alpha }}
{# num=1: "Exhibit A" #}
{# num=26: "Exhibit Z" #}

{# Swedish (alias: alfabetisk) #}
Bilaga {{ num | alfabetisk }}
{# num=1: "Bilaga A" #}
{{ num | alfabetisk(case="lower") }}
{# num=1: "a" #}

{# German (alias: alphabetisch) #}
Anlage {{ num | alphabetisch }}
{# num=1: "Anlage A" #}

{# French (alias: alphabetique) #}
Annexe {{ num | alphabetique }}
{# num=1: "Annexe A" #}

{# Spanish (alias: alfabetico) #}
Anexo {{ num | alfabetico }}
{# num=1: "Anexo A" #}

Note: Values outside 1-26 are returned unchanged (no AA, AB, etc.).

Advanced Conditional Lists: {% enumerate %}

For creating a list of items where each item has its own inclusion condition, use the {% enumerate %} block tag. It automatically handles commas and conjunctions for a grammatically perfect result.

Inside the block, you define items using the {% item if ... %} tag:

Example: Paragraph Style

{# English #}
The limitation does not apply to {%
    enumerate conjunction="or" %}{%
    item if carveout['breach'] %}breach of confidentiality{% enditem %}{%
    item if carveout['infringement'] %}infringement of IPR{% enditem %}{%
    item if carveout['misconduct'] %}reckless conduct{% enditem %}{%
endenumerate %}.
{# All true: "breach of confidentiality, infringement of IPR, or reckless conduct." #}
{# First and last: "breach of confidentiality or reckless conduct." #}
{# First only: "breach of confidentiality." #}

{# Swedish (localized tags) #}
Ansvarsbegränsningen gäller inte {%
    upprakning konjunktion="eller" %}{%
    punkt om undantag['sekretess'] %}brott mot sekretess{% slut_punkt %}{%
    punkt om undantag['immaterialratt'] %}intrång i immateriella rättigheter{% slut_punkt %}{%
    punkt om undantag['grov_oaktsamhet'] %}grov oaktsamhet{% slut_punkt %}{%
slut_upprakning %}.

{# German (localized tags) #}
Die Haftungsbeschränkung gilt nicht für {%
    auflistung konjunktion="oder" %}{%
    punkt wenn ausnahme['vertraulichkeit'] %}Verletzung der Vertraulichkeit{% ende_punkt %}{%
    punkt wenn ausnahme['ip'] %}Verletzung von Schutzrechten{% ende_punkt %}{%
    punkt wenn ausnahme['fahrlassigkeit'] %}grobe Fahrlässigkeit{% ende_punkt %}{%
ende_auflistung %}.

{# French (localized tags) #}
La limitation ne s'applique pas à {%
    enumeration conjonction="ou" %}{%
    element si exception['confidentialite'] %}violation de la confidentialité{% fin_element %}{%
    element si exception['pi'] %}violation de la propriété intellectuelle{% fin_element %}{%
    element si exception['negligence'] %}faute lourde{% fin_element %}{%
fin_enumeration %}.

{# Spanish (localized tags) #}
La limitación no se aplica a {%
    enumeracion conjuncion="o" %}{%
    elemento si excepcion['confidencialidad'] %}incumplimiento de confidencialidad{% fin_elemento %}{%
    elemento si excepcion['pi'] %}infracción de PI{% fin_elemento %}{%
    elemento si excepcion['negligencia'] %}negligencia grave{% fin_elemento %}{%
fin_enumeracion %}.

Example: List Style

You can also generate a formatted <ul> list with correct end-of-line punctuation.

{# English #}
The limitation does not apply to:
{% enumerate style="list", conjunction="or" %}
  {% item if breach %}Breach of confidentiality{% enditem %}
  {% item if infringement %}Infringement of IPR{% enditem %}
{% endenumerate %}

{# Swedish #}
Ansvarsbegränsningen gäller inte:
{% upprakning stil="list", konjunktion="eller" %}
  {% punkt om sekretessbrott %}Brott mot sekretess{% slut_punkt %}
  {% punkt om immaterialrattsintrong %}Intrång i immateriella rättigheter{% slut_punkt %}
{% slut_upprakning %}

{# German #}
Die Haftungsbeschränkung gilt nicht für:
{% auflistung stil="list", konjunktion="oder" %}
  {% punkt wenn vertraulichkeit %}Verletzung der Vertraulichkeit{% ende_punkt %}
  {% punkt wenn schutzrechte %}Verletzung von Schutzrechten{% ende_punkt %}
{% ende_auflistung %}

{# French #}
La limitation ne s'applique pas à:
{% enumeration style="list", conjonction="ou" %}
  {% element si confidentialite %}Violation de la confidentialité{% fin_element %}
  {% element si propriete_intellectuelle %}Violation de la propriété intellectuelle{% fin_element %}
{% fin_enumeration %}

{# Spanish #}
La limitación no se aplica a:
{% enumeracion estilo="list", conjuncion="o" %}
  {% elemento si confidencialidad %}Incumplimiento de confidencialidad{% fin_elemento %}
  {% elemento si propiedad_intelectual %}Infracción de PI{% fin_elemento %}
{% fin_enumeracion %}

Possible Output (if both are true):

The limitation of liability does not apply to: * Breach of confidentiality; or * Infringement of IPR.

enumerate Tag Arguments

  • style (optional):
    • "paragraph" (default): Creates an inline, comma-separated list.
    • "list": Creates a <ul> bullet point list with correct punctuation.
  • conjunction (optional):
    • "and" (default): Uses the localized word for "and".
    • "or": Uses the localized word for "or".
    • Any other string: Uses the provided string verbatim (e.g., "och/eller").
  • transform (optional): Applies a filter to each item before joining.
    • "possessive": Applies the possessive filter to each item.
    • "capitalize": Capitalizes the first letter of each item.

Locale-Specific Aliases

To make templates more readable when written in a specific language, VIBE provides native-language aliases for filters and tags. The English (canonical) names always work, but you can use the aliases when your template locale matches.

Filter Aliases by Language

Filter (English) Swedish (sv) German (de) French (fr) Spanish (es)
plural plural plural pluriel plural
definite bestamd bestimmt defini definido
possessive genitiv genitiv possessif posesivo
indefinite obestamd unbestimmt indefini indefinido
cardinal kardinal kardinal cardinal cardinal
ordinal ordinal ordinal ordinal ordinal
doublet dublett wort_und_zahl doublet doblete
itemize upprakning auflistung enumerer enumerar
roman romersk romisch romain romano
alpha alfabetisk alphabetisch alphabetique alfabetico

Tag Aliases by Language

The enumerate tag and its sub-tags also have localized aliases:

Tag (English) Swedish (sv) German (de) French (fr) Spanish (es)
enumerate upprakning auflistung enumeration enumeracion
endenumerate slut_upprakning ende_auflistung fin_enumeration fin_enumeracion
item punkt punkt element elemento
enditem slut_punkt ende_punkt fin_element fin_elemento

Tag Parameter Aliases

Parameters inside tags can also use localized names:

Parameter (English) Swedish (sv) German (de) French (fr) Spanish (es)
conjunction konjunktion konjunktion conjonction conjuncion
style stil stil style estilo
transform omvandla umwandeln transformer transformar
if om wenn si si

Note: The English names always work regardless of template locale. Aliases are purely for improved readability.

Filter Chaining

Filters can be chained together to apply multiple transformations:

{# English #}
{{ "renewal period" | plural | definite }}
{# Output: "the renewal periods" #}

{# Swedish #}
{{ "Förlängningsperiod" | plural | bestamd | genitiv }}
{# Output: "Förlängningsperiodernas" #}

{# German #}
{{ "Vertrag" | plural | bestimmt }}
{# Output: "die Verträge" #}

{# French #}
{{ "contrat" | pluriel | defini }}
{# Output: "les contrats" #}

{# Spanish #}
{{ "contrato" | plural | definido }}
{# Output: "los contratos" #}