This pipeline is used to declare information relating to SQL tables or for certain fields in those tables. It makes it possible to supplement the information provided by ecrire/public/interfaces.php

The function accepts a parameter which is the array of declared elements, often called $interface, which must also be returned as output from the function. This array consists of the various elements, each of which are also arrays:

  • table_des_tables declares the alias names of SQL tables,
  • exceptions_des_tables assigns aliases to SQL columns for a given table,
  • table_titre specifies the SQL column of an object used to define the title for certain types of URL naming conventions,
  • table_date specifies an SQL data type column for a given SQL table which can be used for certain specific selection criteria (age, age_relatif, ...),
  • tables_jointures defines the possible joins between SQL tables,
  • exceptions_des_jointures creates aliases for SQL columns resulting from a join,
  • table_des_traitements specifies filters to be systematically applied on SPIP tags.


Declares alias names for SQL tables, relating to the declaration provided in either the principal or join tables.

In general, any plugin offering a new editorial object also declares an identical alias as the object name. This makes it possible to write loops like <BOUCLEx(NAME)>, in exactly the same way as <BOUCLEx(spip_name)> (which simply specifies the name of the SQL table).

// 'name_declare' = 'spip_rubriques', but without the 'spip_' prefix
$interface['table_des_tables']['alias'] = 'name_declare';
// examples
$interface['table_des_tables']['articles'] = 'articles'; // ARTICLE loops on spip_articles
$interface['table_des_tables']['billets'] = 'articles'; // BILLET loops on spip_articles


Just as with declaration of aliases for SQL tables, it is also possible to declare aliases for SQL columns. These aliases can also force a join to another table.

// the tag #COLUMN_ALIAS or criteria {column_alias} applied to the correct loop
$interface['exceptions_des_tables']['alias']['column_alias'] = 'column';
$interface['exceptions_des_tables']['alias']['column_alias'] = array('table', 'column');
// examples
$interface['exceptions_des_tables']['breves']['date'] = 'date_heure';
$interface['exceptions_des_tables']['billets']['id_billet'] = 'id_article';
$interface['exceptions_des_tables']['documents']['type_document'] = array('types_documents'
, 'titre');
// allows for the use of criteria like racine (root), meme_parent (same parent), id_parent
$interface['exceptions_des_tables']['evenements']['id_parent'] = 'id_evenement_source';
$interface['exceptions_des_tables']['evenements']['id_rubrique'] = array('spip_articles', 'id_rubrique');


Specifies which field will be used to generate the titles for certain URL naming conventions (propre, arborescent...). The character string passed is an SQL selection declaration (SELECT), which must return 2 columns as output (or the SQL column alias(s)) : "title" and "lang". When the object has no corresponding "lang" field, then it must return '' AS lang instead.

$interface['table_titre']['alias']= "title_column AS titre, lang_column AS lang";
// examples
$interface['table_titre']['mots']= "titre, '' AS lang";
$interface['table_titre']['breves']= 'titre , lang';

Whenever an object has declared its title, the URL generator can then create meaningful URL’s automatically (depending on the URL naming convention chosen for the web site).


This information is used to declare certain SQL columns as date type fields. The SPIP compiler can then apply certain kinds of criteria to these fields, such as "age", "age_relatif", "jour_relatif"... Only one single date type field can be declared for any given table.

$interface['table_date']['alias'] = 'column_name';
// examples
$interface['table_date']['evenements'] = 'start_date';


These declarations are used by the compiler to explicitly determine the possible joins whenever a loop on a table requests an unknown field (tag or criteria).

The compiler knows implicitly how to make certain joins (without declaring them) by looking for the column requested in the other SQL tables that it knows about. The compiler does not search through all tables, but only in those that have specific columns in common:

  • same name as the primary key,
  • same name as a column declared as a potential join in its join description in the principal or join tables.

In many cases, it is useful and preferable to explicitly declare to the compiler which joins that it can try to make when it is presented with an unknown field in a table. That is the explicit purpose of these kinds of declaration. The order of the declarations is sometimes important, since it will effect which join the compiler will find when it looks for the field in another table. Even if the field sought after would be found declared for the table anyway.

$interface['tables_jointures']['spip_nom'][] = 'other_table';
$interface['tables_jointures']['spip_nom']['column'] = 'other_table';
// examples
// {id_mot} for ARTICLES
$interface['tables_jointures']['spip_articles'][]= 'mots_articles';
$interface['tables_jointures']['spip_articles'][]= 'mots';
// event joins (for the plugin agenda) on keywords or articles
$interface['tables_jointures']['spip_evenements'][]= 'mots'; // inserted before the articles join
$interface['tables_jointures']['spip_evenements'][] = 'articles';
$interface['tables_jointures']['spip_evenements'][] = 'mots_evenements';
// articles joins to events (evenements)
$interface['tables_jointures']['spip_articles'][] = 'evenements';

