Getting started with static-site generation in Swift using Publish
Publish is an open source static-site generator written entirely in swift. Together with Ink and Plot, it enables to implement whole websites in swift. Thereby, Ink is responsible for parsing markdown syntax into html, while Plot is a domain specific language (DSL) to define html documents using conventional swift syntax. Both features in itself are incredibly powerful, but their combination into the Publish static-site generator brings them onto an even higher level.
So how do you generate your first static website using Publish? There are a number of possibilites to getting started, but the most convenient way is using the publish
Command Line Interface (CLI). To start the setup process, clone the publish github repository.
git clone https://github.com/JohnSundell/Publish.git
Once the repository is checked out, enter the directory and run make
to build and install the CLI.
cd publish
make
The publish CLI is now installed and you can use it to generate the necessary project structure for a new publish website. Leave the publish repository, then create a folder named after your project. Let's use Homepage
as an example. Enter the project directory and initialize the publish project using the CLI command new
.
cd Homepage
publish new
Open Package.swift
in XCode to inspect the generated files. You'll see a number of files and folders. Package.swift
is the swift package description and contains information on your project targets and its dependencies. You can learn more about swift packages and the Swift Package Manager (SPM) in the official SPM documentation or an excellent post by John Sundell. The folder Content
contains markdown files which are one way to define your website's content. The folder Resources
contains any resources for your project such as images, videos or css files. Finally, the folder Source
contains the actual website description. Open the main.swift
file, to have a look at the website description.
import Foundation
import Publish
import Plot
// This type acts as the configuration for your website.
struct Homepage: Website {
enum SectionID: String, WebsiteSectionID {
// Add the sections that you want your website to contain here:
case posts
}
struct ItemMetadata: WebsiteItemMetadata {
// Add any site-specific metadata that you want to use here.
}
// Update these properties to configure your website:
var url = URL(string: "https://your-website-url.com")!
var name = "Homepage"
var description = "A description of Homepage"
var language: Language { .english }
var imagePath: Path? { nil }
}
// This will generate your website using the built-in Foundation theme:
try Homepage().publish(withTheme: .foundation)
As you see, the struct Homepage
implements the Website
protocol and defines the general structure of the website. The SectionID
enum is used to define the different sections of the website. The struct ItemMetadata
is used to define additional metadata types for your website items. Sections and Items are related in a parent child relationship, meaning that any section may have multiple items (e.g. posts), but an item is related to exactly one section. For now, the struct is empty, meaning that we do not define additional item metadata. Down the line, there are a number of additional properties to define the url you want to use for your website, its name, a description of your website, its main language as well as an image path that is used to represent your website if it's linked on social networks.
The website is then generated by creating an instance of Homepage
and publishing it with the given theme. For now, the built-in foundation
theme is used. Note however, that in general, you'll want to implement your own theme for your website. We'll explore theme creation as well as advanced publishing pipelines in a future post.
For now, have a look at your initial website by running
publish run
and opening http://localhost:8000 in your browser.
Congratulations, you generated your first static-site in Swift using Publish! You can now add new sections in your website description or add new posts by adding additional markdown files in your Content
folder.
Happy coding, see you next time!