Templates

The Templates system provides email and document content templates that can be used for system emails, session and assignment notifications, study-closed emails, and pre-filled document content. Templates are edited in the same Quill-based Editor as documents; placeholder resolution is done by the backend when the template is used.

Key features include:

  • Template types with fixed placeholder sets and usage locations (see table below).

  • Multi-language content stored in template_content; default language on the template row.

  • TemplateEditor and TemplateConfigurator (Placeholders sidebar) shown when the Editor is opened with a template (templateId provided).

  • Toolbar and editor behavior controlled by the same settings as the document editor (see Editor Settings).

Overview

Templates are listed and created from Dashboard → Templates. See the dashboard documentation for navigation details.

Location: frontend/src/components/dashboard/Templates.vue

When you open a template for editing, the Editor loads with templateId provided; it renders the Quill Editor (TemplateEditor) for the main content and, for email types (1, 2, 3, 6), a Placeholders sidebar so you can insert allowed placeholders (e.g. ~username~, ~link~) into the text.

Location: frontend/src/components/editor/sidebar/TemplateConfigurator.vue

Backend storage:

  • template — name, type, public, defaultLanguage, userId.

  • template_content — content (Quill Delta) per template and language.

  • template_edit — draft edits per template and language.

  • placeholder — placeholder keys and labels per template type (used by the frontend sidebar; resolution rules live in the resolver).

Location: backend/utils/templateResolver.js

Placeholder resolution is implemented there: resolveTemplate (returns HTML for emails) and resolveTemplateToDelta (returns Delta for document creation). Only placeholders listed in PLACEHOLDERS_BY_TYPE for the template’s type are substituted at runtime.

Implementing the Template Editor

The main Editor provides templateId via provide and conditionally shows the Placeholders sidebar when the document is a template with placeholders. TemplateEditor and TemplateConfigurator are used inside this Editor when editing a template. When the user saves and closes the editor, draft edits are merged from template_edit into template_content so that the next resolution uses the latest saved content.

Location:

  • frontend/src/components/editor/Editor.vue

  • frontend/src/components/editor/template/TemplateEditor.vue

  • frontend/src/components/editor/sidebar/TemplateConfigurator.vue

<TemplateEditor v-if="templateId" />
<template v-if="templateId && template && !readOnlyOverwrite && hasPlaceholders" #templateConfigurator>
  <TemplateConfigurator />
</template>

Template Types, Placeholders, and Usage

At resolution time, only the placeholder keys listed in the following table are substituted.

Adding a New Template Type or Placeholder

Note

Placeholders marked with * in the table above are required for that type. If a required placeholder is missing from the template text, validation will fail (e.g. publishing or using the template) until it is added. The set of required placeholders is defined in the placeholder table (required: true) and enforced via getMissingRequiredPlaceholders in backend/utils/templateResolver.js.

Here is a concrete example for adding a new placeholder (e.g. studyEndDate for type 6):

  1. Backend (DB + resolver):

    • Add a row to the placeholder table via a migration:

      • type: 6 (Email - Study Close)

      • placeholderKey: studyEndDate

      • other metadata as needed (label, required, etc.)

    • Update PLACEHOLDERS_BY_TYPE / buildReplacementMap in backend/utils/templateResolver.js to fill studyEndDate from context, for example:

      • In the resolver, when context.templateType === 6, set replacements["~studyEndDate~"] = <value from study or session>.

    • If the new placeholder is driven by a specific feature (e.g. study close emails), ensure the call site (e.g. sendStudyClosedEmails in study.js) passes whatever additional data is needed into the resolver context.

  2. Frontend (editor + sidebar):

    • Add the placeholder to the template configurator configuration so it appears in the Placeholders sidebar with a name/description (e.g. update placeholderConfigs / longDescriptions in frontend/src/components/editor/sidebar/TemplateConfigurator.vue).

  3. Access / type visibility:

    • If the new placeholder is tied to a new template type, also update:

      • The template type dropdown in frontend/src/components/dashboard/templates/TemplateModal.vue.

      • getUserFilter in backend/db/models/template.js so that only the correct users (e.g. admins) see or can use that type.

Settings

The template editor uses the same toolbar and edit settings as the document editor. See Editor Settings in the Quill Editor documentation and Adding a New Setting in Settings if you need to add or change a setting key.