Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/r0man/sablono

Lisp/Hiccup style templating for Facebook's React in ClojureScript.
https://github.com/r0man/sablono

clojure clojurescript hiccup lisp react template

Last synced: 24 days ago
JSON representation

Lisp/Hiccup style templating for Facebook's React in ClojureScript.

Awesome Lists containing this project

README

        

* ŜABLONO

[[https://clojars.org/sablono][https://img.shields.io/clojars/v/sablono.svg]]
[[https://github.com/r0man/sablono/actions?query=workflow%3A%22Clojure+CI%22][https://github.com/r0man/sablono/workflows/Clojure%20CI/badge.svg]]
[[https://versions.deps.co/r0man/sablono][https://versions.deps.co/r0man/sablono/status.svg]]
[[https://versions.deps.co/r0man/sablono][https://versions.deps.co/r0man/sablono/downloads.svg]]

Lisp/Hiccup style templating for Facebook's [[http://facebook.github.io/react][React]] in [[https://github.com/clojure/clojurescript][ClojureScript]].

[[https://xkcd.com/1144][http://imgs.xkcd.com/comics/tags.png]]

** Dependencies

/Ŝablono/ doesn't declare a dependency on React anymore. Use the
React dependencies from one of the ClojureScript wrappers or
provide the dependencies yourself like this:

#+BEGIN_SRC clojure :exports code :results silent
[cljsjs/react "16.6.0-0"]
[cljsjs/react-dom "16.6.0-0"]
#+END_SRC

If you want to do server rendering and use the =render= or
=render-static= functions from the =sablono.server= namespace you
need to add the following dependency as well:

#+BEGIN_SRC clojure :exports code :results silent
[cljsjs/react-dom-server "16.6.0-0"]
#+END_SRC

** Usage

Most functions from [[https://github.com/weavejester/hiccup][Hiccup]] are provided in the =sablono.core=
namespace. The library can be used with [[https://github.com/swannodette/om][Om]] like this:

#+BEGIN_SRC clojure :exports code :results silent
(ns example
(:require [om.core :as om :include-macros true]
[sablono.core :as html :refer-macros [html]]))

(defn widget [data]
(om/component
(html [:div "Hello world!"
[:ul (for [n (range 1 10)]
[:li {:key n} n])]
(html/submit-button "React!")])))

(om/root widget {} {:target (. js/document (getElementById "my-app"))})
#+END_SRC

By default, /Ŝablono/ will wrap any forms in the body of hiccup with a call to
=sablono.interpreter/interpret=. If your code returns a React element, then you can
skip the call to this function by marking the s-expression with the metadata tag =:inline=.
For example:

#+BEGIN_SRC clojure :exports code :results silent
[:div {}
^:inline (function-that-returns-react-component)]
#+END_SRC

** HTML Tags

/Ŝablono/ only supports tags and attributes that can be handled by
React. This means you can't have your own custom tags and
attributes at the moment. For more details take a look at the [[http://facebook.github.io/react/docs/tags-and-attributes.html][Tags
and Attributes]] section in the React documentation.

** HTML Attributes

HTML attributes in [[http://facebook.github.io/react/docs/tags-and-attributes.html#html-attributes][React]] are camel-cased and the =class= and =for=
attributes are treated special. /Ŝablono/ renames attributes with
dashes in their name to the camel-cased version and handles the
=class= and =for= special case. This is more consistent with [[https://github.com/weavejester/hiccup][Hiccup]]
and naming conventions used in Clojure.

An =input= element with event listeners attached to it would look
like this in /Ŝablono/:

#+BEGIN_SRC clojure :exports code :results silent
(html [:input
{:auto-complete "off"
:class "autocomplete"
:on-change #(on-change %1)
:on-key-down #(on-key-down %1)
:type "text"}])
#+END_SRC

** Setting innerHTML of a DOM node

It is not recommended to directly set the innerHTML of DOM nodes,
but in some cases it is necessary. i.e. injecting a HTML string
that was generated from Markdown.

#+BEGIN_SRC clojure :exports code :results silent
(html [:div {:dangerouslySetInnerHTML {:__html "

hello world
" }}])
#+END_SRC

You can read more at [[http://facebook.github.io/react/docs/special-non-dom-attributes.html][React's special attributes]].

** Benchmark

Benchmark results can be found [[https://r0man.github.io/sablono/dev/bench/][here]].

** FAQ

*** How to run the tests?

You need to have [[https://nodejs.org/en/][Node.js]] and [[http://phantomjs.org/][PhantomJS]] installed for the
ClojureScript test.

Make sure you have all dependencies installed. The following
command installs the Maven and Node.js dependencies.

#+BEGIN_SRC sh :exports code :results silent
lein deps
#+END_SRC

To run all Clojure and ClojureScript tests run the following
command:

#+BEGIN_SRC sh :exports code :results silent
lein ci
#+END_SRC

For development the ClojureScript tests can be run with
[[https://github.com/bensu/doo][lein-doo]]. To run the tests on Node.js run the following command:

#+BEGIN_SRC sh :exports code :results silent
lein doo node nodejs auto
#+END_SRC

To run the tests on PhantomJS use this command:

#+BEGIN_SRC sh :exports code :results silent
lein doo phantom none auto
#+END_SRC

*** Why is there a compiler and an interpreter?

The interpreter is executed at *run time*, and it's job is to
evaluate Hiccup forms and produce React elements. The compiler on
the other hand, is executed at *compile time* and can optimize
certain Hiccup forms. It's job is to evaluate Hiccup forms and
produce executable code.

A good introduction to this topic can be found in Peter Seibel's
[[http://www.gigamonkeys.com/book][Practical Common Lisp]]:

- [[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html][An HTML Generation Library, the Interpreter]]
- [[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html][An HTML Generation Library, the Compiler]]

** Thanks

This library is based on James Reeves excellent [[https://github.com/weavejester/hiccup][Hiccup]] library. The
server side rendering code has been taken from [[https://github.com/omcljs/om][om.next]].

** License

Copyright © 2013-2020 [[https://github.com/r0man][r0man]]

Distributed under the Eclipse Public License either version 1.0 or
(at your option) any later version.