symfonyckeditortwigfckeditor

Editing Twig templates in CKeditor


I'm trying to allow admin users to edit email templates. These templates are stored in the DB as Twig ones. So the variables in them are set as {{ purchase.number }} and there are loops like

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

Below is one of the templates where I can reproduce this issue:

        <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>

When I just open a page with CKEditor textarea with this template in it, I do no changes to the template and just click on "Source" button and here is how the above mentioned template looks after the click:

<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>

Notice that not only single quote changes to html code, but the main thing is that loops are moved, so it used to be:

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

but becomes:

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

Why does CKEditor change the source if these entities are NOT html and I don't do any changes, I don't even focus on the field.

I tried using these CKEditor config options:

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!!!!!
};

But I still experience this. Can anyone advise on the config option or any other workaround, except for not using WYSIWYG. I tried to convince users to edit html/twig, but the just want WYSIWYG. Thanks


Solution

  • One possible workaround for me, was to add the Twig blocks to config.protectedSource:

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

    They will be ignored in the WYSIWYG editor, but will still be visible in the source code view.

    Additionally you can install the plugin Show protected and there's still a visible hint.