With Hugo, Eleventy, Astro and a dozen more well-maintained static site generators out there, I built this site with Publish, by John Sundell. It is a debatable decision, so let me explain it.
The reason, beyond not wanting anything to do with WordPress
Publish lets me define the site as a struct:
struct DavidNovella: Website {
enum SectionID: String, WebsiteSectionID {
case apps
case blog
}
var url = URL(string: "https://davidnovella.es")!
var name = "David Novella"
var language: Language { .spanish }
}
And the theme as functions that return HTML, with the compiler keeping watch:
func makeItemHTML(for item: Item<Site>,
context: PublishingContext<Site>) throws -> HTML {
HTML(
.lang(context.site.language),
.head(for: item, on: context.site),
.body {
SiteHeader(currentPath: item.path)
Wrapper {
H1(item.title)
Div(item.body).class("content")
}
}
)
}
There are no templates with double braces and no errors that only show up at build time. If I make up a metadata field, it does not compile. It is the same feeling as working with SwiftUI, applied to HTML.
The drawbacks
They are worth stating:
- Publish has not been updated in a while. The latest tagged version is 0.9.0. It compiles without trouble on Swift 6.4, but do not expect fixes.
- The community is small. Compared with Hugo there is little written about it and few themes to crib from.
- The plugin ecosystem is minimal. Whatever you need, you will probably have to write yourself — although writing a
PublishingSteptakes surprisingly little code.
Conclusion
As an exercise in building a site I can maintain with little effort, I think it is a good start. Further down the line I will see whether I have to move to another generator or fork Publish and change a thing or two.