Как мне избежать кода шаблона EJS в файле node.js для оценки на стороне клиента?

Я использую node.js/ejs на стороне сервера и backbone.js на стороне клиента. Как на стороне сервера, так и на стороне клиента используется один и тот же стиль шаблонов. Таким образом, проблема в том, что если я помещаю код шаблона, предназначенный для клиента, в шаблон, он все равно анализируется на стороне сервера.

Если узнал, что что-то вроде этого работает:

<%- "<%= done ? 'done' : '' %\>" %>

Тем не менее, IMHO, это ухудшает код таким образом, что делает весь смысл использования шаблонов бесполезным.

Как бы вы подошли к этому?

Есть ли способ определить блоки кода внутри EJS-шаблонов, которые не анализируются как тег {literal}, используемый в других языках шаблонов?

Обновление: на данный момент я использую _.templateSettings магистрали, чтобы использовать различные разделители на стороне клиента.

Обновление: вот аналогичное решение в контексте JSP: Шаблоны Underscore.js в JSP

4 ответа

Решение

То, как я справился с этим, - переопределить открывающий и закрывающий теги на узле, чтобы 2 экземпляра ejs выглядели для разных тегов.

На узле вы можете перейти в настройках

{open:'<%',close:'%>'}

В моем случае я использую <% и <@ для двух моих версий. Затем в шаблоне ejs узла у меня есть что-то вроде этого (где имя взято из магистрали и EveryAuth, очевидно, из узла):

<% if(everyauth.loggedIn) %><h1><@= name @></h1><% } %>

Я предполагаю, что вопрос можно было бы прочитать следующим образом, потому что это была эта ветка, которую Google предоставил мне при первой ссылке:

"Как я могу избежать тега разделителя кода шаблона EJS только для ограниченного количества элементов?"

tl;dr:

Использовать <%# %> чтобы сломать исходный код синтаксического анализа (например, <<%# %>%= done ? 'done' : '' %<%# %>> выполнит следующий неанализируемый код <%= done ? 'done' : '' %>)

Длинное объяснение

Представьте себе случай, который я решаю изменить % по ? с помощью { delimiter: '?' } вариант (это может иметь место здесь, потому что мы не хотим использовать тот же Backbone.js).

Отлично, это решает вашу проблему. Представьте, что позже по какой-то причине вы используете свою систему шаблонов для генерации XML. Этот XML будет начинаться с<?xml version="1.0" encoding="UTF-8"?>.

Вы снова столкнетесь с той же проблемой. Что? Вы снова будете менять разделитель? И после этого ты снова изменишься? и т. д. Нет, для пунктуального экранирования мы должны просто сказать: "Не анализируйте эту часть документа как EJS".

Таким образом, уловка состоит в том, чтобы избежать понимания EJS, что это парсер разделителей EJS. Так что избегайте этого (в нашем текущем случае) parse<? (или <% в оригинальном футляре).

Итак, просто добавив <?# ?> чтобы нарушить синтаксический анализ, вы ничего не добавите (# элемент предназначен для комментария EJS), и вы избежите понимания парсером <<?# ?>?xml version="1.0" encoding="UTF-8"?<?# ?>>. На выходе будет<?xml version="1.0" encoding="UTF-8"?>

Вывод

В пунктуальность необходимости избежать EJS синтаксического анализа, вы можете просто обмануть анализатор, чтобы произвести вывод, что нужно с помощью<%# %> в качестве прерывателя тегов-разделителей.

Наверняка, возможно, в вашем случае вы можете просто использовать отмеченный ответ, потому что вы будете использовать тег EJS во многих случаях.

Я использую backbone.layout.manager как на стороне клиента, так и на стороне сервера, потому что я хочу, чтобы мои шаблоны были одинаковыми.

Способ, которым я решил проблему с разделителями шаблонов, состоял в том, чтобы отобразить страницу на стороне сервера, а затем внедрить необработанные базовые шаблоны.

С новыми ejs вы можете добавить пользовательский разделитель на стороне клиента:

https://github.com/mde/ejs

например:

Пользовательские разделители могут применяться для каждого шаблона или глобально:

var ejs = require('ejs'),
    users = ['geddy', 'neil', 'alex'];

// Just one template
ejs.render('<?= users.join(" | "); ?>', {users: users}, {delimiter: '?'});
// => 'geddy | neil | alex'

// Or globally
ejs.delimiter = '$';
ejs.render('<$= users.join(" | "); $>', {users: users});
// => 'geddy | neil | alex'

Что ж, сейчас я подхожу к этому, используя require.js с текстовым плагином; это позволяет мне включать шаблоны с использованием AJAX во время разработки и собирать их все в оптимизированный / минимизированный пакет файлов во время развертывания.

Конечно, если вы не используете require.js для управления зависимостями остальной части вашего JS-кода, это работает не так хорошо, но я больше не могу делать javascript dev без require.js теперь, когда я ' Я все равно привык к этому.

Альтернативно, могут быть другие подобные технологии, которые вы могли бы использовать для решения той же проблемы.

Другие вопросы по тегам