[这可能看起来像我的问题是Compojure,但它不是 - 它与Clojure一起]
在这个看似简单的问题上,我一直在拔头发 - 但我无处可去。
我正在使用Compojure(Clojure的轻量级Web框架),我想生成一个显示我的PostgreSQL数据库中的待办事项列表的网页。
下面的代码片段(省略了数据库连接,查询等 - 但不需要该部分,因为特定问题是生成的HTML在< body>和< / body>标记之间没有显示任何内容)
作为测试,我尝试在对main-layout的调用中对字符串进行硬编码,如下所示: (html(主要布局“Aki's Todos”“Haircut< br> Study Clojure< br>回答关于Stackoverfolw的问题”)) - 并且它工作正常。
所以真正的问题是我不相信我知道如何在Clojure中建立一个字符串。不是惯用的方式,也不是通过调用Java的StringBuilder - 正如我在下面的代码中所做的那样。
虚拟啤酒,对任何可以解决它的人来说都是一个很大的支持!非常感谢!
=============================================== ==============
;The master template (a very simple POC for now, but can expand on it later)
(defn main-layout
"This is one of the html layouts for the pages assets - just like a master page"
[title body]
(html
[:html
[:head
[:title title]
(include-js "todos.js")
(include-css "todos.css")]
[:body body]]))
(defn show-all-todos
"This function will generate the todos HTML table and call the layout function"
[]
(let [rs (select-all-todos)
sbHTML (new StringBuilder)]
(for [rec rs]
(.append sbHTML (str rec "<br><br>")))
(html (main-layout "Aki's Todos" (.toString sbHTML)))))
=============================================== ==============
同样,结果是一个网页,但身体标签之间没有任何内容。如果我使用println语句替换for循环中的代码,并将代码指向repl - 忘记网页内容(即调用main-layout),结果集将被打印 - 但是 - 问题在于构建字符串。
再次感谢。
〜秋
答案 0 :(得分:6)
for
是懒惰的,在你的函数中它永远不会被评估。将for
更改为doseq
。
user> (let [rs ["foo" "bar"]
sbHTML (new StringBuilder)]
(for [rec rs]
(.append sbHTML (str rec "<br><br>")))
(.toString sbHTML))
""
user> (let [rs ["foo" "bar"]
sbHTML (new StringBuilder)]
(doseq [rec rs]
(.append sbHTML (str rec "<br><br>")))
(.toString sbHTML))
"foo<br><br>bar<br><br>"
您还可以使用reduce
和interpose
或clojure.string/join
来自clojure.string,或者可能使用其他一些选项。
user> (let [rs ["foo" "bar"]]
(reduce str (interpose "<br><br>" rs)))
"foo<br><br>bar"
user> (require 'clojure.string)
nil
user> (let [rs ["foo" "bar"]]
(clojure.string/join "<br><br>" rs))
"foo<br><br>bar"
答案 1 :(得分:2)
您希望像re-gsub这样使用:
(要求'clojure.contrib.str-utils);;请尽快让我们使用re-gsub
(clojure.contrib.str-utils / re-gsub#“\ newline”“&lt; br&gt;&lt; br&gt;”your-string-with-todos-separated-with-newlines)
这最后一行会产生你喜欢的字符串。正如您可能已经知道的那样,require-part可以让编译器访问功能强大的clojure.contrib.str-utils库,而无需将其导入当前命名空间(这可能会导致程序增长时发生不必要的冲突)。
返回reg-exp,并允许你定义一个#“regexp”形式的reg-exp,用于替换所有后续使用参数的regexp命中的实例,应用于第三个参数。在这种情况下,\ newline是在regexp中表示换行符的方式,以及字符串和我们正在寻找的字符。
我认为你真正想做的是用html格式制作一个漂亮的有序或无序列表。这些可以通过[hiccup-page-helpers] [2]完成(如果你没有它们,你可能有一个组件,从它被分解为compojure,打嗝等等,因为你使用html函数)。
如果你想使用hiccup-page-helpers,请以这种方式使用上面提到的clojure.contrib.str-utils中的命令重新拆分:
(使用'hiccup.page-helpers);;注意命名空间冲突,因为hiccup.page-helpers中的所有函数都进入了当前的命名空间。
(unordered-list(clojure.contrib.str-utils / re-split#“\ newline”your-string-with-todos-separated-with-newlines))
哪个应该整洁
&LT; UL&GT;
&LT;李&GT;待办事项-ITEM1和LT; /锂&GT;
&LT;李&GT;待办事项-ITEM2&LT; /锂&GT;
&LT; / UL&GT;
(是的,有一个order-list命令以相同的方式工作!)
在上面的clojure代码的最后一行中,你所有的todos都进入了一个(列表“todo1”“todo2”),它被hiccup.page-helpers unordered-list函数立即使用,并且转换为html-ized列表。
祝好朋友和朋友们好运!