An awesome Swift HTML DSL library using result builders.
import SwiftHtml
let doc = Document(.html) {
Html {
Head {
Title("Hello Swift HTML DSL")
Meta().charset("utf-8")
Meta().name(.viewport).content("width=device-width, initial-scale=1")
Link(rel: .stylesheet).href("./css/style.css")
}
Body {
Main {
Div {
Section {
Img(src: "./images/swift.png", alt: "Swift Logo")
.title("Picture of the Swift Logo")
H1("Lorem ipsum")
.class("red")
P("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
.class(["green", "blue"])
.spellcheck(false)
}
A("Download SwiftHtml now!")
.href("https://github.com/binarybirds/swift-html/")
.target(.blank)
.download()
Abbr("WTFPL")
.title("Do What The Fuck You Want To Public License")
}
}
.class("container")
Script().src("./js/main.js").async()
}
}
}
let html = DocumentRenderer(minify: false, indent: 2).render(doc)
print(html)
Install
You can simply use SwiftHtml as a dependency via the Swift Package Manager:
You can define your own custom tags by subclassing the Tag or EmptyTag class.
You can follow the same pattern if you take a look at the core tags.
open class Div: Tag {
}
// <div></div> - standard tag
open class Br: EmptyTag {
}
// <br> - no closing tag
By default the name of the tag is automatically derived from the class name (lowercased), but you can also create your own tag type & name by overriding the createNode() class function.
open class LastBuildDate: Tag {
open override class func createNode() -> Node {
Node(type: .standard, name: "lastBuildDate")
}
}
// <lastBuildDate></lastBuildDate> - standard tag with custom name
It is also possible to create tags with altered content or default attributes.
open class Description: Tag {
public init(_ contents: String) {
super.init()
setContents("<![CDATA[" + contents + "]]>")
}
}
// <description><![CDATA[lorem ipsum]]></description> - content wrapped in CDATA
open class Rss: Tag {
public init(@TagBuilder _ builder: () -> Tag) {
super.init(builder())
setAttributes([
.init(key: "version", value: "2.0"),
])
}
}
// <rss version="2.0">...</rss> - tag with a default attribute
Attribute management
You can set, add or delete the attributes of a given tag.
Leaf("example")
// set (override) the current attributes
.setAttributes([
.init(key: "a", value: "foo"),
.init(key: "b", value: "bar"),
.init(key: "c", value: "baz"),
])
// add a new attribute using a key & value
.attribute("foo", "example")
// add a new flag attribute (without a value)
.flagAttribute("bar")
// delete an attribute by using a key
.deleteAttribute("b")
// <leaf a="foo" c="baz" foo="example" bar></leaf>
You can also manage the class atrribute through helper methods.
Span("foo")
// set (override) class values
.class("a", "b", "c")
// add new class values
.class(add: ["d", "e", "f"])
// add new class value if the condition is true
.class(add: "b", true)
/// remove multiple class values
.class(remove: ["b", "c", "d"])
/// remove a class value if the condition is true
.class(remove: "e", true)
// <span class="a f"></span>
You can create your own attribute modifier via an extension.
Sometimes you’ll need extra parameters for the build function, so you have to call the build method by hand.
In those cases it is recommended to introduce a render function instead of using build.
let tag = WebIndexTemplate(ctx) {
ListComponent(["a", "b", "c"])
.render(req)
}
.render(req)
If you want to create a lightweight template engine for the Vapor web framework using SwiftHtml, you can see a working example inside the Feather CMS core repository.
SwiftHtml
An awesome Swift HTML DSL library using result builders.
Install
You can simply use
SwiftHtml
as a dependency via the Swift Package Manager:Add the
SwiftHtml
product from theswift-html
package as a dependency to your target:Import the framework:
That’s it.
Creating custom tags
You can define your own custom tags by subclassing the
Tag
orEmptyTag
class.You can follow the same pattern if you take a look at the core tags.
By default the name of the tag is automatically derived from the class name (lowercased), but you can also create your own tag type & name by overriding the
createNode()
class function.It is also possible to create tags with altered content or default attributes.
Attribute management
You can set, add or delete the attributes of a given tag.
You can also manage the class atrribute through helper methods.
You can create your own attribute modifier via an extension.
There are other built-in type-safe attribute modifiers available on tags.
Composing tags
You can come up with your own
Tag
composition system by introducing a new protocol.This way it is also possible to extend the
TagBuilder
to support the new protocol.Sometimes you’ll need extra parameters for the build function, so you have to call the build method by hand.
In those cases it is recommended to introduce a
render
function instead of using build.If you want to create a lightweight template engine for the Vapor web framework using SwiftHtml, you can see a working example inside the Feather CMS core repository.
Credits & references