Problem with creating string in Clojure

[it might seem like my problem is with Compojure, but it isn’t with Clojure]

I am pulling my hair out on this seemingly simple problem, but I get nothing.

I play with Compojure (a lightweight web framework for Clojure) and I just want to create a web page showing my list of todos that are in the PostgreSQL database.

Below are the code snippets (excluding database connection, query, etc.), but this part is not needed, since the specific problem is that the received HTML code does not show anything between the <body> and </body> tags .

As a test, I tried hard-coded a string in a main-layout call, for example: (html (main-layout "Aki Todos") "Haircut" Clojure Research <br> Answer a question about Stackoverfolw ")) - and it works fine.

So, the real problem is that I do not believe that I know how to create a string in Clojure. Not in an idiomatic way, not by calling StringBuilder in Java - as I tried to do in the code below.

Virtual beer and a large supply for those who can solve it! Thank you very much!

==================================================== ============

;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 Todos" (.toString sbHTML))))) 

==================================================== ============

Again, the result is a web page, but nothing happens between body tags. If I replaced the code in the for loop with println instructions and directed the code to forget the web page material (i.e., calling the main layout), then the result set will be printed - BUT - the problem is with the building up the line.

Thanks again.

~ Aki

+4
source share
2 answers

for lazy, and in your function it is never evaluated. Change for to 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>" 

You can also use reduce and interpose , or clojure.string/join from clojure.string, or perhaps some other parameters.

 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" 
+6
source

You would like to use re-gsub as follows:

(require 'clojure.contrib.str-utils) ;; put in mind so we can use re-gsub later

(clojure.contrib.str-utils / re-gsub # "\ newline" "<br> <br>" your-string-with-todos-separated-with-newlines)

This last line will lead to the desired line. The necessary part, as you already know, allows the compiler to reach the powerful clojure.contrib.str-utils library without importing it into the current namespace (which could potentially lead to unwanted collisions when the program grows).

repeatedly for reg-exp and allows you to define reg-exp of the form # "regexp", which will replace all instances that subsequently fall into regexp with an argument, applied to the third argument. \ Newline in this case clojures is a way of expressing strings in regular expressions, as well as the strings and character we are looking for.

I think what you really wanted to do was make an excellent ordered or unordered list in html format. This can be done using [hiccup-page-helers] [2] (if you do not have them, you probably have a component of the time before it is split into compojure, hiccup, etc., since you use html function).

If you want to use hiccup-page-helpers, use the re-split command from clojure.contrib.str-utils mentioned above, like this:

(use "hiccup.page-helers"); be aware of all namespace conflicts as all functions in hiccup.page-helers are in your current namespace.

(unordered list (clojure.contrib.str-utils / re-split # "\ newline" your lines-with-todos-separated-with-newlines))

which should do neat
<ul>
<& Li GT; ToDo-element 1 </ & Li GT;
<& Li GT; ToDo-element 2 </ & Li GT;
</ ΞΌl>

(and yes, there is an ordered list command that works the same way!)

In the last line of clojure code above, all of your todos fall into (list "todo1" "todo2"), which is immediately consumed by the uncontrolled list function hiccup.page-helers and converted to html.

Good luck with compojure and friends!

+2
source

Source: https://habr.com/ru/post/1334784/


All Articles