Publish – A Static Site Generator for Swift Developers

Welcome to Publish, a static site generator built specifically for Swift developers. It enables entire websites to be built using Swift, and supports themes, plugins and tons of other powerful customization options. Publish is used to build all of swiftbysundell.com. Websites as Swift packages When using Publish, each website is defined as a Swift package, which acts as the configuration as to how the website should be generated and deployed — all using native, type-safe Swift code. For example, here’s what the configuration for a food recipe website might look like: struct DeliciousRecipes: Website { enum SectionID: String, WebsiteSectionID { case recipes case links case about } struct ItemMetadata: WebsiteItemMetadata { var ingredients: [String] var preparationTime: TimeInterval } var url = URL(string: “https://cooking-with-john.com“)! var name = “Delicious Recipes“ var description = “Many very delicious recipes.“ var language: Language { .english } var imagePath: Path? { “images/logo.png“ } } Each website built using Publish can freely decide what kind of sections and metadata that it wants to support. Above, we’ve added three sections — Recipes, Links, and About — which can then contain any number of items. We’ve also added support for our own, site-specific item metadata through the ItemMetadata type, which we’ll be able to use in a fully type-safe manner all throughout our publishing process. Start out simple, and customize when needed While Publish offers a really powerful API that enables almost every aspect of the website generation process to be customized and tweaked, it also ships with a suite of convenience APIs that aims to make it as quick and easy as possible to get started. To start generating the Delicious Recipes website we defined above, all we need is a single line of code, that tells Publish which theme to use to generate our website’s HTML: try DeliciousRecipes().publish(withTheme: .foundation) Not only does the above call render our website’s HTML, it also generates an RSS feed, a site map, and more. Above we’re using Publish’s built-in Foundation theme, which is a very basic theme mostly provided as a starting point, and as an example of how Publish themes may be built. We can of course at any time replace that theme with our own, custom one, which can include any sort of HTML and resources that we’d like. By default, Publish will generate a website’s content based on Markdown files placed within that project’s Content folder, but any number of content items and custom pages can also be added programmatically. Publish supports three types of content: Sections, which are created based on the members of each website’s SectionID enum. Each section both has its own HTML page, and can also act as a container for a list of Items, which represent the nested HTML pages within that section. Finally, Pages provide a way to build custom free-form pages that can be placed into any kind of folder hierarchy. Each Section, Item, and Page can define its own set of Content — which can range from text (like titles and descriptions), to HTML, audio, video and various kinds of metadata. Here’s how we could extend our basic publish() call from before to inject our own custom publishing pipeline — which enables us to define new items, modify sections, and much more: try DeliciousRecipes().publish( withTheme: .foundation, additionalSteps: [ // Add an item programmatically .addItem(Item( path: “my-favorite-recipe“, sectionID: .recipes, metadata: DeliciousRecipes.ItemMetadata( ingredients: [“Chocolate“, “Coffee“, “Flour“], preparationTime: 10 * 60 ), tags: [“favorite“, “featured“], content: Content( title: “Check out my favorite recipe!“ ) )), // Add default titles to all sections .step(named: “Default section titles“) { context in guard section.title.isEmpty else {…

Like to keep reading?

This article first appeared on github.com. If you'd like to keep reading, follow the white rabbit.

View Full Article

Leave a Reply