是否有使用nunjucks的方法将DOM结构转换为另一个结构?

问题描述 投票:0回答:1

我经常从InDesign导出的HTML文件构建网页。在InDesign中,我可以控制元素class属性,但是更改DOM结构本身相当困难。而且它输出的DOM并不总是足够的,因此我需要一种转换DOM的方法。

我所采用的方法是在操纵up的实例上运行一组jquery命令,以强制性地调整DOM并将输出的HTML保存到文件中。它变得非常难以维护,很难从代码中分辨出预期的输入和输出。

因此,我正在尝试将nunjucks作为模板引擎来生成输出。但是AFAIK Nunjucks擅长打印以前定义的变量,但不提供任何工具来从HTML块中检索其输入]

我想编写一个带有选择器的模板/宏,这些选择器可以在输入中找到内容,有点像这样:

<section>
    <header>
        <h2>{% contentFrom(".section-header") %}</h2>
    </header>
    <main>
        {% contentFrom(".content") %}
    </main>
</section>

然后将我的输入包裹在一个nunjucks标记中,像这样

{% filter dont_know_yet_what_should_go_in_here }
    <p class="section-header">My_header_here</p>
    <p class="content">My_contents</p>
{% endfilter}

我想这可以通过nunjucks定制过滤器或定制标签来实现。但是,如果有更好的解决方案,我也将其作为答案!

javascript dom nunjucks templating-engine
1个回答
0
投票
在Nunjucks中,可以将一些html包装在{% call someMacro() %}标签中。这样,someMacro()宏将获得额外奖励:包装的内容可通过caller()方法在宏内部使用。

但是caller()将整个HTML块作为字符串返回,我仍然需要一种方法来解析它并仅选择我需要的元素。为此,我使用了cheerio以及一些Nunjucks自定义全局变量。

由于无法在Nunjucks模板内运行纯JavaScript,因此在我的gulp设置中,我为cheerio的load()方法定义了一个别名,并通过全局变量(通常称为$)将其传递给我的nunjucks环境:

const cheerio = require('cheerio') function cheer(html, selector) { var a = cheerio.load(html.toString()) return a(selector) } var manageEnvironment = function(environment) { environment.addGlobal('$', cheer); } // then pass manageEnvironment to Nunjucks initializer function

然后,在我的模板中,将caller()分配给一个变量,只是为了使其不那么冗长,然后我可以使用我的函数来选择和修改输入DOM,然后再将其插入到我的模板中:
{% macro myComponent() %} {% set a = caller() %} {# Assigned caller to a shorter variable because it'll be repeated a few times #} <section> <header> <h1>{{ $(a, '.box-title').html() }}</h1> </header> <main> {{ $(a, '._obj_box *:not(.box-title)').html() }} </main> <footer style="border: 2px solid red;"> {{ $(a, ".see_more-title").html() | urlize | safe }} </footer> </section> {% endmacro %}

我不知道为什么,但是Nunjucks总是逃避了从$()方法返回的HTML,即使我使用了safe过滤器也是如此。由于我拥有完全受控的环境,因此关闭整个Nunjucks渲染的自动转义会更容易。

© www.soinside.com 2019 - 2024. All rights reserved.