【问题标题】:What is correct way of inserting wagtail streamfield block dependencies into the template?将 wagtail 流场块依赖项插入模板的正确方法是什么?
【发布时间】:2018-08-13 03:07:36
【问题描述】:

我依靠模板继承系统将extra_css 和/或extra_js 插入到我的页面中:

base.html

<!DOCTYPE html>
<html lang="en">
    <head>
        <!-- Core CSS -->

        {% block extra_css %}
            {# Override this in templates to add extra stylesheets #}
        {% endblock %}

    </head>
    <body>

        {% block content %}{% endblock content %}

        <!-- Core JS -->

        {% block extra_js %}
            {# Override this in templates to add extra javascript #}
        {% endblock extra_js %}

    </body>
</html>

page.html

{% extends "base.html" %}

{% block extra_css %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/css/select2.min.css" rel="stylesheet" />
{% endblock %}

{% load wagtailcore_tags wagtailimages_tags %}

{% block content %}
<div class="blog-post">

  <!-- Custom HTML -->

  {% block content %}
  {% include_block page.body %}
  {% endblock %}

</div><!-- /.blog-post -->
{% endblock %}

{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.6-rc.0/js/select2.min.js"></script>
<script type="text/javascript">

// Custom JavaScript

</script>
{% endblock extra_js %}

这很好用,因此确实在它所属的地方插入了额外的 css/js。

如果我需要使用streamfield,其中一个块模板需要自定义 css/js,就会出现问题。在这种情况下,自定义资源与块一起插入,但不在 base.html 中的指定位置。

例如,如果上面示例中 page.html 中的 extra_js 已添加到块模板中,则 select2 会抱怨 jquery 不存在,它会完全正确,因为它是随块插入的,但与 Core JS 库之后的预期不同。

加载jquery 两次会导致其他问题:https://stackoverflow.com/a/25782679/2146346

其他选项是将所有块依赖项加载到页面中,但它会用冗余资源填充页面,因为并非streamfield 中的每个块都可能在页面上使用。

还有其他选择吗?

【问题讨论】:

    标签: django-templates wagtail wagtail-streamfield


    【解决方案1】:

    我还没有想出我喜欢的方式来做这件事。在 Wagtail 编辑器端执行此操作的工具非常好。但是,这是我为 WagtailCodeBlock 所做的:

    {% load static wagtailcodeblock_tags %}
    {% spaceless %}
        {# This is ugly, as it'll inject this code for each block, but browsers are smart enough to not load each time. #}
        <script src="{% static 'wagtailcodeblock/js/prism.min.js' %}" type='text/javascript'></script>
        <link href="{% static 'wagtailcodeblock/css/prism.min.css' %}" rel="stylesheet">
        {% load_prism_theme %}
        {% for key, val in self.items %}
            {% if key == "language" %}
                <script>
                    language_class_name = 'language-{{ val }}';
                </script>
            {% endif %}
            {% if key == "code" %}
                <pre class="line-numbers">
                    <code id="target-element-current">{{ val }}</code>
                </pre>
                <script>
                    var block_num = (typeof block_num === 'undefined') ? 0 : block_num;
                    block_num++;
                    document.getElementById('target-element-current').className = language_class_name;
                    document.getElementById('target-element-current').id = 'target-element-' + block_num;
                </script>
            {% endif %}
        {% endfor %}
    {% endspaceless %}
    

    在这个示例中,我在每个中加载 JS/CSS 资源,并让浏览器解决它。它还假设 jQuery 是在父级加载的。但是,也可以使用 JavaScript 上下文来确保只加载一次,这是我的下一步。目前,它并不漂亮,但它确实有效。

    在 Wagtail 编辑器方面,有 @property media。我希望在渲染端有类似的东西:

    class CodeBlock(StructBlock):
        """
        Code Highlighting Block
        """
    
        WCB_LANGUAGES = get_language_choices()
        off_languages = ['html', 'mathml', 'svg', 'xml']
    
    
        language = ChoiceBlock(choices=WCB_LANGUAGES, help_text=_('Coding language'), label=_('Language'))
        code = TextBlock(label=_('Code'))
    
        @property
        def media(self):
    
            theme = get_theme()
    
            prism_version = get_prism_version()
            if theme:
                prism_theme = '-{}'.format(theme)
            else:
                prism_theme = ""
    
            js_list = [
                "https://cdnjs.cloudflare.com/ajax/libs/prism/{}/prism.min.js".format(
                    prism_version,
                ),
            ]
    
            for lang_code, lang_name in self.WCB_LANGUAGES:
                # Review: https://github.com/PrismJS/prism/blob/gh-pages/prism.js#L602
                if lang_code not in self.off_languages:
                    js_list.append(
                        "https://cdnjs.cloudflare.com/ajax/libs/prism/{}/components/prism-{}.min.js".format(
                            prism_version,
                            lang_code,
                        )
                    )
            return Media(
                js=js_list,
                css={
                    'all': [
                        "https://cdnjs.cloudflare.com/ajax/libs/prism/{}/themes/prism{}.min.css".format(
                            prism_version, prism_theme
                        ),
                    ]
                }
            )
    
        class Meta:
            icon = 'code'
            template = 'wagtailcodeblock/code_block.html'
            form_classname = 'code-block struct-block'
            form_template = 'wagtailcodeblock/code_block_form.html'
    

    我希望这能给您一些想法,如果您想出更好的方法,我会全力以赴。祝你好运。

    【讨论】:

      【解决方案2】:

      您能否创建另一个仅添加到流场块模板中的 js 块?因此,在 base.html 中,您将拥有 extra_js 块以及 streamblock_js。您可以在 extra_js 中使用 jquery,并在 streamblock_js 中使用 streamblock 的额外依赖项。如果您在一页上的每个流块有多个自定义 css/js,您可以在 base.html 模板中添加尽可能多的额外块来加载所有依赖项。我不确定这是否可行,但这是我的想法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-11-17
        • 1970-01-01
        • 2019-03-10
        • 1970-01-01
        相关资源
        最近更新 更多