4

私は clojure と Web 開発スタックが初めてです。enlive を使用して HTML テンプレートに値を設定しようとしています:

(en/deftemplate project-main-page
  (en/xml-resource "project-main.html")
  [id]
  [:#project-name] (en/content (str "Name: " ((get-project id) :name)))
  [:#project-desc] (en/content (str "Desc: " ((get-project id) :desc))))

これは、2 つの HTML 要素を設定するのに問題なく機能しますが、関数を繰り返し呼び出す必要がありますget-project。現時点では、これはローカル マップから読み取るだけですが、最終的には外部ストレージへのアクセスが必要になるため、この関数で 1 回だけ実行することをお勧めします。

私は使用することを考えていましたlet:

(en/deftemplate project-main-page
  (en/xml-resource "project-main.html")
  [id]
  (let [project (get-project id)]
    [:#project-name] (en/content (str "Name: " (project :name)))
    [:#project-desc] (en/content (str "Desc: " (project :desc)))))

ただし、これは description 要素にのみ影響し、name フォームは無視されます。

内でローカル変数をバインドする最良の方法は何deftemplateですか?

4

2 に答える 2

2

あなたが達成しようとしていることを私が理解していれば; enlive が提供する変換マクロを使用することもできます。

(defn main-page [{:keys [name desc] :as project}]
 (en/transformation
   [:#project-name] (en/content (str "Name: " name)
   [:#project-desc] (en/content (str "Desc: " desc))))


(en/deftemplate project-main-page
  (en/xml-resource "project-main.html")
  [id]
   (main-page (get-project id)))

コードはテストされていませんが、必要なことを行う別の方法を伝えてくれることを願っています

于 2012-08-14T08:04:14.483 に答える
1

Enlive のdeftemplateマクロは、args ベクトルの後に一連のタグ/コンテンツのペアが必要です (args ベクトルは[id]例にあります)。マクロはフォームを想定していないため、単に aletをそこに貼り付けることはできません。そのため、マクロがletスプライシングを行うと、すべてが台無しになり、上記の動作が発生します。

deftemplateこれを修正する 1 つの方法は、args ベクトルの識別子を使用してバインディング定義を許可する独自のマクロを作成することです。例:

(alt/deftemplate project-main-page
  (en/xml-resource "project-main.html")
  [id]
  [project (get-project id)]
  [:#project-name] (en/content (str "Name: " (project :name)))
  [:#project-desc] (en/content (str "Desc: " (project :desc))))

マクロは、を使用deftemplateする単純なラッパーであり、これはおそらく変更を挿入する必要がある場所です。templatesnippet*

(defmacro snippet* [nodes args & forms]
  `(let [nodes# (map annotate ~nodes)]
     (fn ~args
       ; You could add let bindings here since args are in scope
       (doall (flatmap (transformation ~@forms) nodes#)))))

もう 1 つのオプション (ライブラリ コードをいじる必要がないため、より簡単かもしれません) は、get-project結果をキャッシュするために、関数に一定レベルの間接性を追加することです。core.cacheライブラリを試すことができます。

于 2012-08-13T04:11:21.923 に答える