Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/johnsundell/plot

A DSL for writing type-safe HTML, XML and RSS in Swift.
https://github.com/johnsundell/plot

dsl html rss static-site-generation templating xml

Last synced: 6 days ago
JSON representation

A DSL for writing type-safe HTML, XML and RSS in Swift.

Awesome Lists containing this project

README

        


Plot




Swift Package Manager

Mac + Linux

Twitter: @johnsundell

Welcome to **Plot**, a domain-specific language (DSL) for writing type-safe HTML, XML and RSS in Swift. It can be used to build websites, documents and feeds, as a templating tool, or as a renderer for higher-level components and tools. It’s primary focus is on static site generation and Swift-based web development.

Plot is used to build and render all of [swiftbysundell.com](https://swiftbysundell.com).

## Write HTML — in Swift!

Plot enables you to write HTML using native, fully compiled Swift code, by modeling the HTML5 standard’s various elements as Swift APIs. The result is a very lightweight DSL that lets you build complete web pages in a highly expressive way:

```swift
let html = HTML(
.head(
.title("My website"),
.stylesheet("styles.css")
),
.body(
.div(
.h1("My website"),
.p("Writing HTML in Swift is pretty great!")
)
)
)
```

Looking at the above, it may at first seem like Plot simply maps each function call directly to an equivalent HTML element — and while that’s the case for *some* elements, Plot also inserts many kinds of highly valuable metadata automatically. For example, the above expression will result in this HTML:

```html


My website






My website


Writing HTML in Swift is pretty great!



```

As you can see above, Plot added both all of the necessary attributes to load the requested CSS stylesheet, along with additional metadata for the page’s title as well — improving page rendering, social media sharing, and search engine optimization.

Plot ships with a very wide coverage of the HTML5 standard, enabling all sorts of elements to be defined using the same lightweight syntax — such as tables, lists, and inline text styling:

```swift
let html = HTML(
.body(
.h2("Countries and their capitals"),
.table(
.tr(.th("Country"), .th("Capital")),
.tr(.td("Sweden"), .td("Stockholm")),
.tr(.td("Japan"), .td("Tokyo"))
),
.h2("List of ", .strong("programming languages")),
.ul(
.li("Swift"),
.li("Objective-C"),
.li("C")
)
)
)
```

Above we’re also using Plot’s powerful composition capabilities, which lets us express all sorts of HTML hierarchies by simply adding new elements as comma-separated values.

## Applying attributes

Attributes can also be applied the exact same way as child elements are added, by simply adding another entry to an element’s comma-separated list of content. For example, here’s how an anchor element with both a CSS class and a URL can be defined:

```swift
let html = HTML(
.body(
.a(.class("link"), .href("https://github.com"), "GitHub")
)
)
```

The fact that attributes, elements and inline text are all defined the same way both makes Plot’s API easier to learn, and also enables a really fast and fluid typing experience — as you can simply type `.` within any context to keep defining new attributes and elements.

## Type safety built-in

Plot makes heavy use of Swift’s advanced generics capabilities to not only make it *possible* to write HTML and XML using native code, but to also make that process completely type-safe as well.

All of Plot’s elements and attributes are implemented as context-bound *nodes*, which both enforces valid HTML semantics, and also enables Xcode and other IDEs to provide rich autocomplete suggestions when writing code using Plot’s DSL.

For example, above the `href` attribute was added to an `` element, which is completely valid. However, if we instead attempted to add that same attribute to a `

` element, we’d get a compiler error:

```swift
let html = HTML(.body(
// Compiler error: Referencing static method 'href' on
// 'Node' requires that 'HTML.BodyContext' conform to
// 'HTMLLinkableContext'.
.p(.href("https://github.com"))
))
```

Plot also leverages the Swift type system to verify each document’s element structure as well. For example, within HTML lists (such as `


    ` and `