.. /* * This file is part of the SavaPage project . * Copyright (c) 2026 Datraverse B.V. * Author: Rijk Ravestein. * * SPDX-FileCopyrightText: (c) 2020 Datraverse B.V. * SPDX-License-Identifier: CC-BY-SA-4.0 * * For more information, please contact Datraverse B.V. at this * address: info@datraverse.com */ .. _ch-custom-email: Email Templates --------------- .. contents:: |RST_TABLE_OF_CONTENTS| :depth: 1 :local: .. _ch-custom-email-intro: Introduction ~~~~~~~~~~~~ Email templates are a powerful instrument to customize layout and content of email messages. Templates are defined as XML files, and are located in the ``/opt/savapage/server/custom/template/`` directory by default. :ref:`Alternative locations ` can be configured. Default templates are present in the SavaPage i18n jars. Therefore, after a first-time installation the custom ``template/`` directory will be empty. However, when SavaPage finds a suitable i18n XML file in the custom directory, that belongs to an :ref:`Email Message Type `, it will use that template. You can create i18n variants of template XML files by appending the locale to the base file name. For example: ``template_de.html`` is the German variant of ``template.xml``. .. _ch-custom-email-template-syntax: Email Template Syntax ~~~~~~~~~~~~~~~~~~~~~ .. contents:: :depth: 1 :local: The base syntax of an Email Template [2]_ is described by example in the following XML file: .. callout:: .. code-block:: xml # <1> # <2> # <3> # <4> HTML

with $obj.attr$ and other placeholders

]]>
.. annotations:: :1: `DTD `__ of XML persisted ``java.util.Properties`` file. :2: Placeholder object attributes are dentified by a ``$`` character at the beginning and the end. Valid objects are defined for each :ref:`Email Message Type `. The global :ref:`Application Object ` is valid for all types. :3: Content for plain ``text`` message body. :4: Content for ``html`` message body. .. [2] Email Template syntax is based on `StringTemplate `__. .. _ch-custom-email-template-syntax-cid: Embedded Images ^^^^^^^^^^^^^^^ HTML content may contain Embedded (Inline) Images. Images are first defined in separated template entries with keys that have “``cid_``” prefix. Those keys can then be used as placeholders for ``cid`` scheme values. SavaPage email processor will embed the image file and replace ``cid`` placeholders with a unique Content-ID for the Embedded (Inline) Image. Custom image files are referred to by their relative path from the custom ``template/`` directory. Internal stock images can simply be referred to by their upper-case identifier, as shown in the table below. .. table:: Stock Image Identifiers +-----------------------+-----------------------------------------------+ | Object.attribute | Value | +=======================+===============================================+ | ``SAVAPAGE_ICON`` | SavaPage Icon: 32 x 32 pixels, 705 bytes. | +-----------------------+-----------------------------------------------+ | ``SAVAPAGE_LOGO`` | SavaPage Logo with "SavaPage" text at the | | | bottom: 148 x 174 pixels, 5.6 kB. | +-----------------------+-----------------------------------------------+ The XML snippet below shows how it works: .. callout:: .. code-block:: xml SAVAPAGE_ICON # <1> images/mysite-logo.png # <2> # <3> mysite.xyz # <4> ]]> .. annotations:: :1: ``cid_1`` holds a stock image. :2: ``cid_2`` holds the relative path to a custom image file. :3: Note that the URL of the image has scheme ``cid``. |PRODUCT_NAME| email processor will embed the image and replace `$cid_1$`` with a unique Content-ID for the Embedded (Inline) Image with key ``cid_1``. :4: The ``cid_2`` image is handled just as its ``cid_1`` sibling. .. _ch-custom-email-template-stationary: Email Stationary Template ~~~~~~~~~~~~~~~~~~~~~~~~~ An Email Stationary Template is used by an :ref:`Email Message Template ` as container to embed its content in. A stationary is typically used by many :ref:`Email Messages Types `, and thus gives a common look-and-feel to various email output. A Stationary Template contains the following placeholder objects: - :ref:`Stationary `. - :ref:`Application `. And this is how it looks like: .. callout:: .. code-block:: xml $stationary.content$ and additional app placeholders]]> # <2> $stationary.header$

