我依靠模板继承系统将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
中的每个块都可能在页面上使用。
还有其他选择吗?
答案 0 :(得分:0)
我还没有想出一个我喜欢这样做的方式。在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'
我希望这会给你一些想法,如果你想出更好的方法,我会全力以赴。祝你好运。
答案 1 :(得分:0)
您可以创建另一个仅添加到流场块模板中的js块吗?因此,在base.html中,您将拥有extra_js块以及streamblock_js。您可以在extra_js中使用jquery,在streamblock_js中使用streamblock的额外依赖项。而且,如果您在一个页面上每个streamblock具有多个自定义css / js,则可以在base.html模板中添加尽可能多的额外块以加载所有依赖项。我不确定这是否行得通,但这是我的主意。