swift-website-dsl
is a domain specific language (DSL) library for building websites using the Swift programming language.
While some website DSLs built in Swift abstract away HTML/CSS, this DSL doesn't. This library keeps the elements of HTML/CSS while providing the elegance of writing code in a style like SwiftUI and with the type safety of Swift. The result is a DSL that encodes the HTML spec and keeps is rooted in the familiarity of website development but leverages the power the Swift language to make it more enjoyable and less error prone.
The Swifty Notes website is an example of a site written using this library. Here is a code snippet to see what using this library is like
Html {
Head(title: "SwiftyNotes", cssStyleFileName: "CodeColors.css")
Body {
SiteHeader()
SiteNotes()
Footer {
P("Jason Zurita © 2024 | Built in Swift and ") {
A(copy: "open source.", url: "https://github.com/jasonzurita/swiftynotes")
}
}
.textAlign(.center)
.color(.mediumGray)
}
.font(.apple)
.textAlign(.center)
.background(.color(.lightGray))
.margin(0)
.padding(0)
}
To test out the DSL using the provided example website
- Open terminal
- Clone this repo
git clone https://github.com/jasonzurita/swift-website-dsl
- Change directories to the cloned project
cd <path>/swift-website-dsl
- Generate the example website
swift run
- Open the generated website in your browser
open _site/index.html
Congrats 🥳. Try and make changes to the example site, swift run
again, and refresh your browser!
Note: The example website and swiftynotes project setup are good examples to follow along with the below steps
- Add the swift-website-dsl to your package.swift manifest
dependencies: [ .package(url: "https://github.com/jasonzurita/swift-website-dsl.git", from: "1.0.0"), ]
- Make use of the library in the desired target
.product(name: "SwiftWebsiteDSL", package: "swift-website-dsl"),
- Import the library to get access to all the HTML elements and styling modifiers
import SwiftWebsiteDSL
- To generate your website
- Create a
main.swift
file like this - This step will define the output folder for the generated site. For example, the example website uses
_site
- Create a
- Make your website module an executable in your package.swift
products: [ .executable(name: "<your-site-name>", targets: ["<your-site-target-name>"]), ],
- To build and generate the site
swift run
from the root directory
There are two Swift modules in this repo: the example website, and the HTML eDSL.
The HTML embedded domain specific language (eDSL) was build using Swift's Result Builders to be SwiftUI like in its syntax. Knowing about HTML will help in knowing the provided elements like body and what styles can be used.
This module consumes the above HTML eDSL library. The result is a fully Swift defined site along with styling. When swift run
is invoked, this module runs as an executable and generates HTML that is ready to be statically hosted and consumed by browsers.
The building block elements (e.g., H and Body tags) are individually generated in tests (including styles) and then text snapshotted using the Point-Free Snapshot Testing library. The result is that there is a high level of code coverage and that each element is locked in with the generated output HTML and given style. This further ensures the HTML spec is codified and won't break when making changes to the library. Check out the snapshots and tests.
Tests can be run locally and also automatically run in CI via the test workflow.
The output of the _site
directory is a ready to go static website! For example, the SwiftyNotes site is hosted using CloudFlare pages as a static website. When a new commit is pushed to the main branch, GitHub Actions runs the tests, builds the website, and then uploads the generated site (the _site
directory) for CloudFlare to host it 🚀!