Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

I want to store blog posts in EDN file like the one shown below and then convert them to HTML.

Here is a sample file:

    {:slug "slug"
 :title "The first blog post"
 :body [[:div
         [:p "First paragraph"]
         [:ul

          [:li "List Item 1"]
          [:li "List Item 2"]
          [:li "List Item 3"]]

         [:p "Second paragraph"]]]}

Then I try to read it using the following code:

(ns cl-www.core
  (:use [hiccup.core])
  (:require [cl-www.logic :refer [render-everything]]
            [cl-www.common :refer [prettify-html]]
            [clojure.edn]
            [clojure.java.io])
  (:import (org.jsoup Jsoup)
           (org.jsoup.nodes Document))
  (:gen-class))

(def path "/Users/myuser/cl-www/resources/p-2022-12-17.edn")

(defn test-edn
  []
  (let [post-data (-> path
                      (slurp)
                      (read-string))
        post-struct (:body post-data)
        html-struct [:html
                     [:body
                      [:h1 "Hello"]
                      post-struct]]

        html (->> html-struct
                  (html)
                  (prettify-html))]

    (println html)))

When I run (test-edn) I get the following error:
Execution error (IllegalArgumentException) at hiccup.compiler/normalize-element (compiler.clj:59). [:div [:p "First paragraph"] [:ul [:li "List Item 1"] [:li "List Item 2"] [:li "List Item 3"]] [:p "Second paragraph"]] is not a valid element name.
How can I fix it, i. e.

  1. manually write a EDN file, then
  2. read it in Clojure,
  3. insert into a Hiccup structure, and
  4. export it to HTML?
by
Yup, in the edn above the `:body` is a vector with a vector in it and that is not valid hiccup. In hiccup the first element of a vector is often a keyword, indicating which tag to render.

1 Answer

0 votes
by
selected by
 
Best answer

Looks like there was an error in the :body value of the EDN file. This one works:

{:slug "slug"
 :title "The first blog post"
 :body [:div
         [:p "First paragraph"]
         [:ul

          [:li "List Item 1"]
          [:li "List Item 2"]
          [:li "List Item 3"]]

         [:p "Second paragraph"]]}
...