How to include ClojureScript into HTML page? - clojurescript

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.

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

Related

Django - Use variables from included template

I have the following setup:
base.html
...
{% block main-content %}
{% endblock main-content %}
...
admin.html
{% extends "base.html" %}
{% load staticfiles %}
{% block main-content %}
{% include users.html %}
{% endblock main-content %}
The file users.html uses tags like '{{ users }}' because it renders from a view that also returns several variables. Right now, if I call admin.html I can see the template of users.html (basic html, css) without the variables. I don't think the template is rendering from my views.py.
Is there anyway I can obtain the variables that the view is returning?
Note: base.html and admin.html are in the same django app, while users.html is in a different one.
Thank you!
This seems to be a common misapprehension.
Templates do not belong to views. The only relationship is that a view may (or may not) render a template: but a template itself may be rendered by one or many views, and has no actual knowledge of any of them. So when you "include" your template inside your admin template, there is no relationship to any other view that might also render it; if you need some variables in that view, you'll need to pass them there yourself.
Note that this sort of thing - that is, including a template along with some specific context variables - is usually best handled as an inclusion tag

Include files and also copy them to output

In a Jekyll powered page, I have a set of files located in:
_includes/stuff/
I put those files there so that I can include them in other Markdown pages using:
{% include stuff/example.txt %}
This works as expected.
However, I also want to copy those files to the generated page so that I can link to them and that people can follow those links to download them. But by definition, stuff stored in directories starting with an underscore are not copied by Jekyll.
Another approach also didn't work. I put the files in an own top folder called stuff. This copies the folder to the final site. However, I'm not able to include a file from this folder. It seems include_relative only allows including files below the current one. For example, the following don't work:
{% include_relative stuff/example.txt %}
{% include_relative /stuff/example.txt %}
{% include_relative ../stuff/example.txt %}
Any ideas how I can achieve including and copying at the same time?
This works from index.html
{% include_relative example.txt %} for example.txt
{% include_relative stuff/example.txt %} for stuff/example.txt
{% include_relative /stuff/example.txt %} for stuff/example.txt
stuff/example.txt
class Toto
def dototo
myvar = "toto"
end
end
index.html
{% assign codeurl = "stuff/example.txt" %}
{% highlight ruby %}
{% include_relative {{codeurl}} %}
{% endhighlight %}
link to code
if codeurl == "/stuff/example.txt" this generates a link relative to site root
this may need {{site.baseurl}} prepended if your site is not at the root
of a domain (eg: user.github.io/repository)
link to code
For security reasons, this will not work :
{% include_relative ../stuff/example.txt %}
Just to avoid directory traversal
{% include_relative ../../../../../../../../../../../../etc/pwd %}
If you want to put you files in _includes/stuff you will need to do an include: [ /_includes ] in _config.yml, that will include all files in _includes as static files. Not very clean as you cannot filter subdiretories like include: [ /_includes/stuff ] to import only your stuff files.
Note : a dirty trick allows you to import only _includes/stuff/*.txt but I think it's really dirty.
# _config.yml
include:
- "_includes"
- "stuff"
- "*.txt"
exclude:
- "_includes/*.*"

Render static html page inside my base django template

I'm developing a web portal using
- Django 1.2
- Apache
- Mod WSGI
I've several HTML files which are being served by apache.
I want to render those static HTML pages under my base template in order to keep my header / footer and dynamic menus intact.
One way I could thought its using iframes. Another way is to do read HTML files and return string while rendering but in that case I'm loosing advantage of apache, so I want to know if there would be any better way of doing it, is there any existing solution provided by django stuff ?
I'm not sure if this is exactly what you're asking for, but you can insert an html file (or even another template) in a template with the ssi and include tags, depending on your needs:
{% ssi '/path/to/file.html' %}
{% include 'relative/path/to/template.html' %}
yes, it's the include tag
Loads a template and renders it with the current context. This is a way of "including" other templates within a template.
it's as simple as
{% include "templates/static_template_1.html" %}
or, if you create a variable in the view side:
{% include template_name_variable %}
it shares the context with the base template (the one including them)
Edit:
Perhaps you ment to load html-files outside the template-system. Then my way will not suffice.
An option is to extend your base template.
Your base template should not be aware of the sub templates as that would be logically wrong.
Example:
base_template.html:
<html>
<div id='header'></div>
{% block content %}
This text can be left out else it it will shown when nothing is loaded here
{% endblock %}
sub_template.html:
{% extends "base_template.html" %}
{% block content %}
<h1>This is my subpage</h1>
{% endblock %}
You can read more here:
https://docs.djangoproject.com/en/1.2/topics/templates/

Is it possible to perform Includes with flask?

Say I have a template layout saved in template.html. This template includes a banner, side navigation, content container, and footer. Can I use flask to break up these page elements in such a way that I can have files such as banner.html, sidenavigation.html, etc. and render these different files within template.html?
From: http://jinja.pocoo.org/docs/templates/#include
template.html
{% include 'banner.html' %}
{% include 'sidenavigation.html' %}
{% include 'content.html' %}
{% include 'footer.html' %}
By default, Flask uses Jinja2 as its template engine. See Jinja's Template Designer Documentation how it's done.
Before you start, you need to write these components separately to other html files as pure html. For example, these files shouldn't contain any jinja syntax. After that, according to the documentation, you can easily import them into your template.html file by calling {% include 'filename.html' %} code.

jinja2 load template file from template

Is there a way I can load a jinja2 template from within another template file? Something like
{{ render_template('path/to/file.html') }}
I have some snippets which I want to reuse, so it's important for me to have this functionality.
{% include "file" %} does this. See the jinja2 docs for more information.
Use either the extends tag or the include tag, depending on how you want to design your multi-file views.
You should make template files with {% macro -%}s and use {% import "file" as file %} to use the macros in other template files. See the docs.
Here is an example:
<!- in common_macros.html ->
{% macro common_idiom1(var1, var2, ... varN) -%}
<!- your idiom, where you can use var1 through varN ->
{%- endmacro %}
<!- in my_template.html ->
{% import "common_macros.html" as idioms %}
{{ idioms.common_idiom1(a, b, ... N) }}
Specifically this answer allows the OP to pass arguments to his macros, similar to the behavior he desired like how render_template behaves (simply including the file as previous answers have stated above does not achieve the same behavior as render_template).
This is generally better than making a fresh template for every idiom, or than using inheritance, which is a special case solution (what if you want to use the snippet multiple times in one template)?