【问题标题】:How do I use snippets in enlive?如何在 enlive 中使用片段?
【发布时间】:2013-01-04 01:56:08
【问题描述】:

我是一名 Rails 开发人员,开始涉足 Clojure。我正在尝试用 ERB 做一些非常简单的事情,但我一生都无法在 enlive 中弄清楚。

假设我在 layout.html 中有一个网站的简单布局文件:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>

我有这些 sn-ps,例如 header.html 和 footer.html 以及这个简单的路由。

(deftemplate layout "layout.html" [])

(defroutes home-routes
  (GET "/" [] layout))

我怎样才能做到这样,每当请求转到“/”时,它会转换布局并将页眉和页脚 sn-ps 插入其中?

【问题讨论】:

    标签: clojure templating compojure enlive


    【解决方案1】:

    enlive tutorial 中有很好的示例答案。

    警告。所有源文件链接似乎都已损坏。您需要在所有链接中的https://github.com/swannodette/ 之后插入enlive-tutorial/blob/master/,或者直接从教程项目中打开它们。

    【讨论】:

      【解决方案2】:

      defsn-p 仅匹配 html 的特定部分(这就是为什么它将选择器作为参数),并对其进行转换。 deftemplate 获取整个 html,并对其进行转换。另外,defsn-p 返回一个 Clojure 数据结构,而 deftemplates 返回一个字符串向量,所以 deftemplate 中通常使用 defsn-p。

      让您了解 sn-p(或选择器)返回的数据是什么样的:

      (enlive/html-snippet "<div id='foo'><p>Hello there</p></div>")
      ;=({:tag :div, :attrs {:id "foo"}, :content ({:tag :p, :attrs nil, :content ("Hello there")})})
      

      在你的情况下,你想要这样的东西:

      header.html:

      <div id="my-header-root">
      ...
      </div>
      

      Clojure 代码:

      (enlive/defsnippet header "path/to/header.html" [:#my-header-root] []
      identity)
      
      (enlive/defsnippet footer "path/to/footer.html" [enlive/root] []
      identity)
      
      (enlive/deftemplate layout "layout.html" [header footer]
      [:head] (enlive/content header)
      [:body] (enlive/append footer))
      
      (defroutes home-routes
        (GET "/" [] (layout (header) (footer))
      

      sn-ps 中使用的标识函数返回它的参数,在本例中是由 :#my-header-root 选择器选择的数据结构(我们不进行任何转换)。如果你想在 head.html 中包含所有内容,你可以使用 enlive 附带的根选择器步骤。

      您可以使用以下方式查看从 defsn-p 生成的 html:

      (print (apply str (enlive/emit* (my-snippet))))
      

      我也推荐教程:https://github.com/swannodette/enlive-tutorial/ 还有一篇由 Brian Marick 撰写的关于 defsn-p 和 deftemplate 宏如何工作的更多细节。

      最后一个提示,您可以使用 enlive 附带的 sniptest 宏来试验选择器和转换:

      (enlive/sniptest "<p>Replace me</p>"
      [:p] (enlive/content "Hello world!"))
      ;= "<p>Hello world!</p>"
      

      【讨论】:

      • 谢谢!对未来读者的更正。行 (enlive/defsn-p header "path/to/header.html" [:#my-header-root] identity) 应该在选择器之后有一个向量。所以应该是:(enlive/defsn-p header "path/to/header.html" [:#my-header-root] [] identity)。与页脚的 defsn-p 相同。
      • 啊,错过了那个。我已经相应地更新了示例。
      猜你喜欢
      • 2023-03-09
      • 2014-12-02
      • 2014-10-28
      • 2011-10-24
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多