NOTE: this website was build using Miraj. The source code is available at: miraj-project/homepage . Many other simple examples with commented code are available at miraj-project/demos/hello-world

Components can also be easily defined as one-off elements for use in a single page. Both page and components can be defined in the same project.

Miraj also makes it very easy to define and share component libraries. Multiple components may be defined across multiple namespaces; a deflibrary macro then assembles any combination of components into a library namespace, which is independent of the defining namespaces. Miraj can automatically generate a demo page for previewing/testing components under development.

Things get a little more complicated when you add web components. Miraj allows the programmer to define and use Polymer-based components in idiomatic Clojure, without having to worry about the directory structures, file names, and href values required to make the generated HTML, Javascript and CSS files work together.

Providing Clojure functions for HTML elements is relatively trivial. Miraj also provides macros that make page and component definitions look similar to the deftype and defrecord constructions of Clojure.

Clojurescript already eliminates the need to program in Javascript; Miraj does the same for HTML. (A genuine Clojure face for CSS programming remains a future project).

Miraj eliminates mixed-language programming, allowing the programmer to define pages and components in Clojure. Miraj compiles this Clojure code into HTML, Javascript, and CSS.

An HTML page is analogous to a Clojure program of one function, main. In particular, the <link> and <script> elements in the <head> element are analogous to the :require and :import directives of Clojure's ns macro: they tell the runtime to find, fetch, and load the referenced resources.

The goal of the Miraj Project is to create a pure Clojure, 100% functional programming model for web application development, including first-class support for defining and using Web Components ( Polymer only for this version).

Pass HTML metadata as a Clojure map; Miraj will validate the map against Clojure.spec specifications (which may be found in miraj_spec.clj and miraj/x/ , and then transform it into the appropriate elements in <head>.

BigInt and BigDecimal end up looking like Int and Decimal:

With a few exceptions, clojure attribute values go through normal Clojure evaluation and then are serialized as strings. You can use expressions as attribute values:

Use the Unicode character \uFEFF, 'ZERO WIDTH NO-BREAK SPACE', to force display of the delimiters without Polymer interpretation:

if you are using Polymer, you must escape opening double bracesand bracketsif you want to display them in a string, since Polymer treats these as special "binding annotations" (see polymer for more info). I.e. if you put something inside double braces or brackets, it will be interpreted as a property and will be displayed as null if it has no value:

Character entity references like € require special handling, since & is automatically escaped. Use the Unicode literal (for example, \u20AC for the Euro sign, €). You can embed character literals directly, or you can use ordinary Clojure definitions or bindings to get names:

HTML5 empty elements must not be self-closing; they must have a close tag. Miraj understands empty elements:

HTML5 void elements cannot have any content; they also cannot be "self-closing"; they may only have a start tag with no '/'. Miraj understands void elements:

The miraj.html library wraps the lower-level miraj.co-dom library, providing one function per HTML5 element, as well as some additional goodies.

See the Hello World demos for many examples.

Polymer

Currently Miraj only supports Polymer version 1; support for the recently-released version 2 is in development.

Miraj provides a library, miraj.polymer, that supports features specific to Polymer. For example, it supports Polymer bindings, helper elements, and Event protocols.

Polymer Component Libraries In addition, Miraj provides a collection of pre-built libraries for the collection of components built by the Polymer Project. These libraries wrap the native Polymer implementations, which can be found at webcomponents.org Warning: only the iron and paper libraries are fully up to date; the remaining libraries are outdated, but will soon be upgraded. miraj.polymer.iron "Basic building blocks for creating an application." (iron-elements)

miraj.polymer.paper Material design UI elements. (paper-elements)

miraj.polymer.gold "Elements built for e-commerce-specific use-cases, like checkout flows." (gold-elements)

miraj.polymer.google

miraj.polymer.layout

miraj.polymer.molecules

miraj.polymer.neon

miraj.polymer.platinum

Polymer Assets The assets that implement Polymer components are package in miraj.polymer.assets ; this library contains everything you would get if you installed using bower, packaged as a jarfile so the assets become available. via the classpath. Each of the miraj.polymer.* libraries has a dependency on this library, so the user never needs to import it directly. To serve your component-based application statically, or using a non-Java server, you must copy the assets your app needs to a folder on the server's search path. The boot-miraj/assetize task will copy the contents of the miraj.polymer.assets jar to the filesystem. Alternatively, you can use bower to install the components you need, but the path to them must be miraj/polymer/assets.

Using Polymer Components To use a Polymer component in a webpage, include the library as a dependency in your boot/leiningen project file, and then :require it in your Clojure namespace, just like any other library: (ns foo.bar ...) (defpage baz (:require [miraj.polymer.paper :as paper :refer [button card]]) ...) See the Polymer hello-world demo for more detailed examples. Miraj generally follows a simple naming convention for Polymer components: <foo-bar> becomes miraj.polymer.foo/bar. For example, paper-button maps to miraj.polymer.paper/button. In some cases, another ns segment is used; for example, the function for <paper-input-container> is miraj.polymer.paper.input/container . (Documentation is incomplete, but the library source code is easily understandable.) Data Binding Helper Elements Polymer's data binding helper elements –<dom-if>, <dom-repeat>, etc. – are implemented in miraj.polymer . Some of the names have been changed to be more consistent with Clojure practice; for example, for <array-selector> we use miraj.polymer/selection. See the source code for the complete list.