Есть ли способ использовать nunjucks для преобразования структуры DOM в другую? - PullRequest
0 голосов
/ 02 мая 2020

Я часто создаю веб-страницы из экспортированных файлов InDesign HTML. А в InDesign у меня есть некоторый контроль над атрибутом elements class, но изменить саму структуру DOM довольно сложно. И не всегда достаточно go с DOM, который он выводит, поэтому мне нужен способ преобразовать DOM.

Подход, который у меня был, состоял в том, чтобы запустить набор 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 или пользовательских тегов , Но если будет гораздо лучшее решение, я тоже приму это как ответ!

1 Ответ

0 голосов
/ 06 мая 2020

Хорошо, я решил это!

В Nunjucks можно обернуть немного html в тег {% call someMacro() %}. Таким образом, макрос someMacro() вызывается с бонусом: упакованный контент можно использовать внутри макроса с помощью метода caller().

Но caller() возвращает весь кусок HTML в виде строки и мне все еще нужен способ разобрать его и выбрать только те элементы, которые мне нужны. Для этого я использовал cheerio вместе с некоторыми пользовательскими глобальными значениями Nunjucks.

Поскольку в шаблонах Nunjucks невозможно запустить чистый javascript, в моей настройке gulp я определил псевдоним cheerio's 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.

...