2013-03-13 9 views
7

Jestem stosunkowo nowy w tworzeniu stron internetowych Clojure i Compojure. Pierwszym problemem, który zauważyłem w przykładzie zabawkowym, który buduję, jest szablon HTML. Chciałbym mieć wsparcie dla czegoś takiego jak częściowe w Railsach lub w szablonowej strukturze, z której korzysta Django.Komponowanie szablonów z Hiccup i Compojure

Obecnie mam:

(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"]])) 

Czy istnieje dobry sposób dla mnie nie do powtórzenia kodu? Chciałbym, aby rzeczy w tagu HEAD były w jego własnym pliku szablonu lub funkcji, a następnie móc je uwzględnić w trakcie pracy. Na przykład chciałbym włączyć go do funkcji "trasy w szczegółach". Spojrzałem na Enlive, ale nie jestem pewien jak tego użyć z Hiccupem. Należy docenić wszelkie przemyślenia na temat najlepszych praktyk.

Odpowiedz

11

Można wyciągnąć części znaczników się na oddzielne Vars:

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

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

Jeśli potrzebujesz fragment/częściowe podjąć parametrów, można uczynić go funkcji zamiast, na przykład:

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

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

Czasami chcesz, aby Twój "fragment" składał się z wielu elementów najwyższego poziomu, a nie z jednego. W takim przypadku można owinąć je w liście - czkawka będzie go rozwinąć inline:

(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 ... ])) 

Kiedy zdajesz sobie sprawę fakt, że czkawka znaczników jest wykonany z prostych struktur danych clojure, przekonasz się że manipulowanie/go budować z funkcjami jest łatwe i elastyczne.

+0

Dziękuję za szczegółową odpowiedź. Właśnie tego szukałem. –