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
- Added some error checking to SuperMD builtins that relate to links, like trying to use
- SuperHTML
- Fixed documentation for
linkRef
, which wrongly reported it did not accept any argument. - Added
$page.alternative('rss')
which allows you to obtain anAlternative
value by name (instead of looping over all$page.alternatives
). - Added
link()
toAlternative
so you can now link to RSS feeds like so:
(the Frequently Asked Questions section was updated accordingly)<ctx alt="$page.alternative('rss')"> <a href="$ctx.alt.link()" type="$ctx.alt.type"> RSS feed </a> </ctx>
- Fixed documentation for
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 templatessriHash()
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
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 forDate.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
andlayouts/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
replacevar
. The first escapes HTML, while the second doesn’tinline-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 whatinline-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 becomeassets_dir_path
(I also recommend renamingstatic
toassets
)- 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
doorport to 1990 if you don’t specify-Dport
output_prefix
has been renamed tooutput_path_prefix
In
MultilingualSite
,variants
has been renamed tolocalized variants
Scripty has gained a new
Asset
type and handful of new builtins, including adding the ability to query for the currentlocale_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
changetry zine.addWebsite
tozine.website
.addWebsite
andaddMultilingualWebsite
have been renamed towebsite
andmultilingualWebsite
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
andaddMultilingualWebsite
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
andmultilingualWebsite
.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
andendsWith
. 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 alsofmt
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.
- While you’re at it, change
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 toup()
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).
- 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 (
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, renamebase_url
tohost_url
.
- Take the contents of
- 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 tosuffix
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 functionsget(key, fallback)
allows to get a key from a map and provide a fallback valueget!(key)
errors out if the key doesn’t existget?(key)
returns null if the value is missing, to be used in conjunction withif
attributes.
- Strings
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!()
andget()
: 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 Zig0.12.0-dev.3161+377ecc6af
and above. Make sure to update your GitHub Actions workflows accordingly.
2024-02-13
- Overhauled the documentation page. Now it’s a little bit easier to get started with Zine.
- Added deployment guides: one for GitHub Pages and one for Cloudflare Pages (thanks
ninja_tron
!) - Started work on the JSON replacement for better frontmatters, join the Discord server or catch me live on Twitch for related discussion & sneak peeks.
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 Zig0.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
vsindex.md
naming convention. Now it’s alwaysindex.md
and you can use theskip_subdirs
frontmatter property to get the old behavior. See the docs for more information.