clojure - 如何在 Mustache 模板引擎中实现自省(introspection)?

标签 clojure mustache

(def template "{{name}}.{{surname}}
  {{#data}}
    * {{.}}
  {{/data}}")

(introspect template) => {:name "" :surname "" :data []}

是否有内省(introspection)实现?

最佳答案

如果问题是如何构建内省(introspection)函数,instaparse是一种方法:

(require '[instaparse.core :as insta])

(def parse
  (insta/parser
    "<moustache> = (tagged-block / word / sp)*
     <tagged-block> = comment | section | var
     comment = <tag-open> <'!'> (word | sp)* <tag-close>
     section = section-block-open (current-item / var / comment / word / sp)* <section-block-close>
     <section-block-open> = <tag-open> <'#'> name <tag-close>
     section-block-close = tag-open '/' name tag-close
     var = <tag-open> name <tag-close>
     current-item  = <tag-open> <'.'> <tag-close>
     <word> = #'[^\\s{}]+'
     <sp> = #'[\\s]+' 
     name = #'[^\\s{}]+'
     tag-open = '{{'
     tag-close = '}}'"))

(def template "{{name}}.{{surname}}
  {{#data}}
  * {{.}}
  {{/data}}")

(parse template) ;=> ([:var [:name "name"]] "." [:var [:name "surname"]] "\n  " [:var [:name "#data"]] "\n  " "*" " " [:var [:name "."]] "\n  " [:var [:name "/data"]])

(defn introspect [parsed]
  (->> (tree-seq sequential? seq parsed)
       (filter sequential?)
       (filter #(#{:var :section} (first %)))
       (map (juxt first (comp keyword last second)))
       (map #(case (first %)
               :var [(second %) ""]
               :section [(second %) []]))
       (into {})))

(assert (= {:name "" :surname "" :data []}
           (introspect (parse template))))

我添加了对注释的支持,其他 mustache 结构应该很容易添加:

(parse "Hello {{people}}!! {{! people could be the world!!}}")
;=> ("Hello" " " [:var [:name "people"]] "!!" " " [:comment " " "people" " " "could" " " "be" " " "the" " " "world!!"])

它没有涵盖整个 Mustache 语法,但我认为这是一个好的开始。

关于clojure - 如何在 Mustache 模板引擎中实现自省(introspection)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31564275/

相关文章:

clojure - clojure的所有特殊形式是什么?

functional-programming - 帮助在 Clojure 中设计一个小的单元测试宏

Clojure:列表的最大值

clojure - 在 ClojureScript Figwheel 中访问 defrecord 方法

templating - mustache /霍根 JS : Is it possible to reference parent tags within a list?

python - 如何在 Pystache 中使用 '.' 渲染键?

clojure - 学习 Clojure : NullPointerException on triplicate

javascript - 无法实现 mustache js 来显示信息

javascript - Handlebars.js 使用 ../引用父上下文

javascript - 将 javascript 应用到 Mustache 创建的对象