2013-03-13 23 views
7

Tôi tương đối mới đối với phát triển web Clojure và Compojure. Vấn đề đầu tiên mà tôi đã nhận thấy trong ví dụ đồ chơi mà tôi đang xây dựng là việc tạo mẫu HTML. Tôi muốn có hỗ trợ cho một cái gì đó như partials trong Rails, hoặc khuôn khổ templating rằng Django sử dụng.Soạn thảo các mẫu với Hiccup và Compojure

Hiện nay tôi có:

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

Có cách nào tốt cho tôi không để lặp lại mã? Tôi muốn nội dung trong thẻ HEAD nằm trong tệp hoặc chức năng mẫu của riêng nó và sau đó có thể bao gồm nó khi tôi đi. Ví dụ, tôi muốn đưa nó vào chức năng 'route-in-detail'. Tôi đã nhìn vào Enlive, nhưng tôi không chắc chắn làm thế nào để sử dụng với Hiccup. Bất kỳ suy nghĩ về thực tiễn tốt nhất ở đây sẽ được đánh giá cao.

Trả lời

11

Bạn có thể kéo các bộ phận của markup ra vars riêng biệt:

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

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

Nếu bạn cần đoạn mã của bạn/phần để có các thông số, bạn có thể làm cho nó thành một chức năng thay vào đó, ví dụ:

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

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

Đôi khi bạn sẽ muốn "đoạn mã" của mình bao gồm nhiều phần tử cấp cao nhất thay vì một phần tử duy nhất. Trong trường hợp đó bạn có thể bọc chúng trong một danh sách - nấc cục sẽ mở rộng nó 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 ... ])) 

Một khi bạn nhận ra thực tế là đánh dấu nấc cục được làm từ đồng bằng cấu trúc dữ liệu clojure, bạn sẽ tìm thấy chế tác mà/xây dựng nó với chức năng dễ dàng và linh hoạt.

+0

Cảm ơn bạn đã trả lời chi tiết. Điều này thật đúng với gì mà tôi đã tìm kiếm. –

0

Có một thư viện khuôn mẫu mới gọi là clabango mà được mô hình hóa sau khi thư viện khuôn mẫu Django, nó có thể là những gì bạn đang tìm kiếm sau: https://github.com/danlarkin/clabango

Các vấn đề liên quan