2017-04-22 81 views
0

我正在爲W stream流場創建一個塊,它使用Prism JS庫顯示實時代碼語法高亮顯示。它部分工作;當我在的地方選擇的語言和代碼現有頁面上,代碼顯示出來,強調預期:W stream流場塊:將jQuery注入W Admin管理員

It works for already populated code.

然而,當我嘗試用新的代碼塊創建一個新的鶺鴒頁,我得到一個JavaScript錯誤:

JavaScript error when starting a new page with a new code block.

好像圖書館正在對延遲加載時沒有內容有它突出。我已經嘗試了$(document).ready$(window).load,但這是一種不同的情況,因爲當您單擊「代碼段」按鈕時,包含Prism庫的模板將被動態加載。下面是我得到錯誤的分機:

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) 

下面是我使用的鶺鴒塊Django的鶺鴒代碼:

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' 

...和表單模板的代碼該鶺鴒管理員:

<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_cssextra_js模板塊的代碼。我也嘗試過使用「.getScript」函數,但沒有任何運氣。我絕不是JavaScript專家,所以任何幫助,將不勝感激。該項目的整個源可以在GitHub上找到,如果幫助:

https://github.com/FlipperPA/wagtailcodeblock

任何幫助跟蹤解決這個將不勝感激!謝謝你的時間。

回答

4

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意味着,進口將出現在任何編輯頁面上可能包括你的塊,而不是在增加你的塊剛剛被插入。