summaryrefslogtreecommitdiff
path: root/src/mailman/rest/docs/templates.rst
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/rest/docs/templates.rst')
-rw-r--r--src/mailman/rest/docs/templates.rst539
1 files changed, 539 insertions, 0 deletions
diff --git a/src/mailman/rest/docs/templates.rst b/src/mailman/rest/docs/templates.rst
new file mode 100644
index 000000000..f5d6773dc
--- /dev/null
+++ b/src/mailman/rest/docs/templates.rst
@@ -0,0 +1,539 @@
+===========
+ Templates
+===========
+
+In Mailman 3.1 a new template system was introduced to allow for maximum
+flexibility in the format and content of messages sent by and through Mailman.
+For example, when a new member joins a list, a welcome message is sent to that
+member. The welcome message is created from a template found by a URL
+associated with a template name and a context.
+
+So if for example, you want to include links to pages on you website, you can
+create a custom template, make it available via download from a URL, and then
+associate that URL with a mailing list's welcome message. Some standard
+placeholders can be defined in the template, and these will be filled in by
+Mailman when the welcome message is sent.
+
+The URL itself can have placeholders, and this allows for additional
+flexibility when looking up the content.
+
+
+Examples
+========
+
+Let's say you have a mailing list::
+
+ >>> ant = create_list('ant@example.com')
+
+The standard welcome message doesn't have any links to it because by default
+Mailman doesn't know about any web user interface front-end. When Anne is
+subscribed to the mailing list, she sees this plain welcome message.
+
+ >>> anne = subscribe(ant, 'Anne')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Ant" mailing list
+ From: ant-request@example.com
+ To: Anne Person <aperson@example.com>
+ ...
+ <BLANKLINE>
+ Welcome to the "Ant" mailing list!
+ <BLANKLINE>
+ To post to this list, send your email to:
+ <BLANKLINE>
+ ant@example.com
+ <BLANKLINE>
+ You can make such adjustments via email by sending a message to:
+ <BLANKLINE>
+ ant-request@example.com
+ <BLANKLINE>
+ with the word 'help' in the subject or body (don't include the
+ quotes), and you will get back a message with instructions. You will
+ need your password to change your options, but for security purposes,
+ this email is not included here. There is also a button on your
+ options page that will send your current password to you.
+
+Let's say though that you wanted to provide a link to a Code of Conduct in the
+welcome message. You publish both the code of conduct and the welcome message
+pointing to the code on your website. Now you can tell the mailing list to
+use this welcome message instead of the default one.
+
+ >>> call_http('http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ ... 'list:user:notice:welcome': 'http://localhost:8180/welcome_1.txt',
+ ... }, method='PATCH')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+The name of the template corresponding to the welcome message is
+`list:user:notice:welcome` and the location of your new welcome message text
+is at `http://localhost:8080/welcome_1.txt`.
+
+Now when a new member subscribes to the mailing list, they'll see the new
+welcome message.
+
+ >>> bill = subscribe(ant, 'Bill')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Ant" mailing list
+ From: ant-request@example.com
+ To: Bill Person <bperson@example.com>
+ ...
+ <BLANKLINE>
+ Welcome to the "Ant" mailing list!
+ <BLANKLINE>
+ To post to this list, send your email to:
+ <BLANKLINE>
+ ant@example.com
+ <BLANKLINE>
+ There is a Code of Conduct for this mailing list which you can view at
+ http://www.example.com/code-of-conduct.html
+
+It's even possible to require a username and password (Basic Auth) for
+retrieving the welcome message.
+
+ >>> call_http('http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ ... 'list:user:notice:welcome': 'http://localhost:8180/welcome_2.txt',
+ ... 'username': 'anne',
+ ... 'password': 'is special',
+ ... }, method='PATCH')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+The username and password will be used to retrieve the welcome text.
+
+ >>> cris = subscribe(ant, 'Cris')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Ant" mailing list
+ From: ant-request@example.com
+ To: Cris Person <cperson@example.com>
+ ...
+ <BLANKLINE>
+ I'm glad you made it!
+
+The text is cached so subsequent uses don't necessarily need to hit the
+internet.
+
+ >>> dave = subscribe(ant, 'Dave')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Ant" mailing list
+ From: ant-request@example.com
+ To: Dave Person <dperson@example.com>
+ ...
+ <BLANKLINE>
+ I'm glad you made it!
+
+
+Template format
+===============
+
+Mailman expects the templates to be return as content type
+`text/plain; charset="UTF-8"`.
+
+Template URLs can be any of the following schemes:
+
+* `http://` - standard scheme supported by the requests_ library;
+* `https://` - standard scheme also supported by requests_;
+* `file:///` - any path on the local file system; UTF-8 contents by default;
+* `mailman:///` - a path defined within the Mailman source code tree. It is
+ not recommended that you use these; they are primarily provided for
+ `Mailman's internal use`_.
+
+Generally, if a template is not defined or not found, the empty string is
+used. IOW, a missing template does not cause an error, it simply causes the
+named template to be blank.
+
+
+URL placeholders
+================
+
+The URLs themselves can contain placeholders, and this can be used to provide
+even more flexibility in the way the template texts are retrieved. Two common
+placeholders include the List-ID and the mailing list's preferred language
+code.
+
+ >>> ant.preferred_language = 'fr'
+ >>> call_http('http://localhost:9001/3.1/lists/ant.example.com/uris', {
+ ... 'list:user:notice:welcome':
+ ... 'http://localhost:8180/$list_id/$language/welcome_3.txt',
+ ... }, method='PATCH')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+The next person to subscribe will get a French welcome message.
+
+ >>> dave = subscribe(ant, 'Elle')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="iso-8859-1"
+ Content-Transfer-Encoding: quoted-printable
+ Subject: =?iso-8859-1?q?Welcome_to_the_=22Ant=22_mailing_list?=
+ From: ant-request@example.com
+ To: Elle Person <eperson@example.com>
+ ...
+ <BLANKLINE>
+ Je suis heureux que vous pouvez nous rejoindre!
+
+Standard URL substitutions include:
+
+* `$list_id` - The mailing list's List-ID (`ant.example.com`)
+* `$listname` - The mailing list's fully qualified list name
+ (`ant@example.com`)
+* `$domain_name` - The mailing list's domain name (`example.com`)
+* `$language` - The language code for the mailing list's preferred language
+ (`fr`)
+
+
+Template contexts
+=================
+
+When Mailman is looking for a template, it always searches for it in up to
+three *contexts*, and you can set the template for any of these three
+contexts: a mailing list, a domain, the site.
+
+Most templates are searched first by the mailing list, then by domain, then by
+site. One notable exception is the ``domain:admin:notice:new-list`` template,
+which is sent when a new mailing list is created. Because (modulo any style
+default settings) there won't be a template for the newly created mailing
+list, this template is always searched for first in the domain, and then in
+the site.
+
+In fact, this illustrates a common naming scheme for templates. The
+colon-separated sections usually follow the form
+``<context>:<recipient>:<type>:<name>`` where ``context`` would be "domain" or
+"list, ``<recipient>`` would be "admin", "user", or "member", and ``<type>``
+can be "action" or "notice". This isn't a strict naming scheme, but it does
+give you some indication as to the use of the template. All template names
+used internally by Mailman are given below.
+
+You've already seen how the mailing list context works above. Let's look at
+the domain and site contexts next.
+
+
+Domain context
+--------------
+
+Let's say you want all mailing lists in a given domain to share exactly the
+same welcome message template. Remember that Mailman will insert
+substitutions into the templates themselves to customize them for each mailing
+list, so in general a single template can be shared by all mailing lists in
+the domain.
+
+The first thing to do is to set the URI for the welcome message in the domain
+to be shared.
+
+ >>> call_http('http://localhost:9001/3.1/domains/example.com/uris', {
+ ... 'list:user:notice:welcome':
+ ... 'http://localhost:8180/welcome_4.txt',
+ ... }, method='PATCH')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+And let's create a new mailing list in this domain.
+
+ >>> bee = create_list('bee@example.com')
+
+Now when Anne subscribes to the Bee mailing list, she will get this
+domain-wide welcome message.
+
+ >>> anne = subscribe(bee, 'Anne')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Bee" mailing list
+ From: bee-request@example.com
+ To: Anne Person <aperson@example.com>
+ ...
+ Welcome to the Bee list in the example.com domain.
+
+So far so good. What happens if Fred subscribes to the Ant mailing list?
+
+ >>> fred = subscribe(ant, 'Fred')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="iso-8859-1"
+ Content-Transfer-Encoding: quoted-printable
+ Subject: =?iso-8859-1?q?Welcome_to_the_=22Ant=22_mailing_list?=
+ From: ant-request@example.com
+ To: Fred Person <fperson@example.com>
+ ...
+ <BLANKLINE>
+ Je suis heureux que vous pouvez nous rejoindre!
+
+Okay, that's strange! Why did Fred get the French welcome message? It's
+because the mailing list context overrides the domain context! Similarly, a
+domain context overrides a site context. This allows you to provide generic
+templates to be used as a default, with specific overrides where necessary.
+
+Let's delete the Ant list's override.
+
+ >>> ant.preferred_language = 'en'
+ >>> call_http('http://localhost:9001/3.1/lists/ant.example.com/uris'
+ ... '/list:user:notice:welcome',
+ ... method='DELETE')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+Now when Gwen subscribes to the Ant list, she gets the domain's welcome
+message.
+
+ >>> gwen = subscribe(ant, 'Gwen')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Ant" mailing list
+ From: ant-request@example.com
+ To: Gwen Person <gperson@example.com>
+ ...
+ <BLANKLINE>
+ Welcome to the Ant list in the example.com domain.
+
+
+Site context
+------------
+
+Let's say we want the same welcome template for every mailing list on our
+Mailman installation. For this we use the site context.
+
+First, let's delete the domain context we set previously. Note that
+previously we used a `DELETE` method on the list's welcome template resource,
+but we could have also done this by PATCHing an empty string for the URI,
+which Mailman's REST API interprets as a deletion too. Let's use this
+approach to delete the domain welcome message.
+
+ >>> call_http('http://localhost:9001/3.1/domains/example.com/uris', {
+ ... 'list:user:notice:welcome': '',
+ ... }, method='PATCH')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+Now let's set a new welcome template URI for the site.
+
+ >>> call_http('http://localhost:9001/3.1/uris', {
+ ... 'list:user:notice:welcome':
+ ... 'http://localhost:8180/welcome_5.txt',
+ ... }, method='PATCH')
+ content-length: 0
+ date: ...
+ server: ...
+ status: 204
+
+Now Herb subscribes to both the Ant...
+
+ >>> herb = subscribe(ant, 'Herb')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Ant" mailing list
+ From: ant-request@example.com
+ To: Herb Person <hperson@example.com>
+ ...
+ <BLANKLINE>
+ Yay! You joined the ant@example.com mailing list.
+
+...and Bee mailing lists.
+
+ >>> herb = subscribe(bee, 'Herb')
+ >>> items = get_queue_messages('virgin')
+ >>> print(items[0].msg)
+ MIME-Version: 1.0
+ Content-Type: text/plain; charset="us-ascii"
+ Content-Transfer-Encoding: 7bit
+ Subject: Welcome to the "Bee" mailing list
+ From: bee-request@example.com
+ To: Herb Person <hperson@example.com>
+ ...
+ <BLANKLINE>
+ Yay! You joined the bee@example.com mailing list.
+
+
+Templated texts
+===============
+
+All the texts that Mailman uses to create or decorate messages can be
+associated with a URL. Mailman looks up templates by name and downloads it
+via that URL. The retrieved text supports placeholders which are filled in by
+Mailman. There are a common set of placeholders most templates support:
+
+* ``listname`` - fully qualified list name (e.g. ``ant@example.com``)
+* ``list_id`` - the ``List-ID`` header (e.g. ``ant.example.com``)
+* ``display_name`` - the display name of the mailing list (e.g. ``Ant``)
+* ``short_listname`` - the local part of the list name (e.g. ``ant``)
+* ``domain`` - the domain name part of the list name (e.g. ``example.com``)
+* ``description`` - the mailing list's short description text
+* ``info`` - the mailing list's longer descriptive text
+* ``request_email`` - the email address for the ``-request`` alias
+* ``owner_email`` - the email address for the ``-owner`` alias
+* ``site_email`` - the email address to reach the owners of the site
+* ``language`` - the two letter language code for the list's preferred
+ language (e.g. ``en``, ``it``, ``fr``)
+
+Other template substitutions are described below the template name listed
+below. Here are all the supported template names:
+
+* ``domain:admin:notice:new-list``
+ Sent to the administrators of any newly created mailing list.
+
+* ``list:admin:action:post``
+ Sent to the list administrators when moderator approval for a posting is
+ required.
+
+ * ``subject`` - the original ``Subject`` of the message
+ * ``sender_email`` - the poster's email address
+ * ``reasons`` - some reasons why the post is being held for approval
+
+* ``list:admin:action:subscribe``
+ Sent to the list administrators when moderator approval for a subscription
+ request is required.
+
+ * ``member`` - display name and email address of the subscriber
+
+* ``list:admin:action:unsubscribe``
+ Sent to the list administrators when moderator approval for an
+ unsubscription request is required.
+
+ * ``member`` - display name and email address of the subscriber
+
+* ``list:admin:notice:subscribe``
+ Sent to the list administrators to notify them when a new member has
+ been subscribed.
+
+ * ``member`` - display name and email address of the subscriber
+
+* ``list:admin:notice:unrecognized``
+ Sent to the list administrators when a bounce message in an unrecognized
+ format has been received.
+
+* ``list:admin:notice:unsubscribe``
+ Sent to the list administrators to notify them when a member has been
+ unsubscribed.
+
+ * ``member`` - display name and email address of the subscriber
+
+* ``list:member:digest:footer``
+ The footer for a digest message.
+
+* ``list:member:digest:header``
+ The header for a digest message.
+
+* ``list:member:digest:masthead``
+ The digest "masthead"; i.e. a common introduction for all digest
+ messages.
+
+* ``list:member:regular:footer``
+ The footer for a regular (non-digest) message.
+
+ When personalized deliveries are enabled, these substitution variables are
+ also defined:
+
+ * ``member`` - display name and email address of the subscriber
+ * ``user_email`` - the email address of the recipient
+ * ``user_delivered_to`` - the case-preserved email address of the recipient
+ * ``user_language`` - the description of the user's preferred language
+ (e.g. "French", "English", "Italian")
+ * ``user_name`` - the recipient's display name if available
+
+* ``list:member:regular:header``
+ The header for a regular (non-digest) message.
+
+ When personalized deliveries are enabled, these substitution variables are
+ also defined:
+
+ * ``member`` - display name and email address of the subscriber
+ * ``user_email`` - the email address of the recipient
+ * ``user_delivered_to`` - the case-preserved email address of the recipient
+ * ``user_language`` - the description of the user's preferred language
+ (e.g. "French", "English", "Italian")
+ * ``user_name`` - the recipient's display name if available
+
+* ``list:user:action:confirm``
+ The message sent to subscribers when a subscription confirmation is
+ required.
+
+ * ``token`` - the unique confirmation token
+ * ``subject`` - the ``Subject`` heading for the confirmation email, which
+ includes the confirmation token
+ * ``confirm_email`` - the email address to send the confirmation response
+ to; this corresponds to the ``Reply-To`` header
+ * ``user_email`` - the email address being confirmed
+
+* ``list:user:notice:goodbye``
+ The notice sent to a member when they unsubscribe from a mailing list.
+
+* ``list:user:notice:hold``
+ The notice sent to a poster when their message is being held or moderator
+ approval.
+
+ * ``subject`` - the original ``Subject`` of the message
+ * ``sender_email`` - the poster's email address
+ * ``reasons`` - some reasons why the post is being held for approval
+
+* ``list:user:notice:no-more-today``
+ Sent to a user when the maximum number of autoresponses has been reached
+ for that day.
+
+ * ``sender_email`` - the email address of the poster
+ * ``count`` - the number of autoresponse messages sent to the user today
+
+* ``list:user:notice:post``
+ Notice sent to a poster when their message has been received by the
+ mailing list.
+
+ * ``subject`` - the ``Subject`` field of the received message
+
+* ``list:user:notice:probe``
+ A bounce probe sent to a member when their subscription has been disabled
+ due to bounces.
+
+ * ``sender_email`` - the email address of the bouncing member
+
+* ``list:user:notice:refuse``
+ Notice sent to a poster when their message has been rejected by the list's
+ moderator.
+
+ * ``request`` - the type of request being rejected
+ * ``reason`` - the reason for the rejection, as provided by the list's
+ moderators
+
+* ``list:user:notice:welcome``
+ The notice sent to a member when they are subscribed to the mailing list.
+
+ * ``user_name`` - the display name of the new member
+ * ``user_email`` - the email address of the new member
+
+
+.. _requests: http://docs.python-requests.org/en/master/
+.. _`Mailman's internal use`: https://gitlab.com/mailman/mailman/blob/master/src/mailman/utilities/i18n.py#L45