4

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

2
  • take a look at github.com/ckirkendall/enfocus may fit what you needs. clojurescript, compiled templates. Commented May 20, 2014 at 19:38
  • 1
    Thanks, I'll see if this might work for us. Not sure if it solves the problem of having a single js file including the templates, but seems solid for the rest - I'll have to try it out and see. Appreciate it! Commented May 20, 2014 at 22:33

1 Answer 1

8

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";
Sign up to request clarification or add additional context in comments.

1 Comment

Woah, this is awesome thanks. Being a clojure newbie I'll have to read this a few times before I get it but this is super helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.