PHP_Festi_MarkdownField

Overview

The PHP_Festi_MarkdownField is an extension of the textarea field, designed to handle Markdown content seamlessly. It leverages the power of league/commonmark, a reliable and feature-rich PHP Markdown parser.

  • Extends: textarea field with all its available options.
  • Markdown Parser: Documentation.

Installation

To include this field in your project, simply install the package via Composer:

composer require festi-team/dgs-markdown-field

Adding the Field to DGS

Description

This field is based on the textarea field and inherits all of its configurations. In addition, it offers support for Markdown syntax, making it ideal for use cases that involve rich text or documentation-style content.

Example Field Configuration

Here’s an example of how to configure the markdown field in your DGS XML:

 <field type="<?php echo \Festi\Store\Fields\Markdown\MarkdownField::class; ?>"
        caption="<?php echo __('Note'); ?>"
        name="note"
        maxChars="1000"
        required="true"
        sorting="true"
        filter="text"
        width="65%"/>

Localization

The field passes a language option to Toast UI Editor based on the current Core::OPTION_LANG value. The matching i18n script is loaded from the Toast UI CDN unless the consuming Store provides a custom asset URL.

Built-in locales

Core::OPTION_LANG Toast UI locale i18n script
uk uk-UA https://uicdn.toast.com/editor/latest/i18n/uk-ua.js
ru ru-RU https://uicdn.toast.com/editor/latest/i18n/ru-ru.js
pl pl-PL https://uicdn.toast.com/editor/latest/i18n/pl-pl.js
de de-DE https://uicdn.toast.com/editor/latest/i18n/de-de.js
en en-US https://uicdn.toast.com/editor/latest/i18n/en-us.js

When the current language is not in this map, no i18n script is loaded and the editor falls back to its default English UI.

Adding a custom locale via Store contract

A Store that owns a MarkdownField can extend or override the locale map by implementing Festi\Store\Fields\Markdown\Contracts\IMarkdownLocalesProvider. The field reads the provided map at init time and merges it on top of the defaults — entries from the Store win when keys collide.

MarkdownFieldLocale carries two values:

  • locale — the identifier passed to Toast UI as language (e.g. kk-KZ).
  • assetUrl — full URL of the i18n script. When null, the field loads the script from the official Toast CDN at https://uicdn.toast.com/editor/latest/i18n/{lowercase-locale}.js. Set it when the locale is not published on the CDN and you ship the script yourself.
<?php

declare(strict_types=1);

use Festi\Store\Fields\Markdown\Contracts\IMarkdownLocalesProvider;
use Festi\Store\Fields\Markdown\Contracts\MarkdownFieldLocale;

class NotesStore extends Store implements IMarkdownLocalesProvider
{
    public function getMarkdownLocales(): array
    {
        return [
            // Toast publishes the script — only the locale code is needed.
            'fr' => new MarkdownFieldLocale(locale: 'fr-FR'),

            // Toast does not publish kk-KZ; ship the script with your project.
            'kk' => new MarkdownFieldLocale(
                locale: 'kk-KZ',
                assetUrl: '/plugins/Notes/static/js/markdown-i18n/kk-kz.js'
            ),
        ];
    }
}

Notes

  • The current language is read from Core::OPTION_LANG and normalized (strtolower, _ → -) before lookup. Map keys must be in the same form.
  • The i18n script is loaded as a regular <script> tag, not as an ES module. It must be a self-executing IIFE/UMD bundle that registers itself via toastui.Editor.setLanguage(...) against the global Toast UI Editor loaded earlier. The source files in tui.editor/apps/editor/src/i18n use ES modules (import Editor from '../editorCore') and will not work copied verbatim — wrap them in an IIFE that reads toastui.Editor from the global scope. See the bundled scripts on the CDN (e.g. https://uicdn.toast.com/editor/latest/i18n/uk-ua.js) for the runtime shape, or use this minimal template:
(function () {
    const Editor = toastui.Editor;

    Editor.setLanguage(['kk', 'kk-KZ'], {
        Markdown: 'Markdown',
        // ... payload mirrors the source file from the Toast repo
    });
})();
  • Locale resolution happens in the field's onInit(). Make sure the Store reference is available at that point — return a static map from getMarkdownLocales(), do not rely on per-row state.