$stationary.content$ and additional cid_ and app placeholders

]]> # <3>
.. annotations:: :1: ``$stationary.header$`` is replaced by the ``header`` entry of the embedded template. :2: ``$stationary.content$`` is replaced by the ``text`` entry of the embedded template. :3: ``$stationary.content$`` is replaced by the ``html`` entry of the embedded template. .. note:: SavaPage uses its own stationary types. These types can be overwritten. See :ref:`Email Stationary Types `. .. _ch-custom-email-template-message: Email Message Template ~~~~~~~~~~~~~~~~~~~~~~ Email Message Templates are used by :ref:`Email Message Types `. *Template and Type are tied by name.* For example: the :ref:`JobTicketCompleted ` message type will look for the nearest i18n version of a ``JobTicketCompleted.xml`` template file. In this way, ``JobTicketCompleted_de.xml`` will be the perfect match when a German email message is requested. Email Message Template adds the entry key “``subject``” to the syntax. Optionally, entry keys “``stationary``” and “``header``” can be used to link to an :ref:`Email Stationary Template `. The syntax is described by example in the following XML file: .. callout:: .. code-block:: xml # <1> Text with $obj.attr$ placeholders # <2> EmailStationary Stationary header with placeholders HTML with placeholders.

]]>
.. annotations:: :1: The ``subject`` text of the email. :2: The ``stationary`` value (just the template file basename, without the ``.xml`` suffix) refers to ``EmailStationary.xml``, including i18n ``EmailStationary_*.xml`` variants. If a stationary is linked this way, the ``header`` value is injected into the ``stationary.header`` placeholder of the target stationary, and the ``text`` and ``html`` values are injected into the ``stationary.content`` placeholder of their counterpart stationary entry. .. _ch-custom-email-template-placeholders: Email Placeholders Objects ~~~~~~~~~~~~~~~~~~~~~~~~~~ .. contents:: :depth: 1 :local: Placeholder Objects are used in :ref:`Email Stationary `, and in :ref:`Email Message ` Templates tied to :ref:`Email Messages Types `. .. _ch-custom-email-template-placeholder-stationary: Stationary ^^^^^^^^^^ Object uniquely used by :ref:`Email Stationary Template `. .. table:: Placeholder: Stationary +------------------------+-----------------------------------------------+ | Object.attribute | Value | +========================+===============================================+ | ``stationary.header`` | The ``header`` entry of the embedded | | | template. | +------------------------+-----------------------------------------------+ | ``stationary.content`` | The ``text`` or ``html`` entry of the | | | embedded template. | +------------------------+-----------------------------------------------+ .. _ch-custom-email-template-placeholder-app: Application ^^^^^^^^^^^ A global object with SavaPage application attributes. This object can be used in *any* :ref:`Email Message Type ` context. .. table:: Placeholder: Application +--------------------------+-----------------------------------------------+ | Object.attribute | Value | +==========================+===============================================+ | ``app.name`` | Application name: “|PRODUCT_NAME|” | +--------------------------+-----------------------------------------------+ | ``app.nameVersion`` | Formatted name and version, like: |br| | | | |br| | | | “SavaPage Major.Minor.Revision” | +--------------------------+-----------------------------------------------+ | ``app.nameVersionBuild`` | Formatted name, version and build, like: |br| | | | |br| | | | “SavaPage Major.Minor.Revision (Build)” | +--------------------------+-----------------------------------------------+ | ``app.slogan`` | Short slogan describing the application: |br| | | | |br| | | | “Open Print Portal” | +--------------------------+-----------------------------------------------+ .. _ch-custom-email-template-placeholder-ticket: Ticket ^^^^^^ A Print Job Ticket. See |RST_LINK_JOBTICKETS_WEBAPP|. .. table:: Placeholder: Ticket +--------------------------+-----------------------------------------------+ | Object.attribute | Value | +==========================+===============================================+ | ``ticket.number`` | Ticket number. | +--------------------------+-----------------------------------------------+ | ``ticket.name`` | Document name. | +--------------------------+-----------------------------------------------+ | ``ticket.operator`` | Name of the Job Ticket Operator. | +--------------------------+-----------------------------------------------+ | ``ticket.returnMessage`` | The return message to :ref:`Job Ticket | | | Creator ` | | | (optional). | +--------------------------+-----------------------------------------------+ .. _ch-custom-email-template-placeholder-user: User ^^^^ A User as :ref:`Person `. .. table:: Placeholder: User +-----------------------+-----------------------------------------------+ | Object.attribute | Value | +=======================+===============================================+ | ``user.fullName`` | The full name of the user. | +-----------------------+-----------------------------------------------+ .. _ch-custom-email-template-placeholder-user-registration: User Registration ^^^^^^^^^^^^^^^^^ .. table:: Placeholder: User Registration +-----------------------+-----------------------------------------------+ | Object | Value | +=======================+===============================================+ | ``user_reg.userName`` | User Name. | +-----------------------+-----------------------------------------------+ | ``user_reg.fullName`` | User Full Name. | +-----------------------+-----------------------------------------------+ | ``user_reg.link`` | Verification URL. | +-----------------------+-----------------------------------------------+ .. _ch-custom-email-stationary-types: Email Stationary Types ~~~~~~~~~~~~~~~~~~~~~~ SavaPage uses its own Email Stationary Types. As the table below shows, currently there is just one type in use. You can use this type in your own custom :ref:`Email Message Template ` files. Or, you can override this type by creating your own ``EmailStationary.xml`` i18n variants in the custom ``template/`` directory. .. table:: Email Stationary Types +-----------------------+-----------------------------------------------+ | Name | Scope | +=======================+===============================================+ | ``EmailStationary`` | All Email messages | +-----------------------+-----------------------------------------------+ .. _ch-custom-email-msg-types: Email Message Types ~~~~~~~~~~~~~~~~~~~ .. contents:: :depth: 1 :local: The sections below describe email message types that can be customized. The list is limited for now, but will grow as more messages are refactored for this purpose. .. note:: The global :ref:`Application Object ` is valid for each message type. .. _ch-custom-email-msg-type-ticket-canceled: JobTicketCanceled Email ^^^^^^^^^^^^^^^^^^^^^^^ Email sent when a Job Ticket is canceled. See :ref:`Job Ticket Configuration Properties `. The following placeholder objects apply: .. table:: Placeholder Objects: JobTicketCanceled +-----------------+--------------------------------------------------------------+ | Object | Role | +=================+==============================================================+ | ``ticket`` | Canceled Job Ticket. | +-----------------+--------------------------------------------------------------+ | ``user`` | :ref:`Job Ticket Creator `. | +-----------------+--------------------------------------------------------------+ .. _ch-custom-email-msg-type-ticket-completed: JobTicketCompleted Email ^^^^^^^^^^^^^^^^^^^^^^^^ Email sent when a Job Ticket is completed successfully. See :ref:`Job Ticket Configuration Properties `. The following placeholder objects apply: .. table:: Placeholder Objects: JobTicketCompleted +-----------------+--------------------------------------------------------------+ | Object | Role | +=================+==============================================================+ | ``ticket`` | Completed Job Ticket. | +-----------------+--------------------------------------------------------------+ | ``user`` | :ref:`Job Ticket Creator `. | +-----------------+--------------------------------------------------------------+ .. _ch-custom-email-msg-type-user-reg-verification: UserRegVerification ^^^^^^^^^^^^^^^^^^^ Email sent to verify User :ref:`Self Registration `. The following placeholder objects apply: .. table:: Placeholder Objects: UserRegVerification +-----------------+--------------------------------------------------------------------+ | Object | Role | +=================+====================================================================+ | ``user_reg`` | User | | | :ref:`Self Registration `. | +-----------------+--------------------------------------------------------------------+ .. _ch-custom-template-locations: Custom Template Locations ~~~~~~~~~~~~~~~~~~~~~~~~~ Custom templates are located in the ``/opt/savapage/server/custom/template/`` directory. Sub-locations can be defined for different template groups. These sub-locations can then be activated for different applications, with the following configuration properties: .. list-table:: Configuration Properties for Custom Template Locations :width: 100% :header-rows: 1 * - Configuration property - Description * - custom.template.home - Home location of *all* template files, relative to the default location. For example: a value of ``group-1``` will resolve to: |br| ``/opt/savapage/server/custom/template/group-1`` * - custom.template.home.mail - Home location of Email template files, relative to the default location. For example: a value of ``group-1/mail`` will resolve to: |br| ``/opt/savapage/server/custom/template/group-1/mail`` See |RST_LINK_CONFIG_EDITOR| on how to set these items.