Next: 11. Mailing list definition Up: Sympa Mailing Lists Management Software version Previous: 9. Virtual robot Contents Index
Subsections

- 10.1 Template file format
  - 10.1.1 Variables
  - 10.1.2 Conditions
  - 10.1.3 Loops
  - 10.1.4 File inclusions
  - 10.1.5 Stop parsing
- 10.2 Site template files
  - 10.2.1 helpfile.tpl
  - 10.2.2 lists.tpl
  - 10.2.3 global_remind.tpl
  - 10.2.4 your_infected_msg.tpl
- 10.3 Web template files
- 10.4 Sharing data with other applications
- 10.5 Sharing WWSympa authentication with other applications
- 10.6 Internationalization
  - 10.6.1 Sympa internationalization
  - 10.6.2 List internationalization
  - 10.6.3 User internationalization
- 10.7 Topics
- 10.8 Scenarii
  - 10.8.1 rules specifications
  - 10.8.2 scenario inclusion
- 10.9 Loop detection
- 10.10 Tasks
  - 10.10.1 List task creation
  - 10.10.2 Global task creation
  - 10.10.3 Model file format
  - 10.10.4 Model file examples

#
10. Customizing Sympa/WWSympa

#
10.1 Template file format

Template files within Sympa and WWSympa are text files containing programming elements (variables, conditions, loops, file inclusions) that will be parsed in order to adapt to the runtime context. These templates are an extension of programs and therefore give access to a limited list of variables (those defined in the 'hash' parameter given to the parser).

Review the Site template files (, page ) and List template files (, page ).

The following describes the syntactical elements of templates.

## 10.1.1 Variables

Variables are enclosed between brackets '[]'. The variable name is composed of alphanumerics (0-1a-zA-Z) or underscores (_). The syntax for accessing an element in a 'hash' is [hash-`>`elt].

Examples:

    [url]
    [is_owner]
    [list->name]
    [user->lang]

For each template you wish to customize, check the available variables in the documentation.

## 10.1.2 Conditions

Conditions include variable comparisons (= and `<>`), or existence. Syntactical elements for conditions are [IF xxx], [ELSE], [ELSIF xxx] and [ENDIF].

Examples:

    [IF  user->lang=fr]
    Bienvenue dans la liste [list->name]
    [ELSIF user->lang=es]
    Bienvenida en la lista [list->name]
    [ELSE]
    Welcome in list [list->name]
    [ENDIF]

    [IF is_owner]
    The following commands are available only
    for lists owners or moderators:
    ....
    [ENDIF]

## 10.1.3 Loops

Loops make it possible to traverse a list of elements (internally represented by a 'hash' or an 'array').

`Example :`

    A review of public lists

    [FOREACH l IN lists]
       [l->NAME]
       [l->subject]
    [END]

`[elt-`>`NAME]` is a special element of the current entry providing the key in the 'hash' (in this example the name of the list). When traversing an 'array', `[elt-`>`INDEX]` is the index of the current entry.

## 10.1.4 File inclusions

You can include another file within a template . The specified file can be included as is, or itself parsed (there is no loop detection). The file path is either specified in the directive or accessed in a variable.

Inclusion of a text file :

    [INCLUDE 'archives/last_message']
    [INCLUDE file_path]

The first example includes a file whose relative path is `archives/last_message`. The second example includes a file whose path is in file_path variable.

Inclusion and parsing of a template file :

    [PARSE 'welcome.tpl']
    [PARSE file_path]

The first example includes the template file `welcome.tpl`. The second example includes a template file whose path is in file_path variable.

## 10.1.5 Stop parsing

You may need to exclude certain lines in a template from the parsing process. You can perform this by stopping and restarting the parsing.

