Skip to content

Premade templates in the editor

Premade templates let users start from a designed template instead of an empty canvas.

Enabling premade templates

To activate the premade template picker, set the following option in your TOPOL_OPTIONS configuration:

ts
premadeTemplates: true,

Once enabled, users who open the editor on an empty template are presented with two options:

  • Start from predefined template
  • Design from scratch
Predefined template picker start

Selecting the predefined template option opens a Premade Template Modal Picker directly inside the editor.

Predefined template modal picker

The Premade Template Modal Picker displays a selection of ready-made email templates provided by Topol. These templates are hosted by Topol and are immediately available to use without further configuration.

The picker can also filter templates by categories or keywords. Those filters appear only when the matching API endpoints are set in your TOPOL_OPTIONS.api configuration for listing categories and keywords. Setting either endpoint to an empty string disables the corresponding filter.

Picker options

The optional premadeTemplatesOptions object controls two elements of the picker interface:

ts
premadeTemplatesOptions: {
  hideSearch: true,  // hides the search input in the template list
  showDelete: true,  // shows the Delete button on a template's detail view
},

Both keys are optional booleans and default to off. showDelete is what surfaces the Delete button that calls the Remove Template endpoint, so custom template libraries that support deletion need it set.

Load custom premade templates

Alongside the default Topol templates, your own template library can be served from your backend, which puts brand-specific or client-specific templates directly in the editor.

To do this, implement the following API endpoints.

WARNING

Before implementing the endpoints, check how to work with API endpoints.

List Templates

Called to retrieve a paginated list of available templates.

Request

  • URL: /{API.PREMADE_TEMPLATES}
  • Method: GET
  • params:
    • per_page (integer) - number of templates per page, always sent, starts at 25
    • current_page (integer) - page number, always sent, starts at 1
    • categories (array) - category IDs to filter by
    • keywords (array) - keyword IDs to filter by
    • search (string) - search for templates by name

per_page and current_page are sent on every request, so your endpoint does not need defaults for them. The remaining three are sent only when a filter or search is active.

Expected Response:

json
{
  "success": true,
  "data": {
    "data": [
      {
        "id": 1,
        "name": "Example template",
        "type": "FREE",
        "img_thumb_url": "example.com/img-thumb-url",
        "category_id": 1,
        "description": "Example description",
        "keywords": [
          {
            "id": 1,
            "keyword": "marketing",
            "slug": "marketing",
            "created_at": "2023-01-01T00:00:00.000000Z",
            "updated_at": "2023-01-01T00:00:00.000000Z",
            "pivot": {
              "premade_template_id": 1,
              "premade_template_keyword_id": 1
            }
          }
        ],
        "created_at": "2023-01-01T00:00:00.000000Z",
        "updated_at": "2023-01-01T00:00:00.000000Z"
      }
    ],
    "total_records": 150,
    "current_page": 1,
    "per_page": 25,
    "next_page": 2,
    "prev_page": null,
    "last_page": 6
  }
}

Of the pagination fields, only last_page is read by the editor, where it decides whether the Load more button appears. The others are accepted and ignored, so they are safe to include for your own use. Each template entry needs id and img_thumb_url for the list to render.

List Template

Retrieves full content (HTML + JSON) of the selected template.

  • URL: /{API.PREMADE_TEMPLATES}/{template-id}
  • Method: GET

Response:

json
{
  "success": true,
  "data": {
    "id": 1,
    "name": "Example template",
    "type": "FREE",
    "html": "<b>example html </b>",
    "json": "{\"example\": \"json\"}",
    "category_id": null,
    "order": 1,
    "description": null,
    "visible": 1,
    "created_at": "2023-01-01T00:00:00.000000Z",
    "updated_at": "2023-01-01T00:00:00.000000Z",
    "image_path": "/img/templates/1.jpg",
    "image_thumb_path": "/img/templates/1_thumb.jpg",
    "category": null,
    "keywords": []
  }
}

The editor reads only html and json from this response. json must be a JSON-encoded string, as shown above, because the editor parses it before loading the template.

List Categories

Calling this endpoint will enable a built-in feature for filtering templates by categories and populate it with relevant data.

  • URL: /{API.PREMADE_TEMPLATE_CATEGORIES}
  • Method: GET

Response:

Successful response will look like this:

json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "Business",
      "value": "business"
    },
    {
      "id": 2,
      "name": "E-commerce",
      "value": "e-commerce"
    }
  ]
}

List Keywords

Calling this endpoint will enable a built-in feature for filtering templates by keywords and populate it with relevant data.

  • URL: /{API.PREMADE_TEMPLATES_KEYWORDS}
  • Method: GET

Response:

Successful response will look like this:

json
{
  "success": true,
  "data": [
    {
      "id": 1,
      "name": "sale/discount",
      "value": "salediscount"
    },
    {
      "id": 2,
      "name": "autumn",
      "value": "autumn"
    }
  ]
}

Remove Template

Deletes a template from your custom source. The Delete button that calls this endpoint appears only when premadeTemplatesOptions.showDelete is set (see Picker options).

  • URL: /{API.PREMADE_TEMPLATES}/{templateId}
  • Method: DELETE

Expected response:

json
{
  "success": true
}