English Français Deutsch

Relation function

Starting with version 3.0, Sofawiki supports the Relation language. Relation is at first a query language for the Sofawiki database. But it is more than that. It is a general purpose programming language that allows you to program calculations directly in your templates.

In certain aspects, Relation ressembles the Query function and it has its origin in it. Relation executes Relational Algebra on a stack of relations. Relation is however a complete refactoring and has several improvements:

You find the full documentation of Relation on the website for Belle Nuit Relation, because this is also an Desktop and a command line application.

There is a playground special:relation

Implementation differences

For 90%, the code is identical with the code described in Belle Nuit Relation. There are some differences, first because we are in a server environment and in a Sofawiki context, second because some instructions are not yet ported.


Single { and } are possible, also single [ and ]. If you need double, quote them separately.
To avoid parsing conflicts, the expression engine has also predefined constants _pipe, _colon, _leftsquare, _rightsquare, _leftcurly, _rightcurly, _lt, _gt and _amp.

Both examples are equivalent

The template function can embed templates and functions. Use template content as argument.

Many native wiki functions can also be used. You can use your own wiki functions, if the arity function is defined and returns at least 0.

See also Expression parser and Infinite and undefined

filter name (hint)? (, name (hint)?)*

Belle Nuit Relation provides no instruction to create a relation from Sofawiki fields. Filter fills this gap. You provide the names of the columns and for each name you can give a hint as a quoted strings. Filter returns a relation with all tuples where the value of the field is url-equal (see swNameURL in inc/utilities.php) to the hint, means it contains the hint.

The hint is optional. If you do not provide a hint, the tuple always fullfills the requirement for this field even if the field is not present. If you provide a wildcard "*", the field must be present, but can be empty. The hint can also be a name for a variable you defined before.

You can use the wildcard * at the end of the list, but only if you provide a non-empty hint for at least one field.

The internal fields with the prefix _ (like _name) can be used.
The internal field _paragraph splits up the content in paragraphs.
The internal field _word splits up the content in words.
The internal field _name speeds up search when a hint is set.
The internal field _any searches in all fields.

The key must start with a latin letter and can contain only letters, numbers and underscore. For fields defined with other keys (not recommended) you can access them by replacing the invalid letters with underscore.

Filter finds internally all results but returns only results from namespaces that the user can access or that can be transcluded.


virtual pagename

Executes the page and then reads the fields. Pagename must be quoted and can be an expression.


import pagename

Reads the fields of a page. Pagename must be quoted and can be an expression.



You can either read from a comma separated or tab separated file from within the uploads, if the filename has either the extention ".csv" or ".txt". JSON is not yet supported.
You can read from the cache folder. If the file exists both in site/files and site/cache, the file with the newer modification date is used.
Or you can read from memory within the function, if the filename does not have an extension



You can either write to the cache folder with an extensions ".csv" or ".txt. This allows you to cache complex relations you use often, but which do not update every second.
Or you can write to memory without extension. The lifetime is during the relation function, not the page.



The data instruction can have the option csv. In this case, the lines are read as csv without evaluating expressions (faster).

project concat

You can use concat as aggregator to concatenate text with the separator "::". You can combine this with the replace function to get the separator of your choice

project pivot

You can create quickly a pivot table on two columns and one aggregation. The first column becomes the rows, the second column the columns. Each cell contains the aggregation and there is a _all column and _row.

If you define the format for the value in advance, it will be populated for all created columns

See example Relation pivot


Analyze adds descriptive statistics for the datasets. The first column is expected to be the id, the following columns are the data. Empty fields are considered missing values.


In Belle Nuit Relation the only parameter is a number which can limit the lines as in print 5. In Sofawiki there are more options:

Note that unlike the Query function, there is no output if you do not use at least once the print instruction.


The template uses a page of the template namespace and the name does not need the extension ".txt".


Delegate hands over the current relation to a template or a function with the given name as parameter. The result of the lines can be used for functions. Delegate is particularly useful for the Charts functions.

input variable default (, variable default)*

The relation query can be made interactive. The input instruction shows a form with variables where you define a default value and a submit button. The relation stops here, until the user uses the submit buttom.


The default input type is text. You can use the name of the field with a qualifier to have special types

The type select uses the list separated by the pipe characters.
In the following code, use the field without the qualifyer


Examples for Rosetta Code

Not yet supported functions