Most of the time, by also using the "exceptions_des_jointures" description explained below, it will be sufficient for a SPIP loop to know how to calculate the joins that it will need to display the various tags requested. If that is not always sufficient, don’t forget that joins can also be specified in the loops and criteria themselves (cf. Forcing joins).


This definition is used to assign a column alias that creates a join with another table to retrieve another field, so long as the join is possible. It’s a bit like the "exception_des_tables" which declare a join, but is not specific to a given table. We can then use this alias as a SPIP tag or as a loop criteria.

Note that when we use these joins only as loop criteria like {titre_mots=xx}, it is preferable to write this as {mots.titre=xx}, which is a more generic style and does not require a declaration.

$interface['exceptions_des_jointures']['colonne_alias'] = array('table', 'column');
// examples
$interface['exceptions_des_jointures']['titre_mot'] = array('spip_mots', 'titre');

One special scenario also exists: a third argument can be provided that contains the name of the function which will create the join. This is a rare circumstance, one use of which is employed by the "Forms & Tables" plugin

// special case
$interface['exceptions_des_jointures']['forms_donnees']['id_mot'] = array('spip_forms_donnees_champs', 'valeur', 'forms_calculer_critere_externe');


These descriptions are very useful; they make it possible to define standardised processes (filters) for certain SPIP tags. Using an asterisk (i.e. #TAG*) will deactivate any such processes.

In concrete terms, for each tag, or each tag/loop pair, the functions specified will be executed. %s will be replaced by the actual contents that the tag returns.

Two constants are available for the most common usages:

// typographical processing
define('_TRAITEMENT_TYPO', 'typo(%s, "TYPO", $connect)');
// SPIP shortcut processing ([->artXX], <cadre>, {{}}, ...)
define('_TRAITEMENT_RACCOURCIS', 'propre(%s, $connect)');
$interface['table_des_traitements']['BALISE'][]= 'filtre_A(%s)';
$interface['table_des_traitements']['BALISE'][]= 'filtre_B(filtre_A(%s))';
$interface['table_des_traitements']['BALISE'][]= _TRAITEMENT_TYPO;
$interface['table_des_traitements']['BALISE'][]= _TRAITEMENT_RACCOURCIS;
$interface['table_des_traitements']['BALISE']['boucle']= _TRAITEMENT_TYPO;
// examples in SPIP
$interface['table_des_traitements']['BIO'][]= _TRAITEMENT_RACCOURCIS;
$interface['table_des_traitements']['CHAPO'][]= _TRAITEMENT_RACCOURCIS;
$interface['table_des_traitements']['DATE'][]= 'normaliser_date(%s)';
$interface['table_des_traitements']['ENV'][]= 'entites_html(%s,true)';
// exemples dans le plugin d'exemple "chat"
$interface['table_des_traitements']['RACE']['chats'] = _TRAITEMENT_TYPO;
$interface['table_des_traitements']['INFOS']['chats'] = _TRAITEMENT_RACCOURCIS;

An example which is often very useful is the automatic deletion of the numbers used as prefixes in section titles. This can be implemented using this method in the config/mes_options.php file (or by using this pipeline in a plugin, of course!) :

// simple version
$GLOBALS['table_des_traitements']['TITRE'][]= 'typo(supprimer_numero(%s), "TYPO", $connect)';

// complex version (do not overwrite the existing definition)
if (isset($GLOBALS['table_des_traitements']['TITRE'][0])) {
    $s = $GLOBALS['table_des_traitements']['TITRE'][0];
} else {
    $s = '%s';
$GLOBALS['table_des_traitements']['TITRE'][0] = str_replace('%s', 'supprimer_numero(%s)', $s);


Take the complex example of the Agenda plugin, which declares a table called spip_evenements(events), a linkage table called spip_mots_evenenents (keyword events) and a second linkage table called spip_evenements_participants (event participants).

An alias is defined to loop over the events. Explicit joins are declared, along with a date field and special processes. It uses nearly all of the features defined above!

function agenda_declarer_tables_interfaces($interface){
    // 'spip_' dans l'index de $tables_principales
    //-- Joins ----------------------------------------------------
    $interface['tables_jointures']['spip_evenements'][]= 'mots'; // to be inserted before the join on articles
    $interface['tables_jointures']['spip_articles'][]= 'evenements';
    $interface['tables_jointures']['spip_evenements'][] = 'articles';
    $interface['tables_jointures']['spip_mots'][]= 'mots_evenements';
    $interface['tables_jointures']['spip_evenements'][] = 'mots_evenements';
    $interface['tables_jointures']['spip_evenements'][] = 'evenements_participants';
    $interface['tables_jointures']['spip_auteurs'][] = 'evenements_participants';

    $interface['table_des_traitements']['LIEU'][]= 'propre(%s)';
    // used for critiria such as racine, meme_parent, id_parent
    $interface['exceptions_des_tables']['evenements']['id_rubrique']=array('spip_articles', 'id_rubrique');
    $interface['table_date']['evenements'] = 'date_debut';

    return $interface;

Author Mark Baber Published : Updated : 31/05/10

Translations : English, français