Reputation: 409
I am following guestbook example from the book Web Development With Clojure 3rd edition. I am struggling with including ClojureScript namespace into HTML document. Everything is working fine with example where I have one core.cljs. With that file, only I have to do is to include this piece of code into home.html document:
{% extends "base.html" %}
{% block content %}
<input id="token" type="hidden" value="{{csrf-token}}">
<div id="content"></div>
{% endblock %}
{% block page-scripts %}
{% script "/js/app.js" %}
{% endblock %}
As I mentioned, everything is ok in this situation. But when I created additional ClojureScript file and name it test.cljs and included that in the same way in the new HTML document named test.html I see errors in the console such as "Target container is not a DOM element.". I think that something is wrong with this part:
{% block page-scripts %}
{% script "/js/app.js" %}
{% endblock %}
But I can't figure out how to solve this. Actually, my question maybe should be: How to include ClojureScript into HTML file?. Is the only way this piece of code?
{% block page-scripts %}
{% script "/js/app.js" %}
{% endblock %}
Or, maybe I should change {% script "/js/app.js" %} part of this snippet?
Or even better, when I create simple HTML file without extending any base.html file, how to add clojurescript namespace, how to reference it? You know, like javascript helloworld example
<script src="myscripts.js"></script>
How to do this in ClojureScript? I am using Luminus framework.
Upvotes: 0
Views: 830
Reputation: 3346
In general, a Luminus project with ClojureScript support will compile all ClojureScript code into a single app.js
file, as in this block of the project.clj
file (from a project I just created with lein new luminus guestbook +h2 +immutant +cljs
, where the +cljs
is the important bit):
:cljsbuild{:builds
{:app
{:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
:figwheel {:on-jsload "guestbook.core/mount-components"}
:compiler
{:main "guestbook.app"
:asset-path "/js/out"
:output-to "target/cljsbuild/public/js/app.js" ;; <= THIS
:output-dir "target/cljsbuild/public/js/out"
:source-map true
:optimizations :none
:pretty-print true}}}}
That's a very convenient default for single page apps (a la Angular or React), but I think you are thinking of a website with different HTML pages, each one including a different JavaScript file (in this case, everything is compiled to a single JavaScript file).
If you want to call different functions (eg. from different namespaces), you'll need to export them (to make them easily available from JavaScript) and then call each function in their respective HTML file, a bit like the following:
...
<!-- in test.html -->
{% script "/js/app.js" %}
<script>
guestbook.test.init();
</script>
...
in src/cljs/guestbook/test.cljs
(ns guestbook.test)
(defn mount-components []
(let [content (js/document.getElementById "app")]
(while (.hasChildNodes content)
(.removeChild content (.-lastChild content)))
(.appendChild content (js/document.createTextNode "Welcome to the test page"))))
(defn ^:export init []
(mount-components))
Also, remember to rebuild your ClojureScript files. You can leave another terminal running the following command to recompile any ClojureScript files when they change: lein cljsbuild auto
Upvotes: 1