{"id":13800927,"url":"https://github.com/r0man/sablono","last_synced_at":"2025-05-15T08:05:21.978Z","repository":{"id":12685142,"uuid":"15357315","full_name":"r0man/sablono","owner":"r0man","description":"Lisp/Hiccup style templating for Facebook's React in ClojureScript.","archived":false,"fork":false,"pushed_at":"2020-08-04T21:21:30.000Z","size":675,"stargazers_count":695,"open_issues_count":17,"forks_count":66,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-07T02:19:47.927Z","etag":null,"topics":["clojure","clojurescript","hiccup","lisp","react","template"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"epl-1.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/r0man.png","metadata":{"files":{"readme":"README.org","changelog":"CHANGELOG.org","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["r0man"]}},"created_at":"2013-12-21T10:29:21.000Z","updated_at":"2025-03-04T10:49:18.000Z","dependencies_parsed_at":"2022-09-05T17:30:59.529Z","dependency_job_id":null,"html_url":"https://github.com/r0man/sablono","commit_stats":null,"previous_names":[],"tags_count":37,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r0man%2Fsablono","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r0man%2Fsablono/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r0man%2Fsablono/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/r0man%2Fsablono/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/r0man","download_url":"https://codeload.github.com/r0man/sablono/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248870066,"owners_count":21174974,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","clojurescript","hiccup","lisp","react","template"],"created_at":"2024-08-04T00:01:17.701Z","updated_at":"2025-04-14T11:24:59.290Z","avatar_url":"https://github.com/r0man.png","language":"Clojure","funding_links":["https://github.com/sponsors/r0man"],"categories":["Awesome ClojureScript"],"sub_categories":["Document Object Model"],"readme":"* ŜABLONO\n\n  [[https://clojars.org/sablono][https://img.shields.io/clojars/v/sablono.svg]]\n  [[https://github.com/r0man/sablono/actions?query=workflow%3A%22Clojure+CI%22][https://github.com/r0man/sablono/workflows/Clojure%20CI/badge.svg]]\n  [[https://versions.deps.co/r0man/sablono][https://versions.deps.co/r0man/sablono/status.svg]]\n  [[https://versions.deps.co/r0man/sablono][https://versions.deps.co/r0man/sablono/downloads.svg]]\n\n  Lisp/Hiccup style templating for Facebook's [[http://facebook.github.io/react][React]] in [[https://github.com/clojure/clojurescript][ClojureScript]].\n\n  [[https://xkcd.com/1144][http://imgs.xkcd.com/comics/tags.png]]\n\n** Dependencies\n\n   /Ŝablono/ doesn't declare a dependency on React anymore. Use the\n   React dependencies from one of the ClojureScript wrappers or\n   provide the dependencies yourself like this:\n\n   #+BEGIN_SRC clojure :exports code :results silent\n    [cljsjs/react \"16.6.0-0\"]\n    [cljsjs/react-dom \"16.6.0-0\"]\n   #+END_SRC\n\n   If you want to do server rendering and use the =render= or\n   =render-static= functions from the =sablono.server= namespace you\n   need to add the following dependency as well:\n\n   #+BEGIN_SRC clojure :exports code :results silent\n    [cljsjs/react-dom-server \"16.6.0-0\"]\n   #+END_SRC\n\n** Usage\n\n   Most functions from [[https://github.com/weavejester/hiccup][Hiccup]] are provided in the =sablono.core=\n   namespace. The library can be used with [[https://github.com/swannodette/om][Om]] like this:\n\n   #+BEGIN_SRC clojure :exports code :results silent\n    (ns example\n      (:require [om.core :as om :include-macros true]\n                [sablono.core :as html :refer-macros [html]]))\n\n    (defn widget [data]\n      (om/component\n       (html [:div \"Hello world!\"\n              [:ul (for [n (range 1 10)]\n                     [:li {:key n} n])]\n              (html/submit-button \"React!\")])))\n\n    (om/root widget {} {:target (. js/document (getElementById \"my-app\"))})\n   #+END_SRC\n\n   By default, /Ŝablono/ will wrap any forms in the body of hiccup with a call to\n   =sablono.interpreter/interpret=. If your code returns a React element, then you can\n   skip the call to this function by marking the s-expression with the metadata tag =:inline=.\n   For example:\n\n   #+BEGIN_SRC clojure :exports code :results silent\n    [:div {}\n     ^:inline (function-that-returns-react-component)]\n   #+END_SRC\n\n** HTML Tags\n\n   /Ŝablono/ only supports tags and attributes that can be handled by\n   React. This means you can't have your own custom tags and\n   attributes at the moment. For more details take a look at the [[http://facebook.github.io/react/docs/tags-and-attributes.html][Tags\n   and Attributes]] section in the React documentation.\n\n** HTML Attributes\n\n   HTML attributes in [[http://facebook.github.io/react/docs/tags-and-attributes.html#html-attributes][React]] are camel-cased and the =class= and =for=\n   attributes are treated special. /Ŝablono/ renames attributes with\n   dashes in their name to the camel-cased version and handles the\n   =class= and =for= special case. This is more consistent with [[https://github.com/weavejester/hiccup][Hiccup]]\n   and naming conventions used in Clojure.\n\n   An =input= element with event listeners attached to it would look\n   like this in /Ŝablono/:\n\n   #+BEGIN_SRC clojure :exports code :results silent\n    (html [:input\n           {:auto-complete \"off\"\n            :class \"autocomplete\"\n            :on-change #(on-change %1)\n            :on-key-down #(on-key-down %1)\n            :type \"text\"}])\n   #+END_SRC\n\n** Setting innerHTML of a DOM node\n\n   It is not recommended to directly set the innerHTML of DOM nodes,\n   but in some cases it is necessary. i.e. injecting a HTML string\n   that was generated from Markdown.\n\n   #+BEGIN_SRC clojure :exports code :results silent\n    (html [:div {:dangerouslySetInnerHTML {:__html \"\u003cdiv\u003ehello world\u003c/div\u003e\" }}])\n   #+END_SRC\n\n   You can read more at [[http://facebook.github.io/react/docs/special-non-dom-attributes.html][React's special attributes]].\n\n** Benchmark\n\n   Benchmark results can be found [[https://r0man.github.io/sablono/dev/bench/][here]].\n\n** FAQ\n\n*** How to run the tests?\n\n    You need to have [[https://nodejs.org/en/][Node.js]] and [[http://phantomjs.org/][PhantomJS]] installed for the\n    ClojureScript test.\n\n    Make sure you have all dependencies installed. The following\n    command installs the Maven and Node.js dependencies.\n\n    #+BEGIN_SRC sh :exports code :results silent\n      lein deps\n    #+END_SRC\n\n    To run all Clojure and ClojureScript tests run the following\n    command:\n\n    #+BEGIN_SRC sh :exports code :results silent\n      lein ci\n    #+END_SRC\n\n    For development the ClojureScript tests can be run with\n    [[https://github.com/bensu/doo][lein-doo]]. To run the tests on Node.js run the following command:\n\n    #+BEGIN_SRC sh :exports code :results silent\n      lein doo node nodejs auto\n    #+END_SRC\n\n    To run the tests on PhantomJS use this command:\n\n    #+BEGIN_SRC sh :exports code :results silent\n      lein doo phantom none auto\n    #+END_SRC\n\n*** Why is there a compiler and an interpreter?\n\n    The interpreter is executed at *run time*, and it's job is to\n    evaluate Hiccup forms and produce React elements. The compiler on\n    the other hand, is executed at *compile time* and can optimize\n    certain Hiccup forms. It's job is to evaluate Hiccup forms and\n    produce executable code.\n\n    A good introduction to this topic can be found in Peter Seibel's\n    [[http://www.gigamonkeys.com/book][Practical Common Lisp]]:\n\n    - [[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-interpreter.html][An HTML Generation Library, the Interpreter]]\n    - [[http://www.gigamonkeys.com/book/practical-an-html-generation-library-the-compiler.html][An HTML Generation Library, the Compiler]]\n\n** Thanks\n\n   This library is based on James Reeves excellent [[https://github.com/weavejester/hiccup][Hiccup]] library. The\n   server side rendering code has been taken from [[https://github.com/omcljs/om][om.next]].\n\n** License\n\n   Copyright © 2013-2020 [[https://github.com/r0man][r0man]]\n\n   Distributed under the Eclipse Public License either version 1.0 or\n   (at your option) any later version.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr0man%2Fsablono","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fr0man%2Fsablono","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fr0man%2Fsablono/lists"}