2013-03-13 57 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