Wagtail streamfield 块:将 jQuery 注入 Wagtail Admin
Wagtail streamfield block: injecting jQuery into the Wagtail Admin
我正在为 Wagtail streamfields 创建一个块,它使用 Prism JS 库显示实时代码语法突出显示。它正在部分工作;当我选择了一种语言并在现有页面上放置了代码时,代码会按预期显示并突出显示:
但是,当我尝试使用新的代码块创建新的 Wagtail 页面时,出现 JavaScript 错误:
当没有要突出显示的内容时,库似乎在加载时出现延迟。我已经尝试了 $(document).ready
和 $(window).load
,但这是不同的情况,因为包含 Prism 库的模板是在您单击 "Code Snippet" 按钮时动态加载的。这是我收到的错误的详细信息:
VM730:2 Uncaught ReferenceError: Prism is not defined
at prism_repaint (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:2:5)
at populate_target_code (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:9:5)
at HTMLDocument.eval (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:2:29)
at fire (jquery-2.2.1.js:3182)
at Object.add [as done] (jquery-2.2.1.js:3241)
at jQuery.fn.init.jQuery.fn.ready (jquery-2.2.1.js:3491)
at eval (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:1:13)
at eval (<anonymous>)
at Function.globalEval (jquery-2.2.1.js:338)
at domManip (jquery-2.2.1.js:5285)
这是我用于 Wagtail 块的 Django Wagtail 代码:
class CodeBlock(StructBlock):
"""
Code Highlighting Block
"""
WCB_LANGUAGES = get_language_choices()
language = ChoiceBlock(choices=WCB_LANGUAGES)
code = TextBlock()
class Meta:
icon = 'code'
template = 'wagtailcodeblock/code_block.html'
form_template = 'wagtailcodeblock/code_block_form.html'
...以及 Wagtail 管理员表单模板的代码:
<script>
function prism_repaint(target_class) {
Prism.highlightElement($(target_class)[0]);
}
function populate_target_code(label) {
target_class = '#target-element-' + label;
code_text = $('#' + label).val();
$(target_class).text(code_text);
prism_repaint(target_class);
}
</script>
{% with prism_version="1.6.0" %}
{% block extra_css %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/{{ prism_version }}/themes/prism.min.css" rel="stylesheet" />
{% endblock extra_css %}
{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/{{ prism_version }}/prism.min.js"></script>
{% endblock extra_js %}
<div class="{{ classname }}">
{% if help_text %}
<div class="object-help help">{{ help_text }}</div>
{% endif %}
<ul class="fields">
{% for child in children.values %}
<li{% if child.block.required %} class="required"{% endif %}>
{% if child.block.label %}
<label{% if child.id_for_label %} for="{{ child.id_for_label }}"{% endif %}>{{ child.block.label }}:</label>
{% endif %}
{{ child.render_form }}
</li>
{% if child.block.label == "Language" %}
{# As we loop through, load each language dialect #}
{% for language_choice, language_name in child.block.field.choices %}
{% if language_choice|length %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/{{ prism_version }}/components/prism-{{ language_choice }}.min.js"></script>
{% endif %}
{% endfor %}
<script>
$(document).ready(function() {
// Set initial language class on load
target_class = '#target-element-{{ child.id_for_label }}'.replace('language', 'code');
{% if child.id_for_label|length %}
$(target_class).addClass('language-' + $('#{{ child.id_for_label }}').val());
{% endif %}
// Change language being highlighted when dropdown is changed
$('#{{ child.id_for_label }}').bind('input propertychange', function() {
language_class = 'language-' + $('#{{ child.id_for_label }}').val();
$(target_class).removeClass().addClass(language_class);
prism_repaint(target_class);
});
});
</script>
{% endif %}
{% if child.block.label == "Code" %}
<script>
$(document).ready(function() {
populate_target_code('{{ child.id_for_label }}');
$('#{{ child.id_for_label }}').bind('input propertychange', function() {
populate_target_code('{{ child.id_for_label }}');
});
});
</script>
<li>
<pre><code id="target-element-{{ child.id_for_label }}"></code></pre>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endwith %}
我已验证 CSS 和 JS 已使用 extra_css
和 extra_js
模板块正确注入代码。我也尝试过使用“.getScript”函数,但没有成功。我绝不是 JavaScript 专家,因此我们将不胜感激。如果有帮助,可以在 GitHub 上找到该项目的完整源代码:
https://github.com/FlipperPA/wagtailcodeblock
任何跟踪解决此问题的帮助将不胜感激!感谢您的宝贵时间。
StreamField 块借用 Django 的 form media API 将 JS/CSS 文件与块相关联 - 这是导入 JS/CSS 库的推荐方式。您的代码将变为:
from django import forms
class CodeBlock(StructBlock):
"""
Code Highlighting Block
"""
# ...
@property
def media(self):
prism_version = "1.6.0"
return forms.Media(
js=["https://cdnjs.cloudflare.com/ajax/libs/prism/%s/prism.min.js" % prism_version],
css={'all': ["https://cdnjs.cloudflare.com/ajax/libs/prism/%s/themes/prism.min.css" % prism_version]}
)
以这种方式定义 JS/CSS 意味着导入将出现在任何 可能 包含您的块的编辑页面上,而不是仅在您的块时插入已添加。
我正在为 Wagtail streamfields 创建一个块,它使用 Prism JS 库显示实时代码语法突出显示。它正在部分工作;当我选择了一种语言并在现有页面上放置了代码时,代码会按预期显示并突出显示:
但是,当我尝试使用新的代码块创建新的 Wagtail 页面时,出现 JavaScript 错误:
当没有要突出显示的内容时,库似乎在加载时出现延迟。我已经尝试了 $(document).ready
和 $(window).load
,但这是不同的情况,因为包含 Prism 库的模板是在您单击 "Code Snippet" 按钮时动态加载的。这是我收到的错误的详细信息:
VM730:2 Uncaught ReferenceError: Prism is not defined
at prism_repaint (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:2:5)
at populate_target_code (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:9:5)
at HTMLDocument.eval (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:2:29)
at fire (jquery-2.2.1.js:3182)
at Object.add [as done] (jquery-2.2.1.js:3241)
at jQuery.fn.init.jQuery.fn.ready (jquery-2.2.1.js:3491)
at eval (eval at globalEval (jquery-2.2.1.js:338), <anonymous>:1:13)
at eval (<anonymous>)
at Function.globalEval (jquery-2.2.1.js:338)
at domManip (jquery-2.2.1.js:5285)
这是我用于 Wagtail 块的 Django Wagtail 代码:
class CodeBlock(StructBlock):
"""
Code Highlighting Block
"""
WCB_LANGUAGES = get_language_choices()
language = ChoiceBlock(choices=WCB_LANGUAGES)
code = TextBlock()
class Meta:
icon = 'code'
template = 'wagtailcodeblock/code_block.html'
form_template = 'wagtailcodeblock/code_block_form.html'
...以及 Wagtail 管理员表单模板的代码:
<script>
function prism_repaint(target_class) {
Prism.highlightElement($(target_class)[0]);
}
function populate_target_code(label) {
target_class = '#target-element-' + label;
code_text = $('#' + label).val();
$(target_class).text(code_text);
prism_repaint(target_class);
}
</script>
{% with prism_version="1.6.0" %}
{% block extra_css %}
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/{{ prism_version }}/themes/prism.min.css" rel="stylesheet" />
{% endblock extra_css %}
{% block extra_js %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/{{ prism_version }}/prism.min.js"></script>
{% endblock extra_js %}
<div class="{{ classname }}">
{% if help_text %}
<div class="object-help help">{{ help_text }}</div>
{% endif %}
<ul class="fields">
{% for child in children.values %}
<li{% if child.block.required %} class="required"{% endif %}>
{% if child.block.label %}
<label{% if child.id_for_label %} for="{{ child.id_for_label }}"{% endif %}>{{ child.block.label }}:</label>
{% endif %}
{{ child.render_form }}
</li>
{% if child.block.label == "Language" %}
{# As we loop through, load each language dialect #}
{% for language_choice, language_name in child.block.field.choices %}
{% if language_choice|length %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/{{ prism_version }}/components/prism-{{ language_choice }}.min.js"></script>
{% endif %}
{% endfor %}
<script>
$(document).ready(function() {
// Set initial language class on load
target_class = '#target-element-{{ child.id_for_label }}'.replace('language', 'code');
{% if child.id_for_label|length %}
$(target_class).addClass('language-' + $('#{{ child.id_for_label }}').val());
{% endif %}
// Change language being highlighted when dropdown is changed
$('#{{ child.id_for_label }}').bind('input propertychange', function() {
language_class = 'language-' + $('#{{ child.id_for_label }}').val();
$(target_class).removeClass().addClass(language_class);
prism_repaint(target_class);
});
});
</script>
{% endif %}
{% if child.block.label == "Code" %}
<script>
$(document).ready(function() {
populate_target_code('{{ child.id_for_label }}');
$('#{{ child.id_for_label }}').bind('input propertychange', function() {
populate_target_code('{{ child.id_for_label }}');
});
});
</script>
<li>
<pre><code id="target-element-{{ child.id_for_label }}"></code></pre>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endwith %}
我已验证 CSS 和 JS 已使用 extra_css
和 extra_js
模板块正确注入代码。我也尝试过使用“.getScript”函数,但没有成功。我绝不是 JavaScript 专家,因此我们将不胜感激。如果有帮助,可以在 GitHub 上找到该项目的完整源代码:
https://github.com/FlipperPA/wagtailcodeblock
任何跟踪解决此问题的帮助将不胜感激!感谢您的宝贵时间。
StreamField 块借用 Django 的 form media API 将 JS/CSS 文件与块相关联 - 这是导入 JS/CSS 库的推荐方式。您的代码将变为:
from django import forms
class CodeBlock(StructBlock):
"""
Code Highlighting Block
"""
# ...
@property
def media(self):
prism_version = "1.6.0"
return forms.Media(
js=["https://cdnjs.cloudflare.com/ajax/libs/prism/%s/prism.min.js" % prism_version],
css={'all': ["https://cdnjs.cloudflare.com/ajax/libs/prism/%s/themes/prism.min.css" % prism_version]}
)
以这种方式定义 JS/CSS 意味着导入将出现在任何 可能 包含您的块的编辑页面上,而不是仅在您的块时插入已添加。