All Projects → davidjamesstone → Superviews.js

davidjamesstone / Superviews.js

Template engine targeting incremental-dom

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to Superviews.js

Switzerland
🇨🇭Switzerland takes a functional approach to Web Components by applying middleware to your components. Supports Redux, attribute mutations, CSS variables, React-esque setState/state, etc… out-of-the-box, along with Shadow DOM for style encapsulation and Custom Elements for interoperability.
Stars: ✭ 261 (+7.85%)
Mutual labels:  virtual-dom, webcomponents
Panel
Web Components + Virtual DOM: web standards for powerful UIs
Stars: ✭ 206 (-14.88%)
Mutual labels:  virtual-dom, webcomponents
lego
🚀 Web-components made lightweight & Future-Proof.
Stars: ✭ 69 (-71.49%)
Mutual labels:  virtual-dom, webcomponents
Dna
Progressive Web Components.
Stars: ✭ 22 (-90.91%)
Mutual labels:  virtual-dom, webcomponents
Ioing
Implement the solutions of performance improvement and componentization for your SPA (single page application) products with this Progressive Web App Development Engine.
Stars: ✭ 224 (-7.44%)
Mutual labels:  virtual-dom, webcomponents
Omi
Front End Cross-Frameworks Framework - 前端跨框架跨平台框架
Stars: ✭ 12,153 (+4921.9%)
Mutual labels:  virtual-dom, webcomponents
Virtual Dom
The foundation of HTML and SVG in Elm.
Stars: ✭ 196 (-19.01%)
Mutual labels:  virtual-dom
Hydux
A light-weight type-safe Elm-like alternative for Redux ecosystem, inspired by hyperapp and Elmish
Stars: ✭ 216 (-10.74%)
Mutual labels:  virtual-dom
Myscript Math Web
✏️ ☁️ The easy way to integrate mathematical expressions handwriting recognition in your web app.
Stars: ✭ 194 (-19.83%)
Mutual labels:  webcomponents
Riot
Simple and elegant component-based UI library
Stars: ✭ 14,596 (+5931.4%)
Mutual labels:  webcomponents
Htl Spec
HTML Template Language Specification
Stars: ✭ 213 (-11.98%)
Mutual labels:  template-language
H Include
Declarative client-side inclusion for the Web, using Custom Elements V1
Stars: ✭ 187 (-22.73%)
Mutual labels:  webcomponents
Svg Patterns
SVG patterns for Data Visualization.
Stars: ✭ 201 (-16.94%)
Mutual labels:  virtual-dom
Golymer
Web components with golang (gopherjs) moved to gitlab.com/microo8/golymer
Stars: ✭ 220 (-9.09%)
Mutual labels:  webcomponents
Markuplint
A Linter for All Markup Languages.
Stars: ✭ 193 (-20.25%)
Mutual labels:  webcomponents
Htmlkit
A type-safe DSL that renders dynamic HTML templates in Swift
Stars: ✭ 229 (-5.37%)
Mutual labels:  template-language
Milk
Milk is Mustache in CoffeeScript -- great with your browser or NodeJS!
Stars: ✭ 192 (-20.66%)
Mutual labels:  template-language
Standalone
Create framework agnostic components that are truly reusable and interoperable with all the benefits of the React ecosystem – using the HTML5 custom elements API to extend HTML's vocabulary.
Stars: ✭ 205 (-15.29%)
Mutual labels:  webcomponents
Preact Worker Demo
Demo of preact rendering an entire app in a Web Worker.
Stars: ✭ 204 (-15.7%)
Mutual labels:  virtual-dom
Slang
Slim-inspired templating language for Crystal
Stars: ✭ 200 (-17.36%)
Mutual labels:  template-language

NEW! Try hyperviews instead. The same declarative template language as superviews.js but for any h(tag, props, children) compliant framework like React, hyperapp, preact....

superviews.js

On the server superviews.js is used as a template engine for google's incremental-dom.

It can also now be used in the browser to help build web applications based on Custom Elements V1

Try it out live in your browser

npm install superviews.js --save

API

tmplstr (required) - The template string.
name - The output function name (will be overridden with a <template> element).
argstr - The output function arguments (will be overridden with a <template> element).
mode - The output format. Can be one of ['es6', 'cjs', 'browser', 'amd'], if any other value is passed the function is exported as a variable with that name.

superviews(tmplstr, name, argstr, mode)

CLI

cat examples/test.html | superviews --mode=es6 --name=foo --argstr=bar > examples/test.js

Client

NEW! superviews can now be used in the browser.

Use it as a clientside library with a set of helpful classes and methods for building web applications based on the Web Components spec, specifically Custom Elements V1.

Example

Create a file called tmpl.html

