Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clojurescript templating from html files

I'm new to clojure / clojurescript so there may be a simple solution to this I am overlooking, but here is my problem:

I have existing html files (just raw html, no variables or anything) I'd like to use as partials for a clojurescript project (These html files are things like navigation, footer, etc). I'd like to require these html templates in the clojurescript project, and then have the templates be inlined in the compiled js so I don't have to do any ajax calls for templates in production or copying over the html files to be available to the client in production. Projects like requirejs and browserify have plugins to let you just 'require' the html files - is there an equivalent for clojurescript?

I know of libraries to do templating / dom manipulation so that is not an issue. It is simply the translating of multiple external html files into inlined strings/dom nodes/whatever to be included in the production js.

Thanks

like image 361
Isaac Chansky Avatar asked Feb 12 '23 22:02

Isaac Chansky


1 Answers

You can do this using macros executed at compile time.

project.clj

  :dependencies [[org.clojure/clojure "1.6.0"]
                 [org.clojure/clojurescript "0.0-2202"]]
  :source-paths ["src"]
  :cljsbuild
  {:builds
   [{:id "main"
     :source-paths ["src/cljs"]
     :compiler
     {
      :output-to "resources/main.js"
      :optimizations :whitespace
      :pretty-print true}}]})

src/cljstemplates/core.clj

(ns cljstemplates.core
  (:require [clojure.java.io :refer (resource)]))

(defmacro deftmpl
  "Read template from file in resources/"
  [symbol-name html-name]
  (let [content (slurp (resource html-name))]
    `(def ~symbol-name
       ~content)))

src/cljs/web.cljs

(ns cljstemplates.web
  (:require-macros [cljstemplates.core :refer [deftmpl]]))

(deftmpl head "header.html")
(deftmpl nav "nav.html")
(deftmpl foot "footer.html")

This will generate vars head, nav, foot containing strings read from files in resources/ folder.

resources/nav.html

<nav>
  <ul>
    <li>Tweets</li>
  </ul>
</nav>

Output (main.js):

cljstemplates.web.nav = "\x3cnav\x3e\n  \x3cul\x3e\n    \x3cli\x3eTweets\x3c/li\x3e\n  \x3c/ul\x3e\n\x3c/nav\x3e\n";
like image 101
edbond Avatar answered Apr 29 '23 08:04

edbond