在CKeditor中编辑Twig模板

时间:2014-01-07 17:21:59

标签: symfony ckeditor twig fckeditor

我正在尝试允许管理员用户编辑电子邮件模板。这些模板作为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 textarea打开一个包含此模板的页面时,我对模板执行无更改,只需单击“源”按钮,以下是上述模板的后续处理方式点击:

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

如果这些实体不是html并且我没有做任何更改,为什么CKEditor会更改源代码,我甚至不关注该字段。

我尝试使用这些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。感谢

6 个答案:

答案 0 :(得分:6)

我可能的解决方法是将Twig块添加到config.protectedSource

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

它们将在WYSIWYG编辑器中被忽略,但仍会在源代码视图中可见。

此外,您可以安装插件Show protected,但仍有明显的提示。

答案 1 :(得分:2)

工作代码是:

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

beacose我们需要允许{{和{%tags for twig

答案 2 :(得分:2)

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

答案 3 :(得分:1)

这就是我喜欢Stack Overflow的原因 - 不管你想问什么,有人可能已经问过了!在这种情况下,答案很接近,但对我来说,添加它们作为受保护的来源并不好 - 我想在我们的CRM中使用它们作为电子邮件模板时在字符串中创建树枝模板。所以,我所做的就是让CKEditor完成它的事情,然后在模板保存之前处理它(在我们的例子中进入数据库,但它也可以存档)。

我添加的功能粘贴在下面 - 随意使用&amp;如你所愿滥用。

这是来自我们的自定义Symfony控制器onBeforePersist一个在实体被持久化之前被调用的钩子...希望它能从代码中自我解释。

注意,正则表达式可能有点狡猾,但似乎有效,我不是正则表达式专家,所以请随意提出更简洁的表达方式。

/**
 * 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);
}

答案 4 :(得分:0)

类似问题CKEditor is escaping html elements

快速提问,以上是您一次尝试过的配置选项列表?两个都喜欢这个

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

将实体设置为true,这不是您想要的,因为它会强制输出中的html实体。

答案 5 :(得分:0)

顺便说一句,其他答案都可以,但如果你在同一个句子中有多个Twig块,则不是。

所以我绝对建议使用这个Regex,它也适用于多个Twig块:

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