<!--
If the outermost element is a `template` element and contains
an `args` attribute it will be used as the function definition.
A `name` attribute can also be supplied. These will be used to
define the enclosing function name and arguments in the incremental-dom output (see below).
-->
<template name="myWidget" args="data todos foo bar">

  <!--
  `script` tags that have no attributes are treated as literal javascript
  and will be simply inlined into the incremental-dom output.
  -->
  <script>
  function add (item) {
    todos.push(item)
  }

  function remove () {
    todos.pop()
  }
  </script>

  <!-- Attribute values can be set using javascript between curly braces {} -->
  <div class="{data.cssClass}">

    <!-- Attributes are omitted if their expression is null or undefined. Useful for `checked`, `disabled` -->
    <input type="text" disabled="{data.isDisabled}">

    <!-- Interpolation in attributes -->
    <a href="http://www.google.co.uk?q={data.query}"></a>

    <!-- Text Interpolation -->
    My name is {data.name} my age is {data.age}
    I live at {data.address}

    <!-- Any javascript can be used -->
    <div title="{JSON.stringify(data)}">Hover for json</div>

    <!-- 'on' event handlers. $event and $element are available to use in the handler. -->
    <button onclick="{alert(hi)}">Say hi</button>
    <input type="text" value="{data.val}" onchange="{data.val = this.value}">
    <a href="#" onclick="{$event.preventDefault(); model.doSomething();}">Some link</a>

    <!-- Use an `if` attribute for conditional rendering -->
    <p if="data.showMe">
      <span class="{data.bar + ' other-css'}">description</span>
    </p>

    <!-- An `if` tag can also be used for conditional
    rendering by adding a `condition` attribute. -->
    <if condition="data.showMe">
      I'm in an `if` block.
    </if>

    <!-- `elseif` and `else` tags can also be used -->
    <if condition="data.foo === 1">
      <span>1</span>
    <elseif condition="data.foo === 2">
      <span>2</span>
    <else>
      Default
    </if>

    <!-- Use a `skip` attribute for conditional patching of children -->
    <aside>
      <div skip="data.skipMe">
        <span id="{data.id}">
        </span>
      </div>
    </aside>

    <!-- The `style` attribute is special and can be set with an object. -->
    <span style="{ color: data.foo, backgroundColor: data.bar }">My style changes</span>

    <!-- The `each` attribute can be used to repeat over items.
    This includes iterating over keys on an Object or any object that has a
    forEach function e.g. an Array, Map, Set.
    Three variables are available for each iteration: $value, $item and $target.-->
    <ul>
      <li each="item in data.items">
        <span class="{ $item % 2 ? 'odd' : 'even' }">{$item}</span>
        <input value="{item.name}">
      </li>
    </ul>

    <!-- Looping over arrays -->
    <ul>
      <li each="item in data.arr">
        <span>{item.name}</span>
      </li>
    </ul>

    <!-- Looping over object keys -->
    <ul>
      <li each="key in data.obj">
        <span title="hello">{key} - {data.obj[key]}</span>
      </li>
    </ul>

    <!-- The `each` attribute also supports defining a `key` to use.
    For Arrays and Objects this is done automatically for you.
    
    If you are iterating a Map, this should be set to identify each item in the list. 
    This allow the diff patch in to keep track of each item in the list.
    See http://google.github.io/incremental-dom/#conditional-rendering/array-of-items.
    The key used here is `product.id`.
     -->
    <ul>
      <li each="product, product.id in data.products">
        {product.name}
      </li>
    </ul>

    <!-- Conditional iteration -->
    <ul>
      <li if="data.items.length" each="item, item.id in data.arr">
        {item.name}
      </li>
      <li if="!data.items.length" class="list-header">
        No items found
      </li>
    </ul>
  </div>

</template>

cat tmpl.html | superviews > tmpl.js

Converts the template above to this incremental-dom code:

