Выполнить метод Ruby на всей странице в Middleman

На моем веб-сайте, созданном Middleman, мне нужно выполнить определенный код Ruby для содержимого всех страниц (шаблонов).

Например, если бы у меня был следующий помощник в моем config.rb:

def myexample(text)
    text.gsub("dog","cat")
end

И в моем test.html.haml:

= myexample("Some text about a dog.")

Мой предварительно просмотренный и сгенерированный /test.html будет выглядеть так:

Some text about a cat.

Однако я использую несколько разных способов вывода текста, который необходимо изменить, в первую очередь с помощью фильтра :markdown HAML, поэтому я бы предпочел не оборачивать все в помощник = myexample("Text").

Я хотел бы иметь возможность запускать код Ruby, который будет принимать содержимое всех страниц (предпочтительно) или сгенерированный вывод HTML (если первый вариант невозможен) в качестве аргумента, передаваемого такому помощнику.

В идеале этот код должен выполняться как в среде разработки, так и в среде сборки, но если это невозможно, достаточно сборки.

Возможно ли это сделать?

PS. В моем конкретном случае я использую сокращенную нотацию для ссылки на другие страницы, а затем использую регулярное выражение и eval(), чтобы заменить их относительными ссылки из файлов данных.


person Rafal    schedule 15.08.2017    source источник
comment
Есть ли причина, по которой вы не можете просто гарантировать, что HAML сгенерирует окончательный HTML, который вы ищете? То, что вы делаете, определенно нетрадиционно, и вы можете сделать это более сложным, чем нужно. Но я также знаю, что ваш реальный код намного сложнее, чем этот.   -  person Feliks Montez    schedule 15.08.2017
comment
Основная проблема здесь в том, что у меня есть более 100 применений фильтра :markdown HAML, который используется для обработки блочной уценки (несколько абзацев), 20% из которых включают ref.pageA ссылок. Мне удалось изменить свои части, поэтому теперь они обрабатываются вашим кодом из другого вопроса, но в этих :markdown фильтрах HAML все еще есть некоторые ссылки, которые необходимо оценить. Я не хочу менять все фильтры HAML на mymarkdown() хелпер, потому что это ухудшит читаемость, а хелпер, похоже, все равно не сможет принимать блочный ввод (несколько абзацев).   -  person Rafal    schedule 16.08.2017
comment
Если запуск кода на всей странице невозможен, единственным решением будет переместить все эти блоки под фильтром :markdown HAML в файл данных, а затем поместить их в шаблон с помощью mymarkdown. И тогда мне пришлось бы обернуть все оставшиеся 1-абзацные биты текста, которые также включают ссылки с помощником mymarkdown.   -  person Rafal    schedule 16.08.2017
comment
Итак, у вас есть несколько абзацев текста (в которых может быть уценка), связанных с каждой записью в ваших файлах данных? Тогда вы получаете доступ к этому тексту из файлов данных через шаблоны HAML?   -  person Feliks Montez    schedule 17.08.2017
comment
Вы когда-нибудь заставляли это работать?   -  person Feliks Montez    schedule 25.08.2017


Ответы (1)


ActionController::Base имеет метод render_to_string, который даст вам обычный HTML-вывод при рендеринге части или страницы, но в строковом формате. Это позволит вам получить визуализированный HTML-код и изменить его, прежде чем, наконец, отобразить его как встроенный шаблон.

В вашем контроллере:

rendered_html = render_to_string 'your_template_or_partial'
# do stuff to rendered_html
render inline: rendered_html.html_safe, layout: 'layouts/application'

Метод html_safe гарантирует, что Rails знает, что отображать это как HTML безопасно. Вы НЕ хотите делать это, если пользовательский ввод обрабатывается, и вы его не санировали!!!!

Если вы не хотите использовать макет при рендеринге, просто удалите аргумент :layout.

person Feliks Montez    schedule 16.08.2017
comment
Я бы рекомендовал использовать этот подход раньше в вашем коде. Вы можете немного упростить свою систему рендеринга, чтобы она не казалась такой хакерской, используя эту технику. Может быть что-то вроде: render_to_string ваш шаблон HAML. Запустите замены. Визуализируйте уценку с помощью Tilt. Затем визуализируйте свой (теперь встроенный) шаблон. - person Feliks Montez; 17.08.2017