Enlive шаблоны – добавить в раздел head

Некоторые страницы моего приложения будут иметь собственные включения js/css, поэтому мне интересно, как я могу добавить эти ресурсы в раздел заголовка html-документа с помощью Enlive. Я нашел преобразователь «добавление», но нет «html-добавления» без автоматического экранирования. Или как правильно это сделать?


person Dmitry Stropalov    schedule 02.04.2012    source источник
comment
У вас есть включение в виде большого двоичного объекта HTML-текста или набора URL-адресов или чего-то еще? О, и html-контент оооооочень медленный.   -  person cgrand    schedule 02.04.2012
comment
Я просто хочу добавить серию ‹link rel=stylesheet href=/css/this-page-custom.css› и js. Я хочу определить их для каждой страницы/шаблона и использовать при необходимости. Например, в Play! framework Я использую заполнитель moreScripts в базовом шаблоне, а затем могу добавить любой сценарий/стиль в производные представления (например: stackoverflow.com/questions/5276075/).   -  person Dmitry Stropalov    schedule 02.04.2012


Ответы (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
person deadghost    schedule 30.01.2014

В 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. Обратите внимание, что вы также можете определить повторно используемые подшаблоны, чтобы оставаться СУХИМ.

person Nicolas Modrzyk    schedule 02.04.2012
comment
Да, я знаю об этом, и я могу изменить контент для тега title, потому что я могу использовать для него селектор, но мне нужно добавить не контент, а узлы к родительскому узлу. - person Dmitry Stropalov; 02.04.2012

Итак, я нашел способ добавить медиа-ресурсы для каждого шаблона. В моем базовом шаблоне у меня есть не-html тег, и я в файле шаблона для страницы есть такой раздел «больше медиа» с необходимыми материалами, и фрагмент вставит его в базовый шаблон с (контентом), и, наконец, я это сделаю ( развернуть). Немного сложно, но работает, и в коде clojure нет html-данных.

person Dmitry Stropalov    schedule 04.04.2012

Я думаю, что нашел решение, хотя я далек от того, чтобы быть профессионалом 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, но, как я уже говорил, мне еще предстоит к нему привыкнуть.

person Jacek Laskowski    schedule 14.01.2013