Adding optional state to shortcodes


Sort of bouncing off of Arbitrary Content Tables, I would like to propose another feature with would allow similar tricks, but in a way that might be conceptually simpler to implement, and possibly even more flexible.

Short description:

This would consist in having “state” variables, mutable and moved from Tera context to Tera context during shortcode rendering for a single page.

Choosing which state is passed along would be done when calling shortcodes (in content/, rather than when implementing then (in templates/shortcodes/code.html).

Use case:

Similar to the feature request that was bounced off of:

This would mainly allow to create lists of figures, lists of schemes, bibliographies, etc… LaTeX style. In general, we get tables of [item] at the end (or start?) of a generated page, along with automated numbering of the [item]s in the page’s body.

Of course opting into passing state from shortcode to shortcode would allow much more than that.

possible interface(s)

In theory, this feature would not change how a shortcode’s body is written (in templates/shortcodes/code.html): those would remain Tera-templated html or md without explicit headers to declare the variables used within.

It would, however, change how shortcodes are called from within a page body, for the shortcodes that opt into passing state.

there are several things to consider here:

  • would it be possible to pass more than a single state variable while calling a single shortcode?
  • while there is no difference between regular variables and state variables in a shortcode’s body, how is the nuance made clear at the call site?
  • optionally, would it be preferable to also introduce an “order” to the shortcode calls that re-use state, or should state only be passed ‘down’ the page body?
    • if a shortcode can accept more than a single state variable, it should probably still accept a single “order”, because having one order per state variable could cause deadlocks.
    • for several shortcodes with the same “order”, would the state be passed along in arbitrary order, or down the page ?

for instance, calling a shortcode with multiple state variables and an order could look like:

{{cite(key="CIE1931XYZ",bib=bibliography_state_1, unused=this_state_is_just_for_show) ;S bibliography_state_1 this_state_is_just_for_show ;O 1}}

This would tell Zola to have state variables bibliography_state_1 and this_state_is_just_for_show,
pass them to the shortcode’s Tera context as bib and unused, then once the shortcode is templated, fish biband unused back and store them back as bibliography_state_1 and this_state_is_just_for_show.

one thing that remains to be decided is how error handling should be done when, for instance, a shortcode is called several times, is supposed to take and return state as a list, but accidentally leaves it as an integer after the first call.

other, already possible approaches:

Doing that by hand / preprocessing the MD files

doing reference-keeping by hand would be very error-prone, especially with long pages.
Preprocessing the MD files to do that reference-keeping by a third party program before calling Zola is possible, but it feels like this goes against Zola’s single binary approach (/philosophy?).

Doing javascript to do this once the page is displayed on a browser

also possible, but having content re-processed feels like it goes against the idea of having a static website

Writing webpages in full html in the templates/ folder in order to use Tera macros instead of shortcodes

…I guess that’s a possibility?

Comparisons, advantages, drawbacks

An obvious drawback of this feature is the slight increase in complexity (especially in the parsing of shortcode calls), as well the reduced ability to render shortcodes in parallel within a single page.

On the other hand, the ability to do some amount of processing with a webpage’s contents puts Zola closer to other static website generators who apply a templating engine to the entirety of each page’s markdown source.
With the use of an “order” between shortcode calls that pass state to each other, this would go even beyond said other generators, which cannot put a table of [item]s before the [item]s are declared in a page’s body. Unless they use a LaTeX-style mechanism to cache such tables from one build to the next.

Another point of comparison is the proposal linked at the start of this one: from what I understood, the original proposal suggests a new API accessible from within a shortcode’s body, while this feature decouple the choice of state (shortcode call) from the code that uses it (shortcode body), which would result in a longer syntax used for every shortcode call, but more flexibility in the use of shortcodes.

Does this feature seem like a good idea?
If so, does it seem better than the original feature suggestion linked at the top? Is it good enough to start implementing for a more in-depth discussion before a pull request?

Thank you!
have a nice day!