2013-03-13 58 views
7

我对Clojure和Compojure Web开发相对较新。我在构建的玩具示例中注意到的第一个问题是HTML模板。我想要支持Rails中的partials或Django使用的模板框架。使用Hiccup和Compojure编写模板

目前我有:

(defn index-page [] 
(html5 
    [:head 
     [:title "Home | Compojure Docs"] 
     (include-css "/css/bootstrap.min.css") 
     (include-css "/css/bootstrap-responsive.min.css")] 
    [:body 
     [:div {:class "container-fluid"} 
      [:div {:class "row-fluid"} 
       [:div {:class "span2 menu"}] 
       [:div {:class "span10 content"} 
        [:h1 "Compojure Docs"] 
        [:ul 
         [:li 
          [:a {:href "/getting-started"} "Getting Started"]] 
         [:li 
          [:a {:href "/routes-in-detail"} "Routes in Detail"]] 
         [:li 
          [:a {:href "/destructuring-syntax"} "Destructuring Syntax"]] 
         [:li 
          [:a {:href "/nesting-routes"} "Nesting Routes"]] 
         [:li 
          [:a {:href "/api-documentation"} "API Documentation"]] 
         [:li 
          [:a {:href "/paas-platforms"} "PaaS Platforms"]] 
         [:li 
          [:a {:href "/example-project"} "Example Project"]] 
         [:li 
          [:a {:href "/example-project-on-cloudbees"} "Example Project on CloudBees"]] 
         [:li 
          [:a {:href "/interactive-development-with-ring"} "Interactive Development with Ring"]] 
         [:li 
          [:a {:href "/emacs-indentation"} "Emacs Indentation"]] 
         [:li 
          [:a {:href "/sessions"} "Sessions"]] 
         [:li 
          [:a {:href "/common-problems"} "Common Problems"]]] 
        (include-js "/js/jquery-1.9.1.min.js") 
        (include-js "/js/bootstrap.min.js")]]]])) 

(defn routes-in-detail [] 
(html5 
    [:head 
     [:title "Routes in Detail | Compojure Docs"] 
     (include-css "/css/style.css")] 
    [:body 
     [:h1 "Routes in Detail"]])) 

有我不重复代码的好办法?我希望HEAD标签中的东西可以放在它自己的模板文件或函数中,然后可以随身携带。例如,我想将它包含在“详细路线”功能中。我看过Enlive,但我不确定如何使用Hiccup。任何想法在这里的最佳实践将不胜感激。

回答

11

你可以拉标记的部分分成不同的增值经销商:

(def head 
    [:head 
    [:title "Home | Compojure Docs"] 
    (include-css "/css/bootstrap.min.css") 
    ... ]) 

(defn routes-in-detail [] 
    (html5 
    head 
    [:body 
     ... ])) 

如果您需要您的代码段/分取的参数,你可以把它变成一个函数来代替,例如:

(defn head [title] 
    [:head 
    [:title title] 
    (include-css "/css/bootstrap.min.css") 
    ... ]) 

(defn routes-in-detail [] 
    (html5 
    (head "Routes in detail") 
    ...)) 

有时您会希望您的“片段”由多个顶级元素组成,而不是单个元素。在这种情况下,你可以在一个列表将它们包装 - 打嗝会内联展开:

(defn head-contents [title] 
    (list [:title title] 
     (include-css "/css/bootstrap.min.css") 
     ...))) 

(defn routes-in-detail [] 
    (html5 
    [:head (head-contents "Routes in detail")] 
    [:body ... ])) 

一旦你意识到一个事实,即打嗝标记是做出来的纯Clojure的数据结构,你会发现,操纵/构建它功能简单灵活。

+0

谢谢你的详细解答。这正是我所期待的。 – 2013-03-13 16:20:51