Редактирование шаблонов Twig в CKeditor

Я пытаюсь разрешить администраторам изменять шаблоны писем. Эти шаблоны хранятся в БД как Twig. Таким образом, переменные в них устанавливаются как {{ purchase.number }}, и есть такие петли, как

    {% if cart['shipping'] %}
        {% for line in cart['shipping'] %}
            <tr>
                <td colspan="7">Shipping ({{ line['text'] }})</td>
                <td>US${{ line['money'] }}</td>
            </tr>
        {% endfor %}
    {% endif %}

Ниже приведен один из шаблонов, где я могу воспроизвести эту проблему:

        <html>
    <body>
        <h3>Order #{{ purchase.number }} was cancelled</h3>
        <p>Order content:</p>
        <table>
            <tr>
                <th>Line</th>
                <th>Item #</th>
                <th>Product Name</th>
                <th>Shipping</th>
                <th>UOM</th>
                <th>Unit Price</th>
                <th>Quantity</th>
                <th>Subtotal</th>
            </tr>
            {% for line in cart['cart'] %}
                <tr>
                    <td>{{ line['LineNo'] }}</td>
                    <td>{{ line['ItemNo'] }}</td>
                    <td>{{ line['ProductName'] }}</td>
                    <td>{{ line['Shipping'] }}</td>
                    <td>{{ line['UOM'] }}</td>
                    <td>US${{ line['UnitPrice'] }}</td>
                    <td>{{ line['Quantity'] }}</td>
                    <td>US${{ line['Subtotal'] }}</td>
                </tr>
            {% endfor %}
            {% if cart['shipping'] %}
                {% for line in cart['shipping'] %}
                    <tr>
                        <td colspan="7">Shipping ({{ line['text'] }})</td>
                        <td>US${{ line['money'] }}</td>
                    </tr>
                {% endfor %}
            {% endif %}
            <tr>
                <td colspan="7"><b>Order Item Total:</b></td>
                <td>US${{ cart['total'] }}</td>
            </tr>
        </table>
    </body>
</html>

Когда я просто открываю страницу с текстовой областью CKEditor с этим шаблоном, я делаю без изменений в шаблон и просто нажимаю кнопку "Источник", и вот как выглядит вышеупомянутый шаблон после щелчок:

<h3>Order #{{ purchase.number }} was cancelled</h3>