;(function () {
var hoisted1 = ["type", "text"]
var hoisted2 = ["type", "text"]
var hoisted3 = ["href", "#"]
var hoisted4 = ["title", "hello"]
var hoisted5 = ["class", "list-header"]
var __target

return function myWidget (data, todos, foo, bar) {
  function add (item) {
      todos.push(item)
    }

    function remove () {
      todos.pop()
    }
  elementOpen("div", null, null, "class", data.cssClass)
    elementOpen("input", "ba1d808c-0069-43bc-a345-89d8a60fa494", hoisted1, "disabled", data.isDisabled)
    elementClose("input")
    elementOpen("a", null, null, "href", "http://www.google.co.uk?q=" + (data.query) + "")
    elementClose("a")
    text(" \
        My name is " + (data.name) + " my age is " + (data.age) + " \
        I live at " + (data.address) + " \
     \
        ")
    elementOpen("div", null, null, "title", JSON.stringify(data))
      text("Hover for json")
    elementClose("div")
    elementOpen("button", null, null, "onclick", function ($event) {
      var $element = this;
    alert(hi)})
      text("Say hi")
    elementClose("button")
    elementOpen("input", "0887e662-2503-4669-b314-2d155cc72cad", hoisted2, "value", data.val, "onchange", function ($event) {
      var $element = this;
    data.val = this.value})
    elementClose("input")
    elementOpen("a", "4308eec1-f2dc-4247-a8d6-c07e81db0c3e", hoisted3, "onclick", function ($event) {
      var $element = this;
    $event.preventDefault(); model.doSomething();})
      text("Some link")
    elementClose("a")
    if (data.showMe) {
      elementOpen("p")
        elementOpen("span", null, null, "class", data.bar + ' other-css')
          text("description")
        elementClose("span")
      elementClose("p")
    }
    if (data.showMe) {
      text(" \
            I'm in an `if` block. \
          ")
    }
    if (data.foo === 1) {
      elementOpen("span")
        text("1")
      elementClose("span")
    } else if (data.foo === 2) {
      elementOpen("span")
        text("2")
      elementClose("span")
    } else {
      text(" \
            Default \
          ")
    }
    elementOpen("aside")
      elementOpen("div")
        if (data.skipMe) {
          skip()
        } else {
          elementOpen("span", null, null, "id", data.id)
          elementClose("span")
        }
      elementClose("div")
    elementClose("aside")
    elementOpen("span", null, null, "style", { color: data.foo, backgroundColor: data.bar })
      text("My style changes")
    elementClose("span")
    elementOpen("ul")
      __target = data.items
      if (__target) {
        ;(__target.forEach ? __target : Object.keys(__target)).forEach(function($value, $item, $target) {
          var item = $value
          var $key = "163c079d-6890-40f1-8983-b4119652d7ca_" + $item
          elementOpen("li", $key)
            elementOpen("span", null, null, "class",  $item % 2 ? 'odd' : 'even' )
              text("" + ($item) + "")
            elementClose("span")
            elementOpen("input", null, null, "value", item.name)
            elementClose("input")
          elementClose("li")
        }, this)
      }
    elementClose("ul")
    elementOpen("ul")
      __target = data.arr
      if (__target) {
        ;(__target.forEach ? __target : Object.keys(__target)).forEach(function($value, $item, $target) {
          var item = $value
          var $key = "9ee2a95c-ce40-4c43-9e1b-bb1e3771c72f_" + $item
          elementOpen("li", $key)
            elementOpen("span")
              text("" + (item.name) + "")
            elementClose("span")
          elementClose("li")
        }, this)
      }
    elementClose("ul")
    elementOpen("ul")
      __target = data.obj
      if (__target) {
        ;(__target.forEach ? __target : Object.keys(__target)).forEach(function($value, $item, $target) {
          var key = $value
          var $key = "07608362-dc5c-4fca-9f46-381ffc62a929_" + $item
          elementOpen("li", $key)
            elementOpen("span", "4bf05389-7b34-4184-9ae5-2f1371d46d05_" + $key, hoisted4)
              text("" + (key) + " - " + (data.obj[key]) + "")
            elementClose("span")
          elementClose("li")
        }, this)
      }
    elementClose("ul")
    elementOpen("ul")
      __target = data.products
      if (__target) {
        ;(__target.forEach ? __target : Object.keys(__target)).forEach(function($value, $item, $target) {
          var product = $value
          var $key = "494094aa-b914-405e-b489-31348c78a2f7_" + product.id
          elementOpen("li", $key)
            text(" \
                    " + (product.name) + " \
                  ")
          elementClose("li")
        }, this)
      }
    elementClose("ul")
    elementOpen("ul")
      if (data.items.length) {
        __target = data.arr
        if (__target) {
          ;(__target.forEach ? __target : Object.keys(__target)).forEach(function($value, $item, $target) {
            var item = $value
            var $key = "f53fcb3e-8035-4108-91bc-1d7661d41681_" + item.id
            elementOpen("li", $key)
              text(" \
                      " + (item.name) + " \
                    ")
            elementClose("li")
          }, this)
        }
      }
      if (!data.items.length) {
        elementOpen("li", "39dad44a-39c4-4d2d-bb31-7daf5bef8b73", hoisted5)
          text(" \
                  No items found \
                ")
        elementClose("li")
      }
    elementClose("ul")
  elementClose("div")
}
})()

browserify

Using browserify? There's the superviewify transform allowing you to simply require your templates and have them automatically compiled to incremental-dom javascript.

npm install superviewify --save

License

MIT

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].