clojure - 如何有条件地生成打嗝结构?
问题描述
我有一堆描述位置的地图:
(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
s,有些则没有。
我想创建一个 Clojure 函数,除其他外,将注释输出到 HTML(如果存在)。
我写了这个函数:
(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
]
)
)
如果我运行使用此函数的代码,我会收到错误
Execution error (IllegalArgumentException) at
hiccup.compiler/normalize-element (compiler.clj:59).
is not a valid element name.
如果我更改comment-hiccup
为nil
,则错误消失。
如何使用 Hiccup 有条件地将数据输出到 HTML?
注意:我是 Clojure 的新手,所以如果我的方法完全错误,请告诉并展示如何正确操作。
解决方案
您的第一次尝试将创建comment-hiccup
如下:
[nil]
有效的打嗝总是以关键字标签开头,例如:
[:h3 "hello"]
[:div nil]
所以错误消息基本上说这nil
不是有效的html标签。但是,在 clojure 中nil
,当转换为字符串时长度为零,因此错误消息变为 is not a valid element name.
而不是类似foo is not a valid element name.
但是,Hiccup 和许多类似的表单将接受nil
而不是有效的 Hiccup 表达式,并在呈现剩余的有效表单之前将它们过滤掉。此功能的存在正是为了允许使用内联if
或when
表单,它们会产生有效的打嗝或nil
.
示例代码:
(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
。
附言
大多数 clojurists 会将上述代码压缩为更“内联”的样式,例如:
(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)]])])
推荐阅读
- google-cloud-platform - 将大量文件从 Box 直接移动到 Google 存储桶?
- android - 获取滚动视图的更新大小
- nginx - Lua拆分和组合字符串
- python - iterrows() 和列来识别入口位置
- sql-server - SQL Server 字符串到 mxn 表
- php - PHP 7.0 未在 Ubuntu 14 上使用已安装的 php-curl 扩展
- javascript - 有没有办法让 HTML 背景图像在高度改变后自动重复?
- angular - 无法将代码从 Vs Code 界面推送到 gitlab。Git:git@gitlab.com:权限被拒绝(公钥,键盘交互)
- typescript - 如何通知 Typescript 编译器已检查并定义了对象的每个值?
- php - 如何在phpunit中模拟内部函数?