HTML and XML Elements
In Papercraft templates, HTML elements are generated by making receiver-less method calls, along with an optional inner text, and optional attributes. Here are some examples (along with the generated HTML):
p "Hello"
#=> <p>Hello</p>
a "About", href: "/about"
#=> <a href="/about">About</a>
input(type: "text", name: "address", disabled: true)
#=> <input type="text" name="address" disabled>
In the above examples, the method calls p, a, and input generate the
corresponding HTML elements, and use the given arguments as the inner text and
the attributes of those elements. As with any normal Ruby method call, you can
choose whether to use parentheses or to emit them.
HTML elements that contain nested elements are expressed by passing a block to the method call. Here’s an example:
div {
h1 "Title"
p {
a "About", href: "/about"
}
}
#=> <div><h1>Title</h1><p><a href="/about">About</a></p></div>
Automatic HTML Escaping
Any dynamic text passed as the inner text of an HTML tag is automatically escaped by Papercraft, preventing any cross-site scripting (XSS) attacks. An attacker may attempt to inject malicious HTML or Javascript snippets into a site in order to gain access to confidential information or perform malicious operations on user data. Papercraft’s automatic escaping of all data used in templates prevents any such attacks.
Custom HTML Tags
Papercraft allows you to easily use custom, non-standard tags in order to customize your HTML markup. This technique is useful as an alternative to specifying CSS classes or id’s. Here’s an example:
# the same, but with custom tags:
container {
left { span "foo" }
right { span "bar" }
}
#=> <container><left>...</left><right>...</right></container>
In some cases, you’d want to use the standard form for custom HTML elements
which use a hyphenated tag, e.g. book-chapter. In that case, replace the
hyphen with an underscore in your tag method call, e.g. book_chapter.
Papercraft will automatically convert any underscore in the tag back to a
hyphen.
HTML Attributes
As discussed above, HTML attributes are specified as keyword arguments:
# normal attributes:
div(class: "my-class", id: "my-id")
#=> <div class="my-class" id="my-id"></div>
# boolean attributes:
input(name: "foo", disabled: true)
#=> <input name="foo" disabled>
input(name: "foo", disabled: false)
#=> <input name="foo">
# hypenated attribute names:
p("text", "data-foo" => "bar")
#=> <p data-foo="bar">text</p>
# or:
p(data_foo: "bar")
#=> <p data-foo="bar"></p>
Using Dynamic Values in HTML Tags
Using dynamic values in tags is easy and natural. Just pass them as arguments to your tag method calls:
->(id, title, opts, body) {
card(id: id) {
h2 title, **opts
p body
}
}
Handling of Void HTML Elements
The following HTML elements are considered
void:
<area>, <base>, <br>, <col>, <embed>, <hr>, <img>, <input>,
<link>, <meta>, <param>, <source>, <track>, <wbr>. Void elements
cannot contain any child elements, or any inner text. They will be rendered
without a closing tag:
Papercraft.html { input type: 'password' }
#=> '<input type="password">'
Attempting to render a void element with child elements or inner text will cause Papercraft to raise an exception:
Papercraft.html { input "foo" }
#=> BOOM: Void element input cannot contain child nodes or inner text
Handling of Void XML Elements
When rendering XML, any element that does not have any child nodes or inner text will be rendered as self-closing:
Papercraft.xml { link foo: "bar" }
#=> '<link foo="bar"/>'

