Zine

Devlog

About

This is a non-exhaustive, curated list of changes meant to help users quickly see what has improved since they last checked.

You can subscribe to this page via RSS.

To update Zine to the latest release run:

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.8.0"

Changes

v0.8.0

2024-10-28

  • Page alternatives now require you to set the name field. You will get a build error if the name is not defined. It would previously default to an empty string, but now it’s mandatory because of the newly added builtins.
  • SuperMD
    • Added some error checking to SuperMD builtins that relate to links, like trying to use $link.ref in combination with $link.url.
    • $link.alternative('rss') to link to a page alternative
  • SuperHTML
    • Fixed documentation for linkRef, which wrongly reported it did not accept any argument.
    • Added $page.alternative('rss') which allows you to obtain an Alternative value by name (instead of looping over all $page.alternatives).
    • Added link() to Alternative so you can now link to RSS feeds like so:
      <ctx alt="$page.alternative('rss')">
        <a href="$ctx.alt.link()" type="$ctx.alt.type">
          RSS feed
        </a>
      </ctx>
      
      (the Frequently Asked Questions section was updated accordingly)

v0.7.2

2024-10-25

  • Windows should now work well. A path-related bug that caused assets to not be detected correctly has now been fixed, and a second bug that caused the webserver to fail to update when a new change happened has also been “fixed” (it’s actually an annoying networking bug unrelated to Zine, so we implemented a workaround). In any case, Windows should now be a first-class citizen for Zine so please consider rawdogging Zine on Windows instead of using Docker/WSL (also report any issue you find!).

  • In the previous release I added by mistake some debug logs that could not be silenced and that caused the webserver to show your the error window even when no error had happened, this is now fixed, sorry!

  • Creating duplicate ids inside of a content file is now properly reported as an error by Zine. Some ids would also not be correctly recorded (for the purpose of deeplinking) before, and that too has been fixed now.

  • New SuperHTML Scripty builtins:

    • $page.linkRef('foo') can be used to deep-link from SuperHTML templates
    • sriHash() can be called on assets to generate a hash for Subresource Integrity, thanks Shardion (#73)!
    • $build.git() can be used to access repo information when in a repository, see the SuperHTML Scripty reference for more information, thanks Sc3l3t0n (#77)!

v0.7.1

2024-10-16

  • When using the simplified website() / multilingualWebsite() interface, you can now pass -Dinclude-drafts flag to enable rendering of content pages that have .draft = true set in their frontmatter. Thank you nihklas (#70).

  • New SuperHTML Scripty builtin functions:

    • $page.hasContentSection: You can now query a page to see if it contains a content section with a given id. Thanks nihklas (#76).
    • $page.subpagesAlphabetic: lists sub pages sorted in alphabetic order. Unblocks rockorager’s recipe website. Recipe websites are good, make more of them.
  • New SuperMD Scripty directive:

    • $text, which can be used to give an id and attributes to a inline piece of text.

v0.7.0

2024-10-11

  • Introduced actual arrays in Zine. Previously we would immediately evaluate Scripty expressions into iterators, which made it awkward to implement bulitin functions such as sort. Zine now has a real concept of Array with dedicated builtins, you can read more in the reference for [any]. Note that arrays don’t yet offer a sorting builtin (figuring out the interface to expose to the user has been left as work for a subsequent release), but they do support other basic stuff like slicing. I’m happy to work with users to implement functions that would unblock them, even if the design of the function will have to be changed in the future.

  • Zine currently has a limitation that prevents it from correctly rendering (calling content() on) pages that have been loaded through Scripty. Over time this limitation has been mitigated, but it’s not fully gone yet. Unfortunately the check that told you that this was the case was not working correctly, and has now been fixed. The most likely situation where you might encounter this problem is when trying to render the content of various pages in an RSS template. Previously it might have worked for simple cases and caused a panic in others, now you will get a consistent error message that tells you that the feature is not available yet.

  • The webserver now properly parses percent encoding in URLs, used whenever files have funky names. Thank you GigaGrunch! (#65)

  • Paths with spaces were not handled correctly when tracking dependencies, causing some failures that might have looked like cache issues, now fixed thanks to brandondyck (#68)

v0.6.3

2024-09-19

  • When iterating content sections with $page.contentSections(), you can now obtain the section’s attached heading by calling heading or heading? on it. This was added mainly to support the usecase of giving titles to RSS entries generated from sections.

v0.6.2

2024-09-17

  • $image.linked() is now implemented and allows you to quickly create an image that links to itself.

v0.6.1-vscode

2024-09-07

  • The VSCode marketplace now has a SuperMD Extension that gives you syntax highlighting for SuperMD files (no LSP for it yet though, sorry!).
  • Similarly, the VSCode SuperHTML Extension would not provide you with syntax highlighting before, but now it does.

v0.6.1

2024-09-07

  • Updated rockorager/zeit, which now includes full support for date formatting strings based on the Go magic date. Previously Zine hardcoded only a very small subset of possible formatting styles. See the reference docs for Date.format for more info.

v0.6.0

2024-09-06

  • Added Page.parentSection() in SuperHTML.

  • The website now has a docs section for editor support.
    Follow those instructions to get syntax highlighting and LSP support in your favorite editor.
    If you have trouble setting up your editor feel free to ask for help in the community.

v0.5.1

2024-09-04

  • Added typst syntax highlighting support.

  • On the topic of RSS feeds, this page now has an RSS feed that you can subscribe to. Every entry in this devlog will become an entry in the RSS feed. If you’re curious to see how this is implemented, clone this repo and see how content/log.smd and layouts/log.xml work together to make it happen (see Get Started for more info).

  • Page in SuperHTML gained the ability to loop over sections defined by a Page.

  • SuperMD Directives can now store data (key-value fields) that can then be accessed programmtically by SuperHTML.

v0.5.0

2024-09-01

  • Added $build.generated which evaluates to the date in which the build is taking place. It doesn’t add a dependency on the current date so a page will only display a newer date if it actually gets regenerated.

    Useful for example to set lastBuildDate in RSS feeds. Note that without caching the date will always be updated, potentially resulting in unwanted behavior.

2024-08-30 (later in the day)

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.7"
  • Fix an off by one error that gave the wrong value to Iterator.last

2024-08-30 (later in the day)

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.6"
  • Fix a bug caused page-local assets to be installed in the wrong place

2024-08-30 (later in the day)

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.5"
  • Fix off-by-one error in some iterators (eg in $page.tags)

2024-08-30 (later in the day)

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.4"
  • Introduced support for captions directly in Markdown link / image syntax. See the updated SuperMD docs for more details.
  • Fixed a bug that prevented users from accessing $if in the intended way.
  • Some SuperMD Scripty reference docs were improved.

2024-08-30 (later in the day)

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.3"

Fixes a printing bug related to Int values.

2024-08-30

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.2"

Fixes a bug that prevented users from accessing $loop in the intended way.

2024-08-29 (later in the day)

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.1"

Fixes a silly but annoyng bug where SuperMD links nested inside of styiling elements would not get analyzed.

2024-08-29

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.4.0"

The SuperMD update!

With this release Zine is now at a point where the development experience is representative of what the final product will look like.

Error messages need to be improved and a lot of developer tooling is still missing, so take that into account, but the core authoring process is now mostly there.

Zine is also now featureful enough to begin the porting process for the official Zig website!

Note

This is going to be the last hugely breaking update to Zine in a while, so it’s a good moment to try Zine out if the fear of breaking changes has prevented you from attempting before.

Breaking changes will still keep coming, don’t worry, but for a while they will be almost exclusively minor changes that will require little work on your part.

Relatedly, I will be at SquiggleConf this October to talk about Zine and related work.

Now onto new features and breaking changes:

  • This website has been updated with a lot of new documentation. The docs section will now be able to guide you from getting the first few steps of creating a zine website, all the way to learning more advanced concepts.

  • The Scripty reference page that was very incomplete in the past has been improved heavily. Additionally, now there are two references: one for SuperMD and one for SuperHTML.

  • SuperMD comes with a ton of new features, too many to fully list here, but here are some highlights:

    • A page can now define content sections that can be rendered separately by the layout. This is huge, so check out the SuperMD Basics page for more information.

    • You can now give ids to headings and other elements to enable deep-linking (which will be also checked by Zine!), and you can also give classes for styling purposes.

    • Did you notice the “NOTE” block above? SuperMD has the concept of blocks, which make it super easy to include something like that in your content without needing to rely on inlined HTML.

      So cool

      These blocks can also be nested and styled!

    • Inlined HTML is forbidden now btw, but there’s an escape hatch for when you need to embed stuff like YouTube videos. See the SuperHTML docs page for more info.

    • Unfortunately we don’t have any tooling for SuperMD available just yet, but it’s high up in the list of priorities so stay tuned for updates in the near future.

  • Now that we have SuperMD, the file extension for content files has changed to .smd.
    If you need to update your Zine site and have a lot of markdown files, our friendly neighborhood LLM suggests to use this command to bulk rename all (run it inside your content dir):

    find . -type f -name "*.md" -exec bash -c 'mv "$0" "${0%.md}.smd"' {} \;
    
  • The logic attributes in SuperHTML (if, loop, var) have been renamed:

    • :if, :loop are still the same, they just gained a colon prefix
    • :text and :html replace var. The first escapes HTML, while the second doesn’t
    • inline-loop doesn’t exist anymore because now we have <ctx>
  • Introducing <ctx>: a special tag that allows you to create a phantom element that doesn’t render to anything. This element effectively allows you to implement what inline-loop was doing for you before, and more.

    Another cool feature of <ctx> is that defining attributes on it makes them available as fields under $ctx. See the SuperHTML docs page for more info.

2024-08-03

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.3.0"

The Asset System update!

  • Zine has now an asset system with clearly defined semantics. Previously we kinda implemented informally what other static site generators offered (eg a static asset directory), while now Zine gained it’s own spin on assets

    There’s a new Assets section in the docs, read it to learn how assets now work in Zine. The most notable changes are:

    • Zine can now make use of artifacts generated via the Zig build system!
    • static_dir_path has become assets_dir_path (I also recommend renaming static to assets)
    • Page assets (eg images placed in the content directory next to the page they belong to) now have one extra rule for file placement, see the docs for more info on that (or let the error messages gently guide you)
  • The dev server now by default opens a door port to 1990 if you don’t specify -Dport

  • output_prefix has been renamed to output_path_prefix

  • In MultilingualSite, variants has been renamed to localized variants

  • Scripty has gained a new Asset type and handful of new builtins, including adding the ability to query for the current locale_code in a multilingual website ($site.localeCode())

2024-07-27

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.2.0"

The build system flexibility update (part 1)!

  • Upgrading from v0.1: in your build.zig change try zine.addWebsite to zine.website.

  • addWebsite and addMultilingualWebsite have been renamed to website and multilingualWebsite respectively (and now don’t return an error anymore)

  • To align with std.Build‘s naming convention (where ‘add’ functions create steps but don’t wire them to the default install step), addWebsite and addMultilingualWebsite are now more low-level functions for defining build pipelines that allow you to customize more things:

    • You can have other build steps depend on the website being built
    • You can specify if and how the development webserver is bound to a named step
    • et cetera

    To learn how to use this more fine-grained API, look at the implementation of website and multilingualWebsite.

  • As suspected, in the last release I did not proprely wire the dependency on zig-afl-kit as a lazy dependency and that caused build errors to some. This is now fixed in this release. Sorry!

The next item on the roadmap is to add an asset system to Zine in order to have the static content generation depend on other steps defined in your build script.

2024-07-26

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.1.3"
  • Scripty strings now have eql, contains and endsWith. With a pinch of creativity you can create menus that style differently the current active page:

    <div class="$page.permalink().endsWith('/blog/').then('selected', '')">
      Blog
    </div>
    

    Similarly, when printing out the list of pages in a section, you can filter-out occasional “miscellaneous” pages (as in belonging to the same section but unwanted in the current list):

    <div loop="$page.subpages()">
      <div if="$loop.it.permalink().contains('/blog/')">
        <a href="$loop.it.permalink() var="$loop.it.title"></a>
      </div>
    </div>
    
  • The SuperHTML CLI tool was updated with two new commands:

    • check: checks HTML and SuperHTML template files for syntax errors, useful if you don’t have / want LSP integration (see also fmt in such case).
    • interface: prints out the interface of a given SuperHTML template file, useful to bootstrap a new SuperHTML template that extends another.
  • Zine and some of its dependencies depend on kristoff-it/zig-afl-kit for fuzzing. I tried now to make it a lazy dependency so that users don’t have to download it just to use Zine (as it’s a dev-only dependency), but I haven’t yet been able to fully test if I did so correctly.

2024-07-25

zig fetch --save "git+https://github.com/kristoff-it/zine#v0.1.0"

Zine has finally reached a first tagged release!

A lot has happened in these 4 months, so read this changelog to learn how to upgrade your Zine website.

The first thing that changed is the recommended way of updating your build.zig.zon.

The second is that Zine now tracks the latest stable version of Zig, which is 0.13.0 at the moment of writing.

Now onto new features and breaking changes:

  • The recommended GitHub Actions Workflow files for building Zine websites on Github have changed. The new version uses the mlugg/setup-zig@v1 action that will automatically manage caching for you. It is highly recommended to update your scripts.

    • While you’re at it, change --summary all to --summary new, which will only list the pages that were rebuilt.
  • SuperHTML (Zine’s templating language) dropped Tree Sitter as its HTML parser in favor of a handcrafted implementation that more closely follows the HTML5 spec. This brings us significantly improved error messages and other advantages.

    • It’s highly recommended you install and configure SuperHTML as your language server for both HTML and SuperHTML Templates in order to get in-editor diagnostics and kickass autoformatting. The repo also offers a Tree Sitter grammar for SuperHTML that incudes a few visual improvements for tags and attributes that have semantic meaning.

      SuperHTML also has a VSCode extension.

    • SuperHTML follows the HTML5 spec much more closely and, while writing an HTML parser from scratch for it, I learned that self-closing tags (tags with a final /) are not a thing in HTML5, so now <extend> and <super> have been defined as void elements in SuperHTML and want no final slash nor closing tag.

      Note that SuperHTML will consider an error using self-closing tags in HTML (outside of a <svg> scope).

    • The correct file extension for templates is .shtml. You must rename all your templates to the new file extension otherwise you will get an error from SuperHTML when it sees non-HTML compliant syntax, since <extend> and <super> are recognized as void elements only in SuperHTML template files.

  • Scripty has impoved as well: inside of nested loops, it is now possible to access outer $loop variables by doing $loop.up(). Each call to up() goes up one level.

    • This is thanks to the fact that interrupts were implemented in Scripty, opening the door to features that rely on the ability to pass from the outside values into scripty (up() relies on that since loops are a SuperHTML concept that Scripty is completely unaware of).
  • For syntax highlighting, Zine uses a distribution of Tree Sitter that bundles a lot of grammars and highlighting queries from Flow Control. The dependency has now been updated to a new version that adds support for more languages.

That’s mostly it. If you encounter bugs while updating, please don’t hesitate to open a new issue on GitHub with a link to a reproduction.

2024-03-26

.url = "git+https://github.com/kristoff-it/zine#e33a1d79b09e8532db60347a7ec4bd3413888977",
.hash = "12209f9be74fcc805c0f086e4a81ccca041354448f5b3592e04b6a6d1b4a95da5a26",
  • Added support for multilingual websites. See the corresponding docs page for more info. Because of this change now the AddWebsiteOptions struct is slightly different, here’s how to fix it:
    • Take the contents of site and move them top level, rename base_url to host_url.
  • Related-but-distinct from the above, you can now specify an output prefix for your static site. The feature was added primarily for i18n purposes but can also be used in simple websites to add an arbitrary prefix.
  • The markdown renderer now renders tables!
  • Fixed a crash in the dev server that would trigger when refreshing the page multiple times in quick succession (the crash was related to websockets). There’s still one remaining known bug related to this same problem though.
  • The dev server now works on Windows (thanks Parzival-3141)
  • New Scripty builtins:
    • Strings
      • addPath() similar to suffix but knows when to add a / or not.
      • fmt() replaces occurrences of {} in your strings with the provided string arguments.
    • Maps, refined the get family of functions
      • get(key, fallback) allows to get a key from a map and provide a fallback value
      • get!(key) errors out if the key doesn’t exist
      • get?(key) returns null if the value is missing, to be used in conjunction with if attributes.

2024-03-21

.url = "git+https://github.com/kristoff-it/zine#ecc72eb042af07f5b4690a35a7ca1dd9c6fd5b61",
.hash = "1220610a18236cd32936502bd7e762743e89ef70408638675420e453be41f1e83de4",
  • Changed datetime library to rockorager/zeit.
  • If you put a @date("...") literal in your custom fields, it will be recognized as a date by Zine.
  • A few improvements to bulitins:
    • get?(), get!() and get(): different ways of getting values out of Ziggy maps (i.e. custom fields).
    • then() on booleans now gives you the ability to create if-then-else expressions.
    • gt on integers.
    • lt, eq, gt on dates.

2024-03-20

.url = "git+https://github.com/kristoff-it/zine#d06884ec657abe87ab4f408b5dc3f336a6dcea9b",
.hash = "1220d3bc95a5343918d69d3478f27ebb4abe14613c159737af64cd2185151efd2fa1",
  • Zine now uses Ziggy as the frontmatter language! In the near future Zine will develop tooling for editing ziggy-markdown files. In the meantime consider downloading the Ziggy CLI tool for a smoother editing experience if you plan to use Ziggy directly.
  • Added an initial version of sections to Zine! See the updated documentation section for more information about that. Beware that $site.pages() was removed in favor of the new system.
  • Added a the ability to define alternatives in the frontmatter of a page. Alternatives allow you to specify multiple layouts to apply to the same piece of content. Useful for generating RSS feeds.
  • Added syntax highlighting to layouts: now strings have a syntaxHighlight builtin.
  • Updated Zig version because a bugfix was needed to add syntax highlighting to templates. Now Zine depends on Zig 0.12.0-dev.3381+7057bffc1 and above. Make sure to update your GitHub Actions workflows accordingly.

2024-03-08

.url = "git+https://github.com/kristoff-it/zine.git#4b3efd178cb6ee9af3c864fa980ad0499823aac6",
.hash = "1220f6920dbb9540cc9013bbaa1621d62ef79aabadcbb6f7b9f45e415de815d15404",
  • Added syntax highlighting support via tree-sitter. Most code snippets of this website have now gained syntax highlighting. No themes are provided for now and it’s expected that you define your own CSS from scratch. See hightlight.css from this website for an idea on how to proceed.
  • Updated Zig version because of a recent breaking change related to std.http. Now Zine depends on Zig 0.12.0-dev.3161+377ecc6af and above. Make sure to update your GitHub Actions workflows accordingly.

2024-02-13

2024-02-11

.url = "git+https://github.com/kristoff-it/zine.git#beb5434a04fad660ecf8db8379532dfe5b5e13b0",
.hash = "12203c37cb5fb3931d3b7d1f1dace46cf5329ffe2fb5a8d2ac87dc78630ce7f601a7",
  • Updated Zig version because of a recent breaking change related to std.Options / root.std_options. Now Zine depends on Zig 0.12.0-dev.2701+d18f52197 and above. Consider using marler8997/zigup if you’re not building Zig from source.
  • The Scripty reference documentation was improved slightly: the reference for Page displays which fields have default values and which do not.
  • The dev server is now better at reporting build errors: in the event of a build error the message will be shown in the terminal, as well as being shown on the web page, and the 404 page too will connect to the hot-reloading mechanism in order to show build errors.

2024-02-09 (later in the day)

.url = "git+https://github.com/kristoff-it/zine.git#da7c32c2c253f6b0dbd392006055598feb07410b",
.hash = "1220e6580fdbd0a56a97300bab938f61fe3b5b35fc7755a150db267422cf554ab299",
  • When running the dev server (zig build serve), Zine will now show build error messages inside of the web page itself using the hot reload mechanism. Fix the build error and the error overlay will disappear. Error messages are ugly for now (#16).

2024-02-09

.url = "git+https://github.com/kristoff-it/zine.git#527762348ef104dce601f52bca9f958a511ff11b",
.hash = "122018fb2b0ba1479ae28bacf3839d38da69044b006068fd67b1b7f4425114bec8d1",
  • Zine will now stop erroring out in the presence of empty markdown files. It will instead print a warning and ignore them. Now you can touch a bunch of files and fill them out as you make progress, without losing hot reloading in the meantime.

2024-02-08

.url = "git+https://github.com/kristoff-it/zine.git#eaa23f2d3a80868251302a1b979dbcc7e5b81d3a",
.hash = "1220230f7c6abf655ef9b1ec14161bd1c15e55afd14ceaedfe2e0e9cc2471b1dd0ca",
  • Removed the _index.md vs index.md naming convention. Now it’s always index.md and you can use the skip_subdirs frontmatter property to get the old behavior. See the docs for more information.