Escaping sensitive JavaScript functions :

    <HEAD>
    <SCRIPT LANGUAGE="JavaScript">
    <!-- for other browsers
      function toggle_selection(myfield) {
        for (i = 0; i < myfield.length; i++) {
        [STOPPARSE]
           if (myfield[i].checked) {
                myfield[i].checked = false;
           }else {
    	    myfield[i].checked = true;
           }
        [escaped_start]
        }
      }
    // end browsers -->
    </SCRIPT>
    </HEAD>

#
10.2 Site template files

These files are used by Sympa as service messages for the `HELP`, `LISTS` and `REMIND *` commands. These files are interpreted (parsed) by Sympa and respect the template format ; every file has a .tpl extension. See , page .

Sympa looks for these files in the following order (where `<`list`>` is the listname if defined, `<`action`>` is the name of the command, and `<`lang`>` is the preferred language of the user) :

1. `~sympa/expl/`<`list`>`/`<`action`>`.`<`lang`>`.tpl`.
2. `~sympa/expl/`<`list`>`/`<`action`>`.tpl`.
3. `~sympa/etc/templates/`<`action`>`.`<`lang`>`.tpl`.
4. `~sympa/etc/templates/`<`action`>`.tpl`.
5. `~sympa/bin/etc/templates/`<`action`>`.`<`lang`>`.tpl`.
6. `~sympa/bin/etc/templates/`<`action`>`.tpl`.

If the file starts with a From: line, it is considered as a full message and will be sent (after parsing) without adding SMTP headers. Otherwise the file is treated as a text/plain message body.

The following variables may be used in these template files :

-
  [conf-`>`email] : sympa e-mail address local part

-
  [conf-`>`domain] : sympa robot domain name

-
  [conf-`>`sympa] : sympa's complete e-mail address

-
  [conf-`>`wwsympa_url] : WWSympa root URL

-
  [conf-`>`listmaster] : listmaster e-mail addresses

-
  [user-`>`email] : user e-mail address

-
  [user-`>`gecos] : user gecos field (usually his/her name)

-
  [user-`>`password] : user password

-
  [user-`>`lang] : user language

## 10.2.1 helpfile.tpl

This file is sent in response to a `HELP` command. You may use additional variables

-
  [is_owner] : TRUE if the user is list owner

-
  [is_editor] : TRUE if the user is list editor

## 10.2.2 lists.tpl

File returned by `LISTS` command. An additional variable is available :

-
  [lists] : this is a hash table indexed by list names and containing lists' subjects. Only lists visible to this user (according to the `visibility` list parameter) are listed.

Example:

    These are the public lists for [conf->email]@[conf->domain]

    [FOREACH l IN lists]

     [l->NAME]: [l->subject]

    [END]

## 10.2.3 global_remind.tpl

This file is sent in response to a `REMIND *` command. (see , page ) You may use additional variables

-
  [lists] : this is an array containing the list names the user is subscribed to.

