如何在Haml中包含内联JavaScript?

129

我该如何在Haml中编写类似这样的内容以包含在模板中?

<script>
$(document).ready( function() {
  $('body').addClass( 'test' );
} );
</script>
4个回答

257

29

你可以像Chris Chalmers在他的回答中所做的那样,但是你必须确保HAML不解析JavaScript。当你需要使用不同于text/javascript的类型时,这种方法实际上很有用,这正是我需要为MathJax做的。

你可以使用plain过滤器来防止HAML解析脚本并抛出非法嵌套错误:

%script{type: "text/x-mathjax-config"}
  :plain
    MathJax.Hub.Config({
      tex2jax: {
        inlineMath: [["$","$"],["\\(","\\)"]]
      }
    });

1
:plain过滤器在解决JavaScript模板问题方面非常有用。谢谢!我正在使用fileupload-jquery(https://blueimp.github.io/jQuery-File-Upload/),其中包含haml中的js模板,只有:plain过滤器有效!更多细节,请阅读我的答案。 - karl li

19

所以我尝试了上面的 :javascript,它有效 :) 但是 HAML 将生成的代码包装在 CDATA 中,如下所示:

<script type="text/javascript">
  //<![CDATA[
    $(document).ready( function() {
       $('body').addClass( 'test' );
    } );
  //]]>
</script>
以下的 HAML 代码生成通常用于包含(例如)Typekit 或 Google Analytics 代码的 <script> 标签。
 %script{:type=>"text/javascript"}
  //your code goes here - dont forget the indent!

Haml 没有为我添加 CDATA,如果 JavaScript 中存在不规则缩进,则 %script 对我也没有起作用。 - agmin
这个不起作用,抛出了一个非法嵌套在纯文本中的异常。 - Marco Prins
如果您需要向<script>标签添加属性,例如id(原问题中有提到),那么这种方法效果更好。我正在使用haml 4.0.7——您可以在haml选项中关闭cdata包装器(--cdata),尽管我认为这并不重要。 - Maciek Rek

2

我在Haml中使用fileupload-jquery。以下是原始的js代码:

<!-- The template to display files available for download -->
<script id="template-download" type="text/x-tmpl">
  {% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
      {% if (file.error) { %}
        <td></td>
        <td class="name"><span>{%=file.name%}</span></td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
        {% } else { %}
        <td class="preview">{% if (file.thumbnail_url) { %}
          <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
          {% } %}</td>
        <td class="name">
          <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
        </td>
        <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
        <td colspan="2"></td>
        {% } %}
      <td class="delete">
        <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
          <i class="icon-trash icon-white"></i>
          <span>{%=locale.fileupload.destroy%}</span>
        </button>
        <input type="checkbox" name="delete" value="1">
      </td>
    </tr>
    {% } %}
</script>

一开始我使用了:cdata(从html2haml转换),但它不能正常工作(删除按钮无法在回调中删除相关组件)。

<script id='template-download' type='text/x-tmpl'>
      <![CDATA[
          {% for (var i=0, file; file=o.files[i]; i++) { %}
          <tr class="template-download fade">
          {% if (file.error) { %}
          <td></td>
          <td class="name"><span>{%=file.name%}</span></td>
          <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
          <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
          {% } else { %}
          <td class="preview">{% if (file.thumbnail_url) { %}
          <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
          {% } %}</td>
          <td class="name">
          <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
          </td>
          <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
          <td colspan="2"></td>
          {% } %}
          <td class="delete">
          <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
          <i class="icon-trash icon-white"></i>
          <span>{%=locale.fileupload.destroy%}</span>
          </button>
          <input type="checkbox" name="delete" value="1">
          </td>
          </tr>
          {% } %}
      ]]>
    </script>

所以我使用:plain过滤器:

%script#template-download{:type => "text/x-tmpl"}
  :plain
    {% for (var i=0, file; file=o.files[i]; i++) { %}
    <tr class="template-download fade">
    {% if (file.error) { %}
    <td></td>
    <td class="name"><span>{%=file.name%}</span></td>
    <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
    <td class="error" colspan="2"><span class="label label-important">{%=locale.fileupload.error%}</span> {%=locale.fileupload.errors[file.error] || file.error%}</td>
    {% } else { %}
    <td class="preview">{% if (file.thumbnail_url) { %}
    <a href="{%=file.url%}" title="{%=file.name%}" rel="gallery" download="{%=file.name%}"><img src="{%=file.thumbnail_url%}"></a>
    {% } %}</td>
    <td class="name">
    <a href="{%=file.url%}" title="{%=file.name%}" rel="{%=file.thumbnail_url&&'gallery'%}" download="{%=file.name%}">{%=file.name%}</a>
    </td>
    <td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
    <td colspan="2"></td>
    {% } %}
    <td class="delete">
    <button class="btn btn-danger" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}">
    <i class="icon-trash icon-white"></i>
    <span>{%=locale.fileupload.destroy%}</span>
    </button>
    <input type="checkbox" name="delete" value="1">
    </td>
    </tr>
    {% } %}

转换后的结果与原始内容完全相同。
因此,在这种情况下,使用:plain过滤器符合我的需求。

:plain不解析已过滤的文本。 对于没有HTML标记的大块文本非常有用,当您不希望以.或-开头的行被解析时使用。

请参考haml.info了解详细信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接