https://github.com/anko/whatxml
LiveScript library for XML/HTML templating using cascades
https://github.com/anko/whatxml
dsl html livescript template-engine xml
Last synced: 3 months ago
JSON representation
LiveScript library for XML/HTML templating using cascades
- Host: GitHub
- URL: https://github.com/anko/whatxml
- Owner: anko
- License: isc
- Created: 2014-07-24T19:26:00.000Z (over 11 years ago)
- Default Branch: master
- Last Pushed: 2019-02-28T03:17:23.000Z (about 7 years ago)
- Last Synced: 2025-03-05T21:11:15.270Z (about 1 year ago)
- Topics: dsl, html, livescript, template-engine, xml
- Language: LiveScript
- Homepage:
- Size: 57.6 KB
- Stars: 1
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: readme.markdown
- License: LICENSE
Awesome Lists containing this project
README
# whatxml
XML/HTML templating with [LiveScript][1]'s [cascade][2] syntax.
"What XML?" *None, ever again.*
[][3]
[][4]
[][5]
```ls
x = whatxml \html
.. \head
.. \title ._ "My page"
..self-closing \link rel : \stylesheet type : \text/css href : \main.css
.. \body
.. \p ._ (.content)
console.log x.to-string { content : "Here's a paragraph." }
```
→
```html
My page
Here's a paragraph.
```
## API summary
- `.. []` adds a tag (with optional attributes)
- `..self-closing []` same, but a self-closing tag
- `.. ` sets attributes
- `.._ ` adds text
- `..raw ` adds text (without escaping it)
- `..comment ` adds a comment
`to-string` recursively renders that tag's tree.
Any of the setters can also take a function parameter which is called with the
value passed to `to-string`. It is expected to return the value that should be
inserted at that point. (See [§ *Templating*][6].)
## API tutorial
### Basics
Create a **root tag**, call it with a `string` to create **child tags**, with
an `object` to **add attributes** or call `_` to **add text** between the tags.
```ls
gandalf = whatxml \person # Create a root tag.
.. { profession : \wizard } # Set an attribute.
.. \name # Add a child node.
.._ "Gandalf" # Put text in it.
console.log gandalf.to-string!
```
```xml
Gandalf
```
Handy shortcut: When creating a tag, pass attributes as an object.
```ls
t = whatxml \tower lean : "3.99"
.. \place city : "Pisa", country : "Italy"
console.log t.to-string!
```
```xml
```
Add **self-closing tags** and **comments**.
```ls
x = whatxml \a
..self-closing \b
..comment "what"
console.log x.to-string!
```
You can have **stand-alone attributes** without a value by setting them to
`true`. ([It's invalid XML][7], but fine in HTML.)
```ls
whatxml \input { +selected }
..to-string! |> console.log
```
```ls
```
Setting an attribute to another value overwrites the previous value. Setting
attributes to `false`, `null` or `undefined` removes that attribute, if
present.
Text is **escaped automatically**, but you can **bypass** that with `raw` if
you have ready-escaped text (e.g. from [`marked`][8]).
```ls
greeting = whatxml \p
.._ "What's up <3"
console.log greeting.to-string!
x = whatxml \p
..raw "I know this is > properly escaped already"
console.log x.to-string!
```
```xml
What's up <3
I know this is > properly escaped already
```
You can also have **multiple top-level tags**:
```ls
x = whatxml!
.. \a
.. \b
console.log x.to-string!
```
### Templating
To **generate content based on data**, you can pass a function to any setter
call. When a tag's `to-string` is called, the functions passed to its setters
before are called with its arguments to produce the final value.
```ls
link = whatxml \a href : (.href)
.._ (.name.to-upper-case!)
console.log link.to-string name : \google href : "https://google.com"
console.log link.to-string name : \runescape href : "http://runescape.com"
```
## Limitations
Check your XML comments are [valid by the XML spec][9]: They may not contain
two consecutive hyphens (`--`). Whatxml doesn't check for you.
[`CDATA`-sections][10] and XML declarations (`` and such)
aren't explicitly supported, but you can happily add them using `raw`.
## Related libraries
Whatxml aims to be a serious general-purpose XML/HTML templating engine for
[LiveScript][11]'s syntax.
Existing attempts have their flaws:
- [`live-templ`][12] came closest to my goals, but objects in nested arrays
cannot represent comments, raw text data or self-closing tags. It also has
no templating.
- [`create-xml-ls`][13] is based on nested objects, so it can't represent two
tags with the same name on the same level of nesting…
- [`htmls`][14] supports only the base HTML tag set. Templating code is
[stringly typed][15] and compiled separately.
[1]: http://livescript.net/
[2]: http://livescript.net/#property-access-cascades
[3]: https://www.npmjs.com/package/whatxml
[4]: https://travis-ci.org/anko/whatxml
[5]: https://david-dm.org/anko/whatxml
[6]: #templating
[7]: http://stackoverflow.com/questions/6926442/is-an-xml-attribute-without-value-valid
[8]: https://github.com/chjj/marked
[9]: http://www.w3.org/TR/2006/REC-xml11-20060816/#sec-comments
[10]: http://en.wikipedia.org/wiki/CDATA
[11]: http://livescript.net/
[12]: https://www.npmjs.org/package/live-tmpl
[13]: https://www.npmjs.org/package/create-xml-ls
[14]: https://www.npmjs.org/package/htmls
[15]: http://c2.com/cgi/wiki?StringlyTyped