Example:

    This is a subscription reminder.

    You are subscribed to the following lists :
    [FOREACH l IN lists

     [l] : [conf->wwsympa\_url]/info/[l]

    [END]

    Your subscriber e-mail : [user->email]
    Your password : [user->password]

## 10.2.4 your_infected_msg.tpl

This message is sent to warn the sender of a virus infected mail, indicating the name of the virus found (see , page ).

#
10.3 Web template files

You may define your own web template files, different from the standard ones. WWSympa first looks for list specific web templates, then for site web templates, before falling back on its defaults.

Your list web template files should be placed in the `~sympa/expl/mylist/wws_templates` directory ; your site web templates in `~sympa/expl/wws_templates` directory.

Note that web colors are defined in Sympa's main Makefile (see , page ).

# 10.4 Sharing data with other applications

You may extract subscribers for a list from any of :

- a text file

- a Relational database

- a LDAP directory

See lparam user_data_source liste parameter , page .

The subscriber_table and user_table can have more fields than the one used by Sympa. by defining these additional fields, they will be available from within Sympa's scenario and templates (see , page and , page ).

#
10.5 Sharing WWSympa authentication with other applications

You might want to make other web applications collaborate with Sympa, and share the same authentication system. Sympa uses HTTP cookies to carry users' auth information from page to page. This cookie carries no information concerning privileges. To make your application work with Sympa, you have two possibilities :

- Delegating authentication operations to WWSympa
  If you want to avoid spending a lot of time programming a CGI to do Login, Logout and Remindpassword, you can copy WWSympa's login page to your application, and then make use of the cookie information within your application. The cookie format is :

      user=<user_email>:<md5>

  where `<`user_email`>` is the user's complete e-mail address, and `<`md5`>` is a MD5 checksum of the `<`user_email`>`+Sympa `cookie` configuration parameter. Your application needs to know what the `cookie` parameter is, so it can check the HTTP cookie validity ; this is a secret shared between WWSympa and your application. WWSympa's loginrequest page can be called to return to the referrer URL when an action is performed. Here is a sample HTML anchor :

      <A HREF="/wws/loginrequest/referrer">Login page</A>

- Using WWSympa's HTTP cookie format within your auth module
  To cooperate with WWSympa, you simply need to adopt its HTTP cookie format and share the secret it uses to generate MD5 checksums, i.e. the `cookie` configuration parameter. In this way, WWSympa will accept users authenticated through your application without further authentication.

#
10.6 Internationalization

Sympa was originally designed as a multilingual Mailing List Manager. Even in its earliest versions, Sympa separated messages from the code itself, messages being stored in NLS catalogues (according to the XPG4 standard). Later a `lang` list parameter was introduced. Nowadays Sympa is able to keep track of individual users' language preferences.

## 10.6.1 Sympa internationalization

Every message sent by Sympa to users, owners and editors is outside the code, in a message catalog. These catalogs are located in the `~sympa/nls/` directory. Messages have currently been translated into 10 different languages :

- cn-big5: BIG5 Chinese (Hong Kong, Taiwan)

- cn-gb: GB Chinese (Mainland China)

- cz: Czech

- de: German

- es: Spanish

- fi: Finnish

- fr: French

- hu: Hungarian

- it: Italian

- pl: Polish

- us: US English

To tell Sympa to use a particular message catalog, you can either set the `lang` parameter in `sympa.conf`, or set the `sympa.pl` `-l` option on the command line.

## 10.6.2 List internationalization

The `lang` list parameter defines the language for a list. It is currently used by WWSympa and to initialize users' language preferences at subscription time.

In future versions, all messages returned by Sympa concerning a list should be in the list's language.

## 10.6.3 User internationalization

The user language preference is currently used by WWSympa only. There is no e-mail-based command for a user to set his/her language. The language preference is initialized when the user subscribes to his/her first list. WWSympa allows the user to change it.

#
10.7 Topics

WWSympa's homepage shows a list of topics for classifying mailing lists. This is dynamically generated using the different lists' `topics` configuration parameters. A list may appear in multiple categories.

The list of topics is defined in the `topics.conf` configuration file, located in the `~sympa/etc` directory. The format of this file is as follows :

    <topic1_name>
    title	<topic1 title>
    visibility <topic1 visibility>
    ....
    <topicn_name/subtopic_name>
    title	<topicn title>

You will notice that subtopics can be used, the separator being /. The topic name is composed of alphanumerics (0-1a-zA-Z) or underscores (_). The order in which the topics are listed is respected in WWSympa's homepage. The visibility line defines who can view the topic (now available for subtopics). It refers to the associated topics_visibility scenario. You will find a sample `topics.conf` in the `sample` directory ; NONE is installed as the default.

A default topic is hard-coded in Sympa: default. This default topic contains all lists for which a topic has not been specified.

#
10.8 Scenarii

List parameters controlling the behavior of commands are linked to different scenarii. For example : the `send private` parameter is related to the send.private scenario. There are three possible locations for a scenario. When Sympa seeks to apply a scenario, it looks first in the related list directory `~sympa/expl/`<`list`>`/scenari`. If it does not find the file there, it scans `~sympa/etc/scenari`, and finally `~sympa/bin/etc/scenari`, which is the directory installed by the Makefile.

A scenario is a small configuration language to describe who can perform an operation and which authentication method is requested for it. A scenario is an ordered set of rules. The goal is to provide a simple and flexible way to configure authorization and authentication for each operation.

Each scenario rule contains :

- a condition : the condition is evaluated by Sympa. It can use variables such as sender for the sender e-mail, list for the listname etc.
- an authentication method. The authentication method can be `smtp`, `md5` or `smime`. The rule is applied by Sympa if both condition and authentication method match the runtime context. `smtp` is used if Sympa use the SMTP `from:` header , `md5` is used if a unique md5 key as been returned by the requestor to validate her message, `smime` is used for signed messages (see , page ).
- a returned atomic action that will be executed by Sympa if the rule matches

Example

> del.auth

    title.us deletion performed only by list owners, need authentication
    title.fr suppression réservée au propriétaire avec authentification
    title.es eliminación reservada sólo para el propietario, necesita autentificación

      is_owner([listname],[sender])  smtp       -> request_auth
      is_listmaster([sender])        smtp       -> request_auth
      true()                         md5,smime  -> do_it

## 10.8.1 rules specifications

A scenario consists of rules, evaluated in order beginning with the first. Rules are defined as follows :

    <rule> ::= <condition> <auth_list> -> <action>

    <condition> ::= [!] <condition
                    | true ()
                    | all ()
                    | equal (<var>, <var>)
                    | match (<var>, /perl_regexp/)
                    | is_subscriber (<listname>, <var>)
                    | is_owner (<listname>, <var>)
                    | is_editor (<listname>, <var>)
                    | is_listmaster (<var>)
                    | older (<date>, <date>)    # true if first date is anterior to the second date
                    | newer (<date>, <date>)    # true if first date is posterior to the second date
    <var> ::= [email] | [sender] | [user-><user_key_word>]
    	 	  | [subscriber-><subscriber_key_word>] | [list-><list_key_word>]
    		  | [conf-><conf_key_word>] | [msg_header-><smtp_key_word>] | [msg_body]
    	 	  | [msg_part->type] | [msg_part->body] | [is_bcc] | <string>

    [is_bcc] ::= set to 1 if the list is neither in To: nor Cc:

    <date> ::= <epoch date> | <date format>

    <listname> ::= [listname] | <listname_string>

    <auth_list> ::= <auth>,<auth_list> | <auth>

    <auth> ::= smtp|md5|smime

    <action> ::=   do_it [,notify]
                 | do_it [,quiet]
                 | reject(<tpl_name>)
                 | request_auth
                 | owner
    	     | editor
    	     | editorkey

    <tpl_name> ::= corresponding template (<tpl_name>.tpl) is send to the sender

    <user_key_word> ::= email | gecos | lang | password | cookie_delay_user
    	            | <additional_user_fields>

    <subscriber_key_word> ::= email | gecos | bounce | reception
    	                  | visibility | date | update_date
    			  | <additional_subscriber_fields>

    <list_key_word> ::= name | host | lang | max_size | priority | reply_to |
    		    status | subject | account |

    <conf_key_word> ::= domain | email | listmaster | default_list_priority |
    		      sympa_priority | request_priority | lang | max_size

(Refer to , page for date format definition)

perl_regexp can contain the string [host] (interpreted at run time as the list or robot domain). The variable notation [msg_header-`><`smtp_key_word`>`] is interpreted as the SMTP header value only when performing the sending message scenario. It can be used, for example, to require editor validation for multipart messages. [msg_part-`>`type] and [msg_part-`>`body] are the MIME parts content-types and bodies ; the body is available for MIME parts in text/xxx format only.

A bunch of scenarii is provided with the Sympa distribution ; they provide a large set of configuration that allow to create lists for most usage. But you will probably create scenarii for your own need. In this case, don't forget to restart Sympa and wwsympa because scenarii are not reloaded dynamicaly.

These standard scenarii are located in the `~sympa/bin/scenari/` directory. Default scenarii are named `<`command`>`.default.

You may also define and name your own scenarii. Store them in the `~sympa/etc/scenari` directory. They will not be overwritten by Sympa release. Scenarii can also be defined for a particular virtual robot (using directory `~sympa/etc/`<`robot`>`/scenari`) or for a list ( `~sympa/expl/`<`robot`>`/`<`list`>`/scenari` ).

Example:

Copy the previous scenario to `scenari/subscribe.rennes1` :

    equal([sender], 'userxxx@univ-rennes1.fr') smtp,smime -> reject
    match([sender], /univ-rennes1\.fr\$/) smtp,smime -> do_it
    true()                               smtp,smime -> owner

You may now refer to this scenario in any list configuration file, for example :

    subscribe rennes1

## 10.8.2 scenario inclusion

Scenarii can also contain includes :

        subscribe
            include commonreject
            match([sender], /cru\.fr$/)          smtp,smime -> do_it
    	true()                               smtp,smime -> owner

In this case sympa applies recursively the scenario named `include.commonreject` before introducing the other rules. This possibility was introduced in order to facilitate the administration of common rules.

You can define a set of common scenario rules, used by all lists. include.`<`action`>`.header is automatically added to evaluated scenarios.

#
10.9 Loop detection

Sympa uses multiple tools to avoid loops in Mailing lists

First, it rejects messages coming from a robot (as indicated by the From: and other header fields), and messages containing commands.

Secondly, every message sent by Sympa includes an X-Loop header field set to the listname. If the message comes back, Sympa will detect that it has already been sent (unless X-Loop header fields have been erased).

Thirdly, Sympa keeps track of Message IDs and will refuse to send multiple messages with the same message ID to the same mailing list.

Finally, Sympa detect loops arising from command reports (i.e. sympa-generated replies to commands). This sort of loop might occur as follows:

    1 - X sends a command to Sympa
    2 - Sympa sends a command report to X
    3 - X has installed a home-made vacation program replying to programs
    4 - Sympa processes the reply and sends a report
    5 - Looping to step 3

Sympa keeps track (via an internal counter) of reports sent to any particular address. The loop detection algorithm is :

- Increment the counter

- If we are within the sampling period (as defined by the `loop_command_sampling_delay` parameter)

  - If the counter exceeds the `loop_command_max` parameter, then do not send the report, and notify the listmaster

  - Else, start a new sampling period and reinitialize the counter, i.e. multiply it by the `loop_command_decrease_factor` parameter

#
10.10 Tasks

A task is a sequence of simple actions which realize a complex routine. It is executed in background by the task manager daemon and allow the list master to automate the processing of recurrent tasks. For example a task sends every year the subscribers of a list a message to remind their subscription.

A task is created with a task model. It is a text file which describes a sequence of simple actions. It may have different versions (for instance reminding subscribers every year or semester). A task model file name has the following format : ``<`model name`>`.`<`model version`>`.task`. For instance `remind.annual.task` or `remind.semestrial.task`.

Sympa provides several task models stored in `~sympa/bin/etc/global_task_models` and `~sympa/bin/etc/list_task_models` directories. Others can be designed by the list master.

A task is global or related to a list.

## 10.10.1 List task creation

You define in the list config file which model with which version you want to use (see , page ). Then the task manager daemon will automatically create the task by looking for the appropriate model file in differents directories in the following order :

1. `~sympa/expl/`<`list name`>`/`
2. `~sympa/etc/list_task_models/`
3. `~sympa/bin/etc/list_task_models/`

See also , page , to know more about standard list models provided with Sympa.

## 10.10.2 Global task creation

The task manager daemon checks if a version of a global task model is specified in `sympa.conf` and then creates a task as soon as it finds the model file by looking in different directories in the following order :

1. `~sympa/etc/global_task_models/`
2. `~sympa/bin/etc/global_task_models/`

## 10.10.3 Model file format

Model files are composed of comments, labels, references, variables, date values and commands. All those syntactical elements are composed of alphanumerics (0-9a-zA-Z) and underscores (_).

- Comment lines begin by '#' and are not interpreted by the task manager.
- Label lines begin by '/' and are used by the next command (see below).
- References are enclosed between brackets '[]'. They refer to a value depending on the object of the task (for instance [list-`>`name]). Those variables are instantiated when a task file is created from a model file. The list of available variables is the same as for templates (see , see page ) plus [creation_date] (see below).
- Variables store results of some commands and are paramaters for others. Their name begins with '@'.
- A date value may be written in two ways :

  - absolute dates follow the format : xxxxYxxMxxDxxHxxMin. Y is the year, M the month (1-12), D the day (1-28`|`30`|`31, leap-years are not managed), H the hour (0-23), Min the minute (0-59). H and Min are optionnals. For instance, 2001y12m4d44min is the 4th of December 2001 at 00h44.

  - relative dates use the [creation_date] or [execution_date] references. [creation_date] is the date when the task file is created, [execution_date] when the command line is executed. A duration may follow with '+' or '-' operators. The duration is expressed like an absolute date whose all parameters are optionnals. Examples : [creation_date], [execution_date]+1y, [execution_date]-6m4d

- Command arguments are separated by commas and enclosed between parenthesis '()'.

Here is the list of current avalable commands :

- stop ()

  Stops the execution of the task and delete the task file

- next (`<`date value`>`, `<`label`>`)

  Stop the execution. The task will go on at the date value and begin at the label line.

- `<`deleted_users`>` = delete_subs (`<`user_selection`>`)

  Delete @user_selection email list and stores user emails successfully deleted in @deleted_users.

- send_msg (`<`user_selection`>`, `<`template`>`)

  Send the template message to emails stored in @user_selection.

- user_selection = select_subs (`<`condition`>`)

  Store emails which match the condition in @user_selection. See 8.6 Scenarii section to know how to write conditions. Only available for list models.

- create (global | list (`<`list name`>`), `<`model type`>`, `<`model`>`)

  Create a task for object with model file `~model type.model.task`.

- chk_cert_expiration (`<`template`>`, `<`date value`>`)

  Send the template message to emails whose certificate has expired or will expire before the date value.

- update_crl (`<`file name`>`, `<`date value`>`)

  Update certificate revocation lists (CRL) which are expired or will expire before the date value. The file stores the CRL's URLs.

Model files may have a scenario-like title line at the beginning.

When you change a configuration file by hand, and a task parameter is created or modified, it is up to you to remove existing task files in the `task/` spool if needed. Task file names have the following format :

``<`date`>`.`<`label`>`.`<`model name`>`.`<`list name | global`>`` where :

- date is when the task is executed, it is an epoch date
- label states where in the task file the execution begins. If empty, starts at the beginning

## 10.10.4 Model file examples

- remind.annual.task

- expire.annual.task

- crl_update.daily.task

      title.fr mise a jour quotidienne des listes de révocation
      title.us daily certificate revocation list update
      title.et sertifikaatide kehtivuse nimekirja uuendatakse iga päev
      title.hu napi frissítése a hitelesítési bizonylatok visszavonásának

      /ACTION
      update_crl (CA_list, [execution_date]+1d)
      next ([execution_date] + 1d, ACTION)

Next: 11. Mailing list definition Up: Sympa Mailing Lists Management Software version Previous: 9. Virtual robot Contents Index