jsml-davidystephenson
v0.0.23
Published
Render HTML from JavaScript.
Downloads
12
Readme
JSML
A JavaScript Markup Language implementation.
Installation
npm install jsml-davidystephenson
Usage
const jsml = require('jsml-davidystephenson')
jsml('hello world')
// 'hello world'
jsml({})
// '<div></div>'
const jsml({ child: 'hello world' })
// '<div>hello world</div>'
jsml({ tag: 'h1' child: 'Welcome!' })
// <h1>Welcome!</h1>
jsml({ tag: 'img', src: 'imgur.com' })
// <img src='imgur.com'>
const format = name => [
{ tag: 'h3', class: 'title', child: 'User page' },
{ tag: 'p', child: `Welcome ${name.toUppercase()}.`}
]
jsml(format('someone'))
// '<h3 class="title">User page</h3> <p>Welcome SOMEONE.</p>'
Strings
Strings return themselves.
jsml('hello world')
// 'hello world'
Numbers
Numbers are converted to strings.
jsml(8675309)
// '8675309'
Functions
Functions are run, and if they return an output, it is converted and returned.
const fn = () => 2 + 2
jsml(fn)
// '4'
Arrays
Array elements are converted individually and then returned as a joined string.
jsml([1, ' ', 2, ' 3 ', 4])
// '1 2 3 4'
jsml([
'first ',
() => 2,
[' third ', 4]
])
// 'first 2 third 4'
Array elements that are not strings, numbers, functions, arrays, objects, are ignored.
jsml([
'first ',
true,
false,
() => 2,
null,
' third',
])
// 'first 2 third'
Objects
Objects return HTML elements.
The object's tag
property is the element type.
jsml({ tag: 'p' })
// '<p></p>'
If no tag
property is provided, the element type will be div
.
const element = jsml({})
// '<div></div>'
The child
property contains the element's text and children.
jsml({ tag: 'p', child: 'hello world' })
// '<p>hello world</p>'
The 'child' value can be a string for text, an object for an element, or an array for multiple nodes.
jsml({
child: [
"I'm a container",
{
child: {
tag: 'p',
child: "I'm the content"
}
}
]
})
// '<div>I'm a container<p>I'm the content</p></div>'
All other properties become attributes of the element. If a properties value is a populated string, number, function, array, or object, it is converted and set as the attribute's value.
If the value is an array, the elements are joined by a space.
const button = jsml({
tag: 'button',
type: 'button',
class: ['btn', 'btn-default', 2 + 2],
child: () => 'Click Me!'
})
// '<button type="button" class="btn btn-default 4">Click Me!</button>'
jsml({
class: 'container',
child: [
{ tag: 'h1', child: 'Call to Action' },
'A summarizing description',
{ tag: 'img', src: '/public/logo.png' },
button
]
})
// '<div class="container"><h1>Call to Action</h1>A summarizing description<img src="/public/logo.png"><button type="button" class="btn btn-default 4">Click Me!</button></div>'
If the value is a populated object, its properties are each added with the key concatenated with the parent's key using dashes. This logic is applied recursively, allowing object values to be nested within object values.
jsml({ data: { one: 'a', two: 'b' }, aria: { hidden: 'true' } })
// '<div data-one="a" data-two="b" aria-hidden="true"></div>'
const nested = {
x: {
y: {
a: 1,
b: 2
},
z: {
c: {
d: 3,
invalid: false
}
}
}
}
jsml(nested)
// '<div x-y-a="1" x-y-b="2" x-z-c-d="3"></div>'
If the value is an empty string or the boolean true
, the property is added without a value.
jsml({ tag: 'option', disabled: '', selected: true, child: "pick something else" })
// '<option disabled selected>pick something else</option>
If the value is anything else, the property is ignored.
jsml({ layout: null, horizontal: {}, disabled: true, something: false, else: 'true' })
// '<div else="true"></div>'
When building a self-closing element, the child
property will be added as an HTML attribute.
jsml({
tag: 'meta',
name: 'viewport',
child: ['width=device-width,', 'initial-scale=1']
})
// '<meta name="viewport" child="width=device-width, initial-scale=1">'
class
attributes can be specified with either the class
or the className
property. If a className
is provided, the class
property is ignored.
jsml({ class: 'hero', child: 'Welcome!' })
// '<div class="hero">Welcome!</div>'
jsml({ tag: 'img', className: 'icon' })
// '<img class="icon">'
jsml({ class: 'inactive', className: 'active' })
// '<div class="active"></div>'