Skip to content

Commit

Permalink
♻️ Hiccup macro which uses always the same output mode
Browse files Browse the repository at this point in the history
Why:
- Hiccup generates 8 code paths every time the hiccup2.core/html macro
  is used, one for each combination of the output formats (html, xhtml,
  xml, sgml) and string escape mode (true, false). In practice, an
  application uses only one or two of them, and the rest is dead code.
- This fixes the problem of exponential amount of generated code in some
  situations. See weavejester/hiccup#210
  • Loading branch information
luontola committed Oct 27, 2024
1 parent 4a0cc6a commit 616ed51
Show file tree
Hide file tree
Showing 22 changed files with 71 additions and 30 deletions.
2 changes: 1 addition & 1 deletion src/territory_bro/ui/congregation_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

(ns territory-bro.ui.congregation-page
(:require [clojure.string :as str]
[hiccup2.core :as h]
[territory-bro.domain.dmz :as dmz]
[territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.info-box :as info-box]
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/documentation_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

(ns territory-bro.ui.documentation-page
(:require [clojure.java.io :as io]
[hiccup2.core :as h]
[territory-bro.infra.resources :as resources]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/error_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

(ns territory-bro.ui.error-page
(:require [clojure.tools.logging :as log]
[hiccup2.core :as h]
[ring.util.response :as response]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]))
Expand Down
16 changes: 16 additions & 0 deletions src/territory_bro/ui/hiccup.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
;; Copyright © 2015-2024 Esko Luontola
;; This software is released under the Apache License 2.0.
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.hiccup
(:require [hiccup.compiler :as compiler]
[hiccup.util :as util]))

(defmacro html [& content]
(binding [util/*html-mode* :html ; compile time options
util/*escape-strings?* true]
`(binding [util/*html-mode* :html ; runtime options
util/*escape-strings?* true]
(util/raw-string ~(apply compiler/compile-html content)))))

(def raw util/raw-string)
2 changes: 1 addition & 1 deletion src/territory_bro/ui/home_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

(ns territory-bro.ui.home-page
(:require [clojure.java.io :as io]
[hiccup2.core :as h]
[territory-bro.domain.dmz :as dmz]
[territory-bro.infra.resources :as resources]
[territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]
Expand Down
7 changes: 2 additions & 5 deletions src/territory_bro/ui/html.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,16 @@
(ns territory-bro.ui.html
(:require [clojure.java.io :as io]
[clojure.string :as str]
[hiccup.util :as hiccup.util]
[hiccup2.core :as h]
[net.cgrand.enlive-html :as en]
[reitit.core :as reitit]
[ring.middleware.anti-forgery :as anti-forgery]
[ring.util.http-response :as http-response]
[ring.util.response :as response]
[territory-bro.infra.json :as json])
[territory-bro.infra.json :as json]
[territory-bro.ui.hiccup :as h])
(:import (org.reflections Reflections)
(org.reflections.scanners Scanners)))

(alter-var-root #'hiccup.util/*html-mode* (constantly :html)) ; change default from :xhtml to :html

(def ^:dynamic *page-path*)


Expand Down
4 changes: 2 additions & 2 deletions src/territory_bro/ui/info_box.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.info-box
(:require [hiccup2.core :as h]
[territory-bro.ui.css :as css]
(:require [territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]))

(defn view [{:keys [title]} content]
Expand Down
4 changes: 2 additions & 2 deletions src/territory_bro/ui/join_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.join-page
(:require [hiccup2.core :as h]
[territory-bro.domain.dmz :as dmz]
(:require [territory-bro.domain.dmz :as dmz]
[territory-bro.infra.authentication :as auth]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]))
Expand Down
4 changes: 2 additions & 2 deletions src/territory_bro/ui/layout.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@
(ns territory-bro.ui.layout
(:require [clojure.string :as str]
[hiccup.page :as hiccup.page]
[hiccup2.core :as h]
[territory-bro.domain.dmz :as dmz]
[territory-bro.infra.auth0 :as auth0]
[territory-bro.infra.authentication :as auth]
[territory-bro.infra.config :as config]
[territory-bro.infra.resources :as resources]
[territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.info-box :as info-box]))
Expand Down Expand Up @@ -181,8 +181,8 @@
(defn page [view model]
(let [styles (:Layout (css/modules))
title (parse-title view)]
(assert (= :html hiccup.util/*html-mode*))
(str (h/html
(assert (= :html hiccup.util/*html-mode*))
(hiccup.page/doctype :html5)
[:html {:lang (name i18n/*lang*)}
[:head
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/map_interaction_help.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

(ns territory-bro.ui.map-interaction-help
(:require [clojure.string :as str]
[hiccup2.core :as h]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.info-box :as info-box]))

Expand Down
4 changes: 2 additions & 2 deletions src/territory_bro/ui/markdown.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.markdown
(:require [hiccup2.core :as h]
[ring.util.http-response :as http-response])
(:require [ring.util.http-response :as http-response]
[territory-bro.ui.hiccup :as h])
(:import (com.vladsch.flexmark.ext.anchorlink AnchorLinkExtension)
(com.vladsch.flexmark.html HtmlRenderer)
(com.vladsch.flexmark.parser Parser)
Expand Down
4 changes: 2 additions & 2 deletions src/territory_bro/ui/printout_templates.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.printout-templates
(:require [hiccup2.core :as h]
[territory-bro.ui.css :as css]
(:require [territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n])
(:import (java.time LocalDate)))
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/printouts_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

(ns territory-bro.ui.printouts-page
(:require [clojure.string :as str]
[hiccup2.core :as h]
[ring.util.response :as response]
[territory-bro.domain.dmz :as dmz]
[territory-bro.gis.geometry :as geometry]
[territory-bro.infra.json :as json]
[territory-bro.infra.middleware :as middleware]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/privacy_policy_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
(:require [clojure.java.io :as io]
[clojure.java.shell :as shell]
[clojure.string :as str]
[hiccup2.core :as h]
[territory-bro.infra.resources :as resources]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.layout :as layout]
[territory-bro.ui.markdown :as markdown]))
Expand Down
4 changes: 2 additions & 2 deletions src/territory_bro/ui/registration_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.registration-page
(:require [hiccup2.core :as h]
[ring.util.http-response :as http-response]
(:require [ring.util.http-response :as http-response]
[territory-bro.domain.dmz :as dmz]
[territory-bro.ui.forms :as forms]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout])
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/settings_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

(ns territory-bro.ui.settings-page
(:require [clojure.string :as str]
[hiccup2.core :as h]
[ring.util.codec :as codec]
[ring.util.http-response :as http-response]
[ring.util.response :as response]
Expand All @@ -13,6 +12,7 @@
[territory-bro.infra.config :as config]
[territory-bro.ui.css :as css]
[territory-bro.ui.forms :as forms]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.info-box :as info-box]
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/support_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

(ns territory-bro.ui.support-page
(:require [clojure.string :as str]
[hiccup2.core :as h]
[territory-bro.infra.authentication :as auth]
[territory-bro.infra.config :as config]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]))
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/territory_list_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

(ns territory-bro.ui.territory-list-page
(:require [clojure.string :as str]
[hiccup2.core :as h]
[territory-bro.domain.dmz :as dmz]
[territory-bro.infra.authentication :as auth]
[territory-bro.infra.json :as json]
[territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.info-box :as info-box]
Expand Down
2 changes: 1 addition & 1 deletion src/territory_bro/ui/territory_page.clj
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@

(ns territory-bro.ui.territory-page
(:require [clojure.string :as str]
[hiccup2.core :as h]
[ring.util.response :as response]
[territory-bro.domain.dmz :as dmz]
[territory-bro.gis.geometry :as geometry]
[territory-bro.infra.config :as config]
[territory-bro.infra.middleware :as middleware]
[territory-bro.ui.css :as css]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout]
Expand Down
28 changes: 28 additions & 0 deletions test/territory_bro/ui/hiccup_test.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
;; Copyright © 2015-2024 Esko Luontola
;; This software is released under the Apache License 2.0.
;; The license text is at http://www.apache.org/licenses/LICENSE-2.0

(ns territory-bro.ui.hiccup-test
(:require [clojure.test :refer :all]
[territory-bro.ui.hiccup :as h])
(:import (hiccup.util RawString)))

(deftest html-test
(is (instance? RawString (h/html)))
(is (= "" (str (h/html))))

(testing "produces HTML 5"
(testing "at compile time"
(is (= "<p flag>foo</p>" (str (h/html [:p {:flag true} "foo"]))))
(is (= "<br>" (str (h/html [:br])))))

(testing "at runtime"
(is (= "<p flag>foo</p>" (str (h/html (identity [:p {:flag true} "foo"])))))
(is (= "<br>" (str (h/html (identity [:br])))))))

(testing "escapes text"
(testing "at compile time"
(is (= "<p>&lt;script&gt;</p>" (str (h/html [:p "<script>"])))))

(testing "at runtime"
(is (= "<p>&lt;script&gt;</p>" (str (h/html [:p (identity "<script>")])))))))
2 changes: 1 addition & 1 deletion test/territory_bro/ui/html_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
(:require [clojure.java.io :as io]
[clojure.string :as str]
[clojure.test :refer :all]
[hiccup2.core :as h]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html])
(:import (java.io File)
(org.apache.commons.codec.digest DigestUtils)
Expand Down
2 changes: 1 addition & 1 deletion test/territory_bro/ui/layout_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
(ns territory-bro.ui.layout-test
(:require [clojure.string :as str]
[clojure.test :refer :all]
[hiccup2.core :as h]
[territory-bro.domain.congregation :as congregation]
[territory-bro.infra.authentication :as auth]
[territory-bro.infra.config :as config]
[territory-bro.test.fixtures :refer :all]
[territory-bro.test.testutil :as testutil :refer [replace-in]]
[territory-bro.ui.hiccup :as h]
[territory-bro.ui.html :as html]
[territory-bro.ui.i18n :as i18n]
[territory-bro.ui.layout :as layout])
Expand Down

0 comments on commit 616ed51

Please sign in to comment.