<p>Order content:</p>
{% for line in cart[&#39;cart&#39;] %} {% endfor %} {% if cart[&#39;shipping&#39;] %} {% for line in cart[&#39;shipping&#39;] %} {% endfor %} {% endif %}

<table>
    <tbody>
        <tr>
            <th>Line</th>
            <th>Item #</th>
            <th>Product Name</th>
            <th>Shipping</th>
            <th>UOM</th>
            <th>Unit Price</th>
            <th>Quantity</th>
            <th>Subtotal</th>
        </tr>
        <tr>
            <td>{{ line[&#39;LineNo&#39;] }}</td>
            <td>{{ line[&#39;ItemNo&#39;] }}</td>
            <td>{{ line[&#39;ProductName&#39;] }}</td>
            <td>{{ line[&#39;Shipping&#39;] }}</td>
            <td>{{ line[&#39;UOM&#39;] }}</td>
            <td>US${{ line[&#39;UnitPrice&#39;] }}</td>
            <td>{{ line[&#39;Quantity&#39;] }}</td>
            <td>US${{ line[&#39;Subtotal&#39;] }}</td>
        </tr>
        <tr>
            <td colspan="7">Shipping ({{ line[&#39;text&#39;] }})</td>
            <td>US${{ line[&#39;money&#39;] }}</td>
        </tr>
        <tr>
            <td colspan="7"><b>Order Item Total:</b></td>
            <td>US${{ cart[&#39;total&#39;] }}</td>
        </tr>
    </tbody>
</table>

Обратите внимание, что не только одиночная кавычка изменяет код html, но главное, что петли перемещаются, поэтому это было:

        {% if cart['shipping'] %}
            {% for line in cart['shipping'] %}
                <tr>

но будет:

{% for line in cart[&#39;cart&#39;] %} {% endfor %} {% if cart[&#39;shipping&#39;] %} {% for line in cart[&#39;shipping&#39;] %} {% endfor %} {% endif %}

Почему CKEditor меняет источник, если эти сущности НЕ html, и я не делаю никаких изменений, я даже не фокусируюсь на этом поле.

Я попытался использовать эти параметры конфигурации CKEditor:

CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR;
CKEDITOR.config.entities = false;

CKEDITOR.config.forcePasteAsPlainText = false; // default so content won't be manipulated on load
CKEDITOR.config.basicEntities = true;
CKEDITOR.config.entities = true;
CKEDITOR.config.entities_latin = false;
CKEDITOR.config.entities_greek = false;
CKEDITOR.config.entities_processNumerical = false;
CKEDITOR.config.fillEmptyBlocks = function (element) {
    return true; // DON'T DO ANYTHING!!!!!
};

Но я все еще испытываю это. Может ли кто-нибудь сообщить о настройке конфигурации или любом другом обходном пути, кроме использования WYSIWYG. Я пытался убедить пользователей редактировать html/twig, но просто хочу WYSIWYG. Благодаря

Ответ 1

Одним из возможных способов обойти меня было добавление блоков Twig в config.protectedSource:

CKEDITOR.config.protectedSource.push(/\{%\s.+\s%\}/g);

Они будут игнорироваться в редакторе WYSIWYG, но все равно будут отображаться в виде исходного кода.

Кроме того, вы можете установить плагин Показать защищенный и все еще есть видимый намек.

Ответ 2

рабочий код:

CKEDITOR.config.protectedSource.push(//г {{[\ s\S]}?}); CKEDITOR.config.protectedSource.push(/{\% [\ s\S]%?}/Г); CKEDITOR.config.protectedSource.push(/{# [\ s\S] * #?}/Г);

потому что нам нужно разрешить теги {{и {% для ветки

Ответ 3

CKEDITOR.config.protectedSource = [
    /\{\{[\s\S]*?\}\}/g,
    /\{\%[\s\S]*?%\}/g,
    /\{\#[\s\S]*?#\}/g,
];

Ответ 4

Вот почему я люблю Qaru - независимо от того, что вы хотите спросить, кто-то, возможно, уже спросил об этом! В этом случае ответы были близки, но для меня добавление их в качестве защищенного источника не было хорошим - я хотел создать шаблоны ветки в строке, поскольку мы используем их для шаблонов электронной почты в нашем CRM. Итак, что я сделал, так это оставить CKEditor, чтобы выполнить свою задачу, а затем обработать ее до того, как шаблон был сохранен (в нашем случае в БД, но это также может быть файл).

Добавленная функция добавлена ​​ниже - не стесняйтесь использовать и злоупотреблять, как вы пожелаете.

Это из нашего пользовательского контроллера Symfony onBeforePersist крюк, который вызывается до того, как сущность сохраняется... Надеюсь, все это объяснит сам код.

Заметьте, что Regex может быть немного изворотливым, но, похоже, работает, я не эксперт по Regex, поэтому, пожалуйста, не стесняйтесь предлагать более сжатое выражение.

/**
 * Before we persist the data, we need to clean up any twig tags in there as the editor encodes html entities...
 *
 * @param Request $request
 * @param $form
 * @param EmailTemplates $entity
 */
public function onBeforePersist(Request $request, $form, $entity)
{
    $template = $entity->getView();

    $re = '/\{(\{|%)([^{}]|(?R))*(\}|%)\}/';
    preg_match_all($re, $template, $matches, PREG_SET_ORDER, 0);

    // We only want the first element of each match - I don't like closures as a rule on readability grounds, but this is small enough to be ok.
    array_walk($matches,function(&$value) {
        if (array($value)) {
            $value = $value[0];
        }
    });

    // Now do a replace on them
    foreach ($matches as $match) {
        $decoded = html_entity_decode($match,ENT_QUOTES);
        if ($match != $decoded) {
            // Only replace if we have actually changed the string
            $template = str_replace($match, $decoded, $template);
        }
    }

    // Update the View...
    $entity->setView($template);
}

Ответ 5

Аналогичный вопрос CKEditor скрывает элементы html

Быстрый вопрос, приведенный выше список параметров конфигурации, которые вы пробовали по одному за раз? Имея оба подобных

CKEDITOR.config.entities = false;
CKEDITOR.config.entities = true;

устанавливает сущности в значение true, а это не то, что вы хотите, поскольку оно заставляет html-объекты выводиться.

Ответ 6

Кстати, другие ответы в порядке, но если в одном и том же предложении имеется более одного блока Twig, это не так.

Поэтому я определенно рекомендую использовать это Regex вместо этого, которое также работает с несколькими блоками Twig:

CKEDITOR.config.protectedSource.push(/\{\{[\s\S]*?\}\}/g);
CKEDITOR.config.protectedSource.push(/\{\%[\s\S]*?%\}/g);