SPIP’s Filters

In the article “SPIP’s Tags: The Syntax” we saw that it is possible to change the behaviour of tags and the way they display text by attaching filters to them:

[ option before (#BALISE|filtre1|filtre2|...|filtre_n) option after]

Filters 1, 2, …n are applied in succession to the #TAG.

Date filters

The following filters are applied to dates ([(#DATE|affdate)] for example).

-  jour or journum display the day (in digits).

-  mois displays the month (in digits).

-  annee displays the year.

-  heures displays the hours of a date (the dates provided by SPIP include the time as well as the day) using the 24 hour clock: "00", "13", "22", etc.

-  minutes displays the minutes of a date.

-  secondes displays the seconds.

-  nom_jour displays the name of the day (Monday, Tuesday...).

-  nom_mois displays the name of the month (January, February...).

-  saison displays the season (spring, summer, autumn, winter).

-  affdate displays the full date as text, for example: “13 August 2005”, in standard British format. (In order to have dates in American or other format see this article on Spip-Contrib.)

This filter can be optionally extended by a PHP date formatting parameter. Example:
[(#DATE|affdate{'Y-m'})] shows the year and the month in digits, separated by a dash.
Spip formats can also be written using this notation. Thus, [(#DATE|saison)] and [(#DATE|affdate{'saison'})] are the same.

-  Some variations of the affdate filter give further possibilities:
affdate_jourcourt displays the name of the month and the number of the day, if the date is in the current year, e.g. “19 April”. If the date is in another year, then the year is also added: “1 November 2004”.
affdate_court displays the name of the month and the number of the day, if the date is in the current year, e.g. “19 April”. If the date is in another year, then only the month and the year is given: “November 2004”.
affdate_mois_annee displays just the month and the year: “April 2005”, “November 2003”.

-  The filter unique returns the value of the filtered tag only if it is the first time that value has occurred. This filter is not limited to dates, but can be put to good use when displaying a list of articles by date. Example:

<BOUCLE_blog(ARTICLES){par date}{inverse}{"<br>"}>
[<hr> <h1>(#DATE|affdate_mois_annee|unique)</h1>]
#TITRE ...
</BOUCLE_blog>

The code snippet above will display the year and month only when the month changes.

A second example:

<BOUCLE_blog2(ARTICLES){par date}{inverse}>
  [<hr><h1>(#DATE|annee|unique)</h1>]
    [<h2>(#DATE|affdate{'Y-m'}|unique|nom_mois)</h2>]
      <a href="#URL_ARTICLE">#TITRE</a><br />
</BOUCLE_blog2>

will show a list like this:
2005      March             A March article             Another article from March      January             A January article  2004      December             Article published in December

Note: The notation affdate{'Y-m'} is used in order to display the names of the months for each year:

  • if we put just: #DATE|nom_mois|unique, the months would only be displayed for the first year (or the first time that month is encountered),
  • and if we put: #DATE|unique|nom_mois, all the dates would be shown. This is because #DATE returns a complete date containing the time as well.

This is why 'Y-m' is used to retain just the year and the month before passing the result to the {unique} filter.

{unique} takes an optional parameter to differentiate between independent uses of the filter. For example:
[(#DATE|affdate_mois_annee|unique{here})] will not have any effect upon
[(#DATE|affdate_mois_annee|unique{there})].

Text filters

See also Text filters.

-  |liens_ouvrants transforms Spip hyperlinks which connect to other sites into links which open in a new window; it gives the equivalent of the HTML target="_blank". N.B. The Spip developers consider that it is, in most cases, impolite to use this feature. Visitors should, in general, be able to decide for themselves whether or not they wish to open a new window, whereas the use of this filter imposes a new window on them. But we bowed to the pressure of very many requests for this feature ;-)

-  |supprimer_numero is used to remove the number preceding a title. This makes it possible, for example, to sort sections or articles {par num titre}, but not to display the numbers (which are thus only used to establish the sort order). The format of the preceding numbers is “xx. Title”, where xx is a number (of any number of digits).

-  |PtoBR transforms paragraph breaks into simple line breaks. This allows you to “compress” the layout, in order to make a table of contents, for example.

-  |taille_en_octets converts a given number of bytes (25678906) into a more readable number: 24.4 Mb.

-  |supprimer_tags removes completely all HTML tags <...>.

-  |textebrut is similar to supprimer_tags, but acts in a more subtle way. In particular, it converts paragraphs <p> ... </p> and line breaks <br> into a simple new line, and also non-breaking spaces (&nbsp;) into simple spaces. This filter can be used, for example, in order to fill a META description using the #DESCRIPTIF tag: [<meta name='description' content='(#DESCRIPTIF|textebrut)'].

-  |texte_backend can be used to convert a text into a useable source for an XML feed. This filter is used in the backend.html template which generates an RSS feed for the site.

-  |couper cuts a text to no more than a specified number of characters. It avoids cutting a word in two, removes formatting elements and adds “(...)” if necessary to show that the text was abridged. The default length is 50 characters, but you can specify a different length by using the following syntax: [(#TEXTE|couper{80})], for example; or override the “(...)” by passing a second parameter: [(#TEXTE|couper{60, '...'})]

-  |match uses a regular expression (cf. preg_match()) in order to extract a fragment of text. If the fragment sought is not found, the filter returns nothing. Example: [(#TITRE|match{^\w+?})] displays the first word of the title. A simple text match can be made: [(#TITRE|match{whatsit})] will display "whatsit" — if the word is found in the title.

-  replace is also based on regular expressions (cf. preg_replace()) which it uses to suppress or to replace all occurences of a fragment of text. If only one parameter is given, the fragment is suppressed.
For example, [(#TEXTE|replace{nota\d*})] will suppress all the occurences of "notaXX" in the text. If two parameters are given, the occurences of the first parameter will be replaced by the second. So tous replace all the occurences of 2005 and 2006 in a text by "2007",use this: [(#TEXTE|replace{200[56],2007})]. Simple text replacements can also be made [(#TEXTE|replace{melon cauliflower,melancholy flower})].

Filters of comparison and testing

-  |?{vrai,faux} is an advanced version of |sinon. It takes one or two parameters:

  • vrai is the value to be displayed instead of the filtered element if it is non-empty.
  • faux is optional. It is the value to be displayed if the filtered element is empty.
    [(#TEXTE|?{#TEXTE,"no text"})] is equivalent to the example given for the filter |sinon.

-  |sinon, indicates what should be displayed if the filtered element is empty. Thus, [(#TEXTE|sinon{"No text found"})]
displays the content of #TEXTE, but if it is empty, it displays instead: "No text found".

-   |oui returns a space or nothing. This is equivalent to |?’ ’,’’ ou |?’ ’ and returns a non-empty content (a space) to indicate that the optional parts of the tags should be displayed.

-   |non is the inverse of |oui and is equivalent to |?’’,’ ’

-   |et allows to check the presence of 2 elements

-   |ou checks for the presence of one of the two elements

- |xou checks for the presence of only one of two elements.

In addition, SPIP will understand the English equivalents « yes », « not », « or », « and » et « xor »

// displays the introdoctury paragraph if it exists, otherwise the beginning of the text
[(#CHAPO|sinon{#TEXTE|couper{200}})]
 // displays "This title is long" only if the title is longer than 30 character
[(#TITRE|strlen|>{30}|oui) This title is long ]
 
[(#CHAPO|non) There is no chapo ]
[(#CHAPO|et{#TEXTE}) There is a chapo, and a text ]
[(#CHAPO|et {#TEXT}|no) There are no both together ]
[(#CHAPO|ou{#TEXTE}) There is either a chapo, or a text, or both ] [(#CHAPO|ou{#TEXTE}|no)
[(#CHAPO|ou{#TEXT}|no) There is neither a chapter nor a text ] [(#CHAPO|x})
[(#CHAPO|xou{#TEXTE}) There is either a chapo or a text (but not both, or neither) ] [(#CHAPO|xor{#TEXTE}|no)
[(#CHAPO|xor{#TEXT}|non) There is either nothing or everything, but not both ]

-   Filters to make comparisons with values:

  • |=={value} and |!={value} make it possible to check, respectively, the equality or inequality of the filtered element and another value. Example:
    <li [(#TITRE|=={editorial}) id="editorial">]#TITRE</li>
  • |>{value}, |>={value}, |<{value} and |<={value} can only be used with tags which have a numeric value and perform a comparison with another numeric value.
    For Example:
    [(#TOTAL_BOUCLE)[(#TOTAL_BOUCLE|>{1}|?{'articles','article'})] in this section]
    

Note: In fact, all PHP comparison operators may be used as filters.

Logo filters

Logo filters have the same syntax as all other filters:
[(#LOGO_XXX|filtre)]

But:
-  #LOGO_XXX**returns the file
-  #LOGO_XXX{top/left/right/center/bottom} generates an alignment
-  #LOGO_XXX{url} generates a logo that points to the url.

-  The filters hauteur and largeur give information on the size (hauteur = height, largeur = width) of an image corresponding to a tag.

These filters are of little interest in the case of logos belonging to documents, because the values they give are already provided by the tags #HAUTEUR et #LARGEUR of the Documents loop. But they can be applied after the filter reduire_image so as to learn the exact dimensions of the image following its reduction in size.

More generally, these filters may be applied to any tag or filter which return an HTML <img ...> tag.

-  |image_reduire{largeur,hauteur} constrains the maximum size of images and logs.

It can be used on a logo in the following way:

[(#LOGO_ARTICLE|right||image_reduire{130})]

In this example the atricle logo is right-aligned with a maximum dimension of 130 pixels.

This filter can take two parameters: largeur et hauteur. If one of the parameters is 0, SPIP only takes the other into account and calculates this dimension keeping it in proportion for the image. This filter can also be applied to the tag #TEXTE and in this case all images which authors have put into their text using SPIP shortcuts will be constrained to the given size.

So for example,

[(#TEXTE|image_reduire{600,0})]

will limit all images displayed in the text to a maximum width of 600 pixels. This makes it possible to ensure a consistent page layout without the author needing to worry about the size of the images which he or she places in an article.

NB. If the option “Generation of thumbnail images” has been activated in the site configuration, these reduced images will be images recalculated by SPIP using a server programme (ideally the GD2 extension), that is for the formats which the server is able to handle (with GD2 this usually means .jpg et .png). Otherwise, a complete version of the image is displayed with the size constraints fixed directly in the HTML code.

Mathematical filters

-  |plus{nn}, |moins{nn} and |mult{nn} correspond, respectively, to addition, subtraction and multiplication.

-  |div{nn} corresponds to non-Euclidean division.

-  |modulo{nn} returns remainder (modulo) of a number after division by nn.

For example, [(#COMPTEUR_BOUCLE|modulo{5})] counts from 0 to 4, then comes back to 0, etc.

In addition, the whole set of mathematical functions present in the PHP language can be used as filters.

Other filters

-  traduire_nom_langue is applied to the tag #LANG and returns the name of the language (instead of the language code) in that language.

Note: The names of languages follow the conventions used in the language in question. Thus «fr» is converted to «français» (without a capital letter), while «es» becomes «Español» (with a capital).

-  |alterner{1,2,3,...} will usually be used with #COMPTEUR_BOUCLE. It returns the value of one of its parameters, according to the current value of the tag to which it is applied. The number of arguments determines the periodicity of the changes. Examples:
In this way, you can alternate a display in a loop. For example,
[(#COMPTEUR_BOUCLE{'yellow','blue'})] will display "white" on the first iteration of the loop, "yellow" on the second, "white" on the third, "yellow" on the fourth, etc. Thus, one can make a list of items that uses a different colour for the odd and even lines:

<B_articles>
   <ul>
<BOUCLE_articles(ARTICLES) {par titre}>
   <li style="background: [(#COMPTEUR_BOUCLE|alterner{'white','yellow'})]">#TITRE</li>
</BOUCLE_articles>
   </ul>
</B_articles>

Note: this filter is purely “numeric”. Thus if it is applied in this way: [(#ID_ARTICLE|alterner{1,2})] it will return “1” for articles with an odd-numbered ID and “2” for those with an even-numbered ID.

-  inserer_attribut{attribut,valeur} makes it possible to add an attribute to an HTML tag which SPIP generates. For example: [(#LOGO_DOCUMENT||inserer_attribut{'alt',#TITRE})] will add an ‘alt’ attribute whose value is the title of the document.

-  extraire_attribut{attribut} is the opposite of the previous filter. It allows you to read the value of an attribute in an HTML tag which has been generated by SPIP. For example, you can discover the path to the thumbnail file which the filter image_reduire has made in this way:
<div style="background: url([(#LOGO_ARTICLE||image_reduire{90}|extraire_attribut{src})]) left;"]>#TEXTE</div>

-  parametre_url{parameter,value} [SPIP 1.8.2] is a filter which lets you add or remove parameters to or from a URL which has been generated by a SPIP tag. If value is '' then the filter removes the parameter from the URL. For example, the tag #SELF returns the URL of the current page. So:

  • [(#SELF|parametre_url{'id_article','12'})] will place a variable id_article equal to 12 un the URL,
  • while [(#SELF|parametre_url{'id_article',''})] will remove any id_article parameter from the current URL.

When used with just one parameter the filter acts differently: #URL...|parametre_url{x} returns the value of the parameter ’x’ in the URL.

This example makes buttons in order to navigate among the documents on a page:

<BOUCLE_current(DOCUMENTS) {id_document}>
  #LOGO_DOCUMENT
  <ul>
  <BOUCLE_previous(DOCUMENTS) {par date} {age_relatif <= 0} {0,1} {exclus}>
  <li>
    <a href="[(#SELF|parametre_url{'id_document',#ID_DOCUMENT})]" title="previous">
      [(#LOGO_DOCUMENT||image_reduire{70})]
    </a>
  </li>
  </BOUCLE_previous>
  <BOUCLE_next(DOCUMENTS) {par date} {age_relatif > 0} {0,1}>
  <li>
    <a href="[(#SELF|parametre_url{'id_document',#ID_DOCUMENT})]" title="next">
      [(#LOGO_DOCUMENT||image_reduire{70})]
    </a>
  </li>
  </BOUCLE_next>
  </ul>
</BOUCLE_current>

Technical filters

-  entites_html converts a text into HTML entities, which can then be placed into a form field. Example: [<textarea>(#DESCRIPTIF|entites_html)</textarea>]

-  texte_script converts the text returned by any tag into a string which can safely be used in PHP or JavaScript. Example: <?php $x = '[(#TEXTE|texte_script)]'; ?>. Caution: you must use the character ' and not ", as in the second case, if your text contains the symbol $, the result could be catastrophic (truncated display, wrong display, PHP crash, etc.)

-  attribut_html converts the text returned by any tag into a string which can safely be used as an HTML attribute. For example, in order to add a mouseover popup text to a hyperlink:

<a href="#URL_ARTICLE" [ title = "(#DESCRIPTIF|supprimer_tags|attribut_html)" ]>#TITRE</a>.

-  liens_absolus is applied to a text tag and transforms any links it contains into absolute links (with the complete site URL). This filter can be particularly useful in the templates for an RSS feed.

-  url_absolue works in the same way as the previous filter, but is applied to a tag which returns a URL (#URL_ARTICLE for example).

-  abs_url combines the two preceding filters and can thus be applied to either a text tag or a URL tag.

-  form_hidden If you make a form on a page which has parameters in the URL, it can be necessary to place the values of these parameters in hidden fields(for example when the #SELF tag is used with the default style of URLs). This function calculates and inserts the necessary fields. Use in this way:

<form action="#SELF">
[(#SELF|form_hidden)]
...
</form>

-  |compacte reduces the size of a CSS or Javascript file by supressing all comments it contains. The filter reads the file and produces a compacted copy to which it gives the address. For example, <link rel="stylesheet" href="[(#CHEMIN{spip_style.css}|compacte)]" type="text/css" media="all" />.

-  Several other technical filters can be found on this page and here.

Adding your own filters

SPIP filters are PHP functions which return just one variable. This means that you can also use PHP’s existing functions and, in addition, create your own custom functions in this way:

function my_filter($text) {
    $text = (tweaks in PHP) ...;
    return $text;
}

In order to avoid changing any core Spip files (which would be overwritten during a programme upgrade), you should place all your own functions in a file named mes_fonctions.php. If SPIP finds a file with this name, it includes it automatically.

This file may be placed:

  • in the directory which contains your templates, or
  • in the root directory of the site
    But never in both places at once.

Filters with parameters

It is possible to pass parameters to filters. The syntax is:
[(#TAG|filter{arg1, arg2}|...)]
and the filter must be defined in the following way in mes_fonctions.php:

function filter($texte, $arg1='default value 1', $arg2='default value 2')
{
    ....calculations....
    return (a string);
}

Any built-in PHP function or function provided by SPIP, or one which is defined in mes_fonctions.php can be called in this way, provided that the text which is to be operated on is the first argument. For example, the PHP function rtrim could be used to remove the final punctuation mark from a text, thus: [(#TEXTE|rtrim{'.?!'})].
The parameters may also be SPIP tags themselves (but without optional codes or filters). For example: [(#TOTAL_BOUCLE|=={#COMPTEUR_BOUCLE}|?{'Fin.',''})]
SPIP tags which have filters themselves may be used:
[(#DESCRIPTIF|sinon{[(#CHAPO|sinon{#TEXTE}|couper{300})]})]

Author bealach, George, Paolo, Thomas Sutton Published : Updated : 28/06/23

Translations : عربي, català, Deutsch, English, Español, français, italiano, Nederlands