首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有条件地生成Hiccup结构?

如何有条件地生成Hiccup结构?
EN

Stack Overflow用户
提问于 2021-06-03 09:18:31
回答 2查看 199关注 0票数 0

我有一堆描述地点的地图:

代码语言:javascript
复制
 (def pizzeria
  {
   :LocationId "pizzeria"
   :Desc       "Pizzeria where Timur works"
   :Address    "Vorgartenstraße 126, 1020 Wien"
   :Comment    ""
   })

(def dancing-school
  {
   :LocationId "dancing-school"
   :Desc       "Dancing school"
   :Comment    "4th district"
   })

这些地图中有些有:Comment,有些则没有。

我想要创建一个Clojure函数,除其他外,如果它存在,它会将注释输出到HTML。

我写了这个函数:

代码语言:javascript
复制
(defn render-location-details
  [cur-location]
  (let [
        desc (get cur-location :Desc)
        address (get cur-location :Address)
        comment (get cur-location :Comment)
        address-title [:h4 "Address"]
        address-body [:p address]
        comment-hiccup [
                        (if (clojure.string/blank? comment)
                          nil
                          [:div
                           [:h4 "Comment"]
                           [:p comment]
                           ])
                        ]
        ]
    [:h3 desc
     address-title
     address-body
     comment-hiccup
     ]
    )
  )

如果运行使用此函数的代码,则会得到错误。

代码语言:javascript
复制
Execution error (IllegalArgumentException) at
hiccup.compiler/normalize-element (compiler.clj:59).
 is not a valid element name.

如果我将comment-hiccup更改为nil,错误将消失。

如何使用将数据有条件地输出到HTML?

注意:我是Clojure的新手,所以如果我的方法完全错误,请告诉并展示如何正确地做。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-03 11:27:58

您的第一次尝试将创建comment-hiccup,如:

代码语言:javascript
复制
[nil]

其中,有效的hiccup总是以关键字标记开头,如:

代码语言:javascript
复制
[:h3 "hello"]
[:div nil]

因此错误消息基本上是说nil不是一个有效的html标记。但是,在clojure中,当转换为字符串时,nil的长度为零,因此错误消息变成is not a valid element name.,而不是foo is not a valid element name.之类的信息。

但是,Hiccup和许多类似的表单将接受nil,而不是一个有效的Hiccup表达式,在呈现其余的有效表单之前,只需过滤掉它们。这个特性的出现正是为了允许使用内联ifwhen表单,它们要么会产生有效的hiccup,要么会产生nil

样本代码:

代码语言:javascript
复制
(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:require
    [hiccup.core :as h]))

(dotest
  (is= (h/html [:p "bar"]) "<p>bar</p>")
  (is= (h/html [:p nil]) "<p></p>")
  (is= (h/html nil) "")

  ; if uncommented, this creates an error during macroexpansion of `h/html`
  ; (println :err1 (h/html [nil]))  ; <=== line 12
  ;    `Syntax error macroexpanding h/html at (tst/demo/core.clj:12:18). 
  ;       java.lang.IllegalArgumentException:  is not a valid element name.`

  )

基于我最喜欢的模板项目

侧注:像上面这样的隐式错误消息是避免在您自己的代码中不必要地使用宏的一个重要原因。以上错误不是在代码执行过程中发生的,而是在代码编译期间发生的。因此,即使用try/catch包装违规行,也无法处理错误。

附注:

大多数法学家会将上述代码浓缩成一种更“内联”的风格,如:

代码语言:javascript
复制
(defn render-location-details
  [cur-location]
  [:div
   [:h3 (:Desc cur-location)]
   [:h4 "Address"]
   [:p (:Address cur-location)]
   (when-not (clojure.string/blank? (:Comment cur-location))
     [:div
      [:h4 "Comment"]
      [:p (:Comment cur-location)]])])
票数 2
EN

Stack Overflow用户

发布于 2021-06-03 09:27:50

下面的代码似乎有效。改善建议仍受欢迎。

代码语言:javascript
复制
(defn render-location-details
  [cur-location]
  (let [
        desc (get cur-location :Desc)
        address (get cur-location :Address)
        comment (get cur-location :Comment)
        address-title [:h4 "Address"]
        address-body [:p address]
        comment-hiccup (if (clojure.string/blank? comment)
                          nil
                          [:div
                           [:h4 "Comment"]
                           [:p comment]
                           ])

        ]
    [:div
      [:h3 desc]
      address-title
      address-body
      comment-hiccup
     ]
    )
  )
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67818744

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档