Некоторые страницы моего приложения будут иметь собственные включения js/css, поэтому мне интересно, как я могу добавить эти ресурсы в раздел заголовка html-документа с помощью Enlive. Я нашел преобразователь «добавление», но нет «html-добавления» без автоматического экранирования. Или как правильно это сделать?
Enlive шаблоны – добавить в раздел head
Ответы (4)
Другие ответы могут предшествовать появлению помощников в стиле икоты. Ответ взят и расширен из: Enlive templating - добавление CSS включает в ‹head›.
(require '[net.cgrand.enlive-html :as html])
Функции для создания узлов HTML (гораздо НАМНОГО проще):
(defn include-js [src]
(first (html/html [:script {:src src}])))
(defn include-css [href]
(first (html/html [:link {:href href :rel "stylesheet"}])))
Пример использования:
;; Example templates/base.html file
<html>
<head>
</head>
<body>
</body>
</html>
(def jquery "http://code.jquery.com/jquery-1.11.0.min.js") ; links work as well
(html/deftemplate home-page "templates/base.html"
[]
[:head] (html/append (map include-css ["css/some_file" "css/index.css"]))
[:head] (html/append (map include-js [jquery "js/index.js"])))
Убедитесь, что он создает правильный HTML:
(print (apply str (home-page)))
;; newlines added by hand for clarity
=> <html>
<head>
<link href="css/some_file" rel="stylesheet" />
<link href="css/index.css" rel="stylesheet" />
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script src="js/index.js"></script>
</head>
<body>
</body>
</html>
nil
В Enlive вы можете писать шаблоны на простом HTML< /а>:
Затем просто замените содержимое с помощью правил шаблона enlive:
(deftemplate microblog-template
"net/cgrand/enlive_html/example.html"
[title posts]
[:title] (content title)
[:h1] (content title)
[:div.no-msg] #(when (empty? posts) %)
[:div.post] #(for [{:keys [title body]} posts]
(at %
[:h2 :a] (content title)
[:p] (content body)))
[[:a (attr? :href)]] (set-attr :title "it's a link"))
Наконец, просто верните результат с помощью:
(apply str (microblog-template "Hello user!"
[{:title "post #1"
:body "hello with dangerous chars: <>&"}
{:title "post #2"
:body "dolor ipsum"}]))
Итак, в первом шаблоне HTML просто пропишите необходимые импорты для файлов javascript и CSS. Обратите внимание, что вы также можете определить повторно используемые подшаблоны, чтобы оставаться СУХИМ.
Итак, я нашел способ добавить медиа-ресурсы для каждого шаблона. В моем базовом шаблоне у меня есть не-html тег, и я в файле шаблона для страницы есть такой раздел «больше медиа» с необходимыми материалами, и фрагмент вставит его в базовый шаблон с (контентом), и, наконец, я это сделаю ( развернуть). Немного сложно, но работает, и в коде clojure нет html-данных.
Я думаю, что нашел решение, хотя я далек от того, чтобы быть профессионалом Enlive (только начал пару недель назад), поэтому, пожалуйста, потерпите меня.
Следующее преобразование предполагает, что link-includes
является последовательностью <link rel="stylesheet" href="/css/this-page-custom.css">
(с соответствующими значениями).
[:head] (html/append
(for [link link-includes]
(-> link
html/html-snippet)))
Вкратце: я начал с совершенно нового проекта, используя lein2
.
jacek:~/sandbox
$ lein2 new stackoverflow/add-to-head-section
Generating a project called stackoverflow/add-to-head-section based on the 'default' template.
To see other templates (app, lein plugin, etc), try `lein help new`.
И добавил [enlive "1.0.1"]
к project.clj
(плюс пространство имен :main
, чтобы lein2 repl
начиналось в пространстве имен):
jacek:~/sandbox/add-to-head-section
$ cat project.clj
(defproject stackoverflow/add-to-head-section "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.4.0"]
[enlive "1.0.1"]]
:main stackoverflow.add-to-head-section.core)
Я позаимствовал простой HTML-шаблон из Twitter Bootstrap Getting Started и сохранил это в src/stackoverflow/add_to_head_section/index.html
.
jacek:~/sandbox/add-to-head-section
$ cat src/stackoverflow/add_to_head_section/index.html
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap 101 Template</title>
</head>
<body>
<h1>Hello, world!</h1>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</body>
</html>
Последней головоломкой было написать сценарий Enlive в src/stackoverflow/add_to_head_section/core.clj
следующим образом:
(ns stackoverflow.add-to-head-section.core
(:require [net.cgrand.enlive-html :as html]))
(html/deftemplate index-html "stackoverflow/add_to_head_section/index.html"
[link-includes]
[:head] (html/append
(for [link link-includes]
(-> link
html/html-snippet))))
(defn render-index-html []
(index-html ["<link rel='stylesheet' href='/css/this-page-custom.css'>"
"<link rel='stylesheet' href='/css/another-custom.css'>"]))
(print (apply str (render-index-html)))
Как только lein2 repl
истекает, срабатывает последняя функция print
и выводит ожидаемый результат.
Возможно, я использовал sniptest
от Enlive, но, как я уже говорил, мне еще предстоит к нему привыкнуть.