我的应用程序的某些页面将包含它自己的 js/css,所以我想知道如何使用 Enlive 将这些资源添加到 html 文档的 head 部分。我找到了“附加”转换器,但没有自动转义就没有“html-append”。或者有什么合适的方法来做到这一点?
4 回答
其他答案可能早于激活打嗝式助手。答案取自并扩展自:Enlive 模板 - 添加 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编写模板:
然后只需使用激活模板规则交换内容:
(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 模板中,只需为 javascripts 和 CSS 文件编写必要的导入。请注意,您还可以定义可重复使用的子模板以保持 DRY。
因此,我找到了一种为每个模板添加媒体资源的方法。在我的基本模板中,我有非 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)))
tl;dr:我从一个全新的项目开始,使用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)
我从Twitter Bootstrap 的 Getting Started中借用了一个简单的 HTML 模板,并将其保存在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
函数就会启动并打印预期的结果。
我可能一直在使用 Enlive 的sniptest
,但正如我所提到的,我还没有习惯它。