The process of building public and private pages

The working of SPIP [1] is based on 2 entry points for the site:

  1. Public: index.php alias spip.php at the root
  2. Private: ecrire/index.php

The requested page is specified in either case by the GET or POST arguments associated with the request. We will see below which are the main ones.

With very rare exceptions (customisation), all other scripts in the tree are not directly executable but could only be included. They are generally "protected" by an initial test:

// securiser
if (!defined("_ECRIRE_INC_VERSION")) {

This verifies that the constant _ECRIRE_INC_VERSION is set, which will not be the case if the script is loaded directly.

This constant is defined by ecrire/inc_version.php which is the keystone of the SPIP architecture. This script is in fact included almost at the very beginning by the public or private indexes.

For the public index, this requires the initial inclusion of ecrire/public.php: apart from this include, we can see that this index is practically empty.


This script is common to all SPIP components. It carries out the basic definitions, initializations and inclusions that determine how everything else works.
It initialises the constants and global variables necessary for SPIP to function, in particular those ensuring its portability on the different platforms.

Quite early on when it loads, it includes the files:

  • inc/utils.php, which contain the functions essential to SPIP (see below)
  • the optional out-of-distribution script named
    which allows to modulate this initialization without having to modify the file

Code sequence:

  • definition of the constant "key" _ECRIRE_INC_VERSION see above
  • definition of the constants representing the base directories of SPIP and in particular _DIR_RACINE, site root, and _DIR_RESTREINT, ecrire/ directory on which all the other folder constants will be based, see details in the code.
  • search, without yet including it from the script mes_options.php historically in ecrire/ and in a standard installation in config/
  • Initialization of all the basic SPIP global sets, including the personalization variables, see technical index of
  • inclusion of inc/utils.php
  • inclusion of mes_options.php optional
  • call of spip_initialisation() if mes_options hasn’t already done it (possibly specifying this initialisation). It takes as parameters the 4 basic SPIP directories: config/, IMG/, tmp/ and local/ and:
    • defines from them all the directories required by SPIP and the rights assigned to them.
    • retrieves and sanitizes all the arguments of the request: GET, POST, COOKIES and server environment.
    • Installs the read/write/delete module necessary for all the caches, among other things.
    • commands the loading of metas, the configuration of SPIP, from the database ... and incidentally the connection to this database.
  • loads the plugins from the tmp/charger_plugins_options.php cache, regenerating this script if necessary.

If we are installing, inc_version.php has a particular functioning that we will not discuss here.


This script does not perform any action but defines the fundamental utility functions of SPIP. There are more than fifty of them ! Here are the most important ones:

  • find_in_path(): in order to allow the customization of the site, most of the files, whether scripts, templates or files served as images, are searched in the "path", in order, directories:
    • squelettes: those optionally defined in
    • $GLOBALS['dossier_squelettes'] and squelettes/
    • activated plugins
    • ecrire/
    • dist/
    • site root
  • include_spip(): allows to include a php script according to the previous schema, so to overload it by providing an alternative (commonly called "fork")
  • charger_fonction(): identical scenario but adapted to a function, which can be defined anywhere. The mechanism first looks for the function under its name() and then, if not found, under a remote_name() as was done historically (all Spip files are loaded by these last two functions).
  • spip_log(): utility to make logs, typically in tmp/log/spip.log, important for the development and monitoring of a site. Note that being based on a var_export(), it can be passed any type of parameter to trace.
  • spip_query(): all SQL queries must pass through this function. Important, table names must be specified as spip_tablename, with the function replacing "spip_" with the real prefix of the installation tables.
  • _q(): this function protects the variables included in a SQL query ( escaping). It is fundamental to pass any variable used in an SQL query if you want to avoid injection attacks.
  • _request(): allows you to retrieve argument variables from the query, regardless of whether they come from a GET, POST or COOKIE and with the assurance that they are "cleaned up" correctly.
  • spip_initialisation() seen above


This optional script allows you to configure the constants, customization variables and functions of SPIP "to your liking".
See the article dedicated to it.

Main Query Argument

As we have seen, the only access to SPIP is via index.php at the root or in ecrire/. The page requested is specified by the arguments accompanying the request. This can be by GET or POST.
These arguments can be explicit or generated by url rewriting when using urls "propres".

They are:

  • page: it’s the only argument for the public area. It specifies the requested page as sommaire (the default), article ... It is interpreted by ecrire/public.php to determine the main background (the template.html of the same name as the page argument) to be returned after having "filled" it according to the other parameters of the request like id_article.
  • action: although this parameter is also interpreted by ecrire/public.php, this is a request that (hopefully) makes a change in the server data. SPIP provides a mechanism to secure such a request. The script which will be used is action/xxx.php where xxx is the value of action.
  • exec: This is typically the argument to a "private" url. Its value xxx gives the script ecrire/exec/xxx.php which will be used.

See Extending SPIP


[1Completely streamlined since version 1.9

Author jack Published : Updated : 14/07/23

Translations : English, français