… and partials/parent-component.html looks like this:
<article>
<h2>This is a parent component</h2>
<div ht-include='partials/sub-component.html'>PLACEHOLDER FOR SUB-COMPONENT</div>
</article>
… and partials/sub-component.html looks like this:
<p>This is a sub component</p>
Then the output would be:
<section>
<article>
<h2>This is a parent component</h2>
<p>This is a sub component</p>
</article>
</section>
Hopefully that answers your question? Or were you thinking more along the lines of a component that calls itself recursively? I haven’t tested that…
EDIT: just tested this, a partial recursively calling itself, I think the build wasn’t happy. I didn’t see any errors get spit out, but perhaps it should… Pinging @calebhailey.com for input here. While may not be very likely someone will try to do this, would be good to get an error from the CLI and maybe have a comment added to the docs with a mention that this should not be done. (ht-include attribute)
Yes, this is supported, as @jordan already explained. There aren’t currently any guard rails around a component including itself (I’ll open an issue for that), so some caution is necessary, but for the most part it should work exactly you hoped it would @AtmanActive
I’m definitely not a power user at this point, I’m also not at my computer to test right now, so I don’t quite know if that is possible. I don’t know if you can put variables within the attribute value like that, but I’m fairly certain there is an approach to accomplish this — just requires a slight shift in thinking… It is likely not going to be done with ht-include alone… we might need some combination of ht-if / ht-not attributes… Or this might be better suited for the ht-block attribute.
Also worth noting here that if we’re speaking of using the hyperctl cli tool for static site generation, no client-side data like cookies and such would be accessible at build time.
I might be able to work on some mockups of layouts that change based on variables, but to make sure I’m on the same page, do you have any examples of how you would want your HTML layout to change related to some data variable?
Taking your example of a lang variable, I could see there being some layout differences with certain language variants based on their writing mode, but I could also see how a modern CSS approach would likely resolve the need for different templates. For example, instead of using directional styling like margin-top, margin-left, where we might run into styling rules that don’t quite work between languages that flow in different directions. However using margin-block-start and margin-inline-start might remedy those issues without needing a separate HTML layout.
Currently there are four sources of template data: site data, page data, namespace data, and layout data. I just updated the documentation to make this more clear (see the “Template data sources” heading):
Depending on the data structure, one or both of the ht-if and ht-not attributes could be used to configure conditional layouts. And these can be combined with ht-include or any of the other templating attributes. Understanding the order in which these templating attributes are evaluated may help you imagine how they might be combined to achieve different results.
PS – So far your first two questions are in the same order that we have documented the templating attributes reference – includes (ht-include), then conditional templating (ht-if and ht-not). In the off chance that you’re thinking about these high level concepts in the same order that we’ve documented them, the next templating attribute that might be of interest is ht-template which repeats elements (i.e. for...in or for...of loops).
I read the Template Data Sources, and it seems to me there is still something missing: an ad-hoc layer of data/variables that could be set/overridden at build time. Like a GLOBAL object that exists at all times and is set/overridden with ENV and/or command line parameters, without touching site.json. In this way, depending on the environment, CLI could build several versions of the site from the same source. Similar to how you now treat $ENV{ HYPER_CONFIG }, but available to inner workings and data sources (to use in paths, ht-ifs, ht-nots, and so on).
In any case, I like the idea of an env. template data prefix. I suspect it will put an asterisk on HyperTemplates guarantees RE: reproducible builds, but I think that’s acceptable.
A website that doesn’t use environment template data will always be reproducible, and even websites that do use environment variables can be reproducible with care.
In my humble opinion, it is important to have sensible defaults, so that lack of defined GLOBAL variables doesn’t wreck havoc. It is expected that 99% of sites/setups/builds won’t be using these, but then, when/if a need arises, it should be easy to start using them.
For example: global.language, shouldn’t be empty, or undefined, but should have value of “en”, if not defined anywhere. Then, just by adding ENV HYPTEM_language and setting it to “fr”, enables build process to explicitly build that version of the site (if used in the templates, of course).
There is no such concept (yet) of builtin variables, but a user-defined data.global namespace would be as easy as dropping a YAML or JSON file in the data directory.
Perhaps environment variables should use a prefix like HT_ to avoid collisions with other tools, then support some naming convention that would allow for overriding. For example, a data.global.lang property could be overwritten with the HT_data_global_lang environment variable.
Nope! Your reply made so much sense that I just got to work. Sorry for the radio silence. I actually just got environment variable-based template data hooked up yesterday and will likely cut a new 0.17.0 release tomorrow. I had a few other changes in the pipeline that I needed to finish up and release first, and those are available now (a 0.14.3 bugfix release, and 0.15.0 and 0.16.0 new feature releases):
I’ll update again soon when the env. namespace is ready.
By the way, thinking some more about it and looking at my various projects’ tree structures, I think the better default for data.global.version would be “v1” instead of just “1”. Usually in paths, the version is designated with a prefix “v”.
All these defaults will need to live hard-coded in the hyperctl itself and once people start using it left and right, there will be room for changes anymore, so better to think twice about each and every one of them.
I also realized that I have no way of following the news/logs about the HyperTemplates project development. Usually on Github I would just click on Watch and be always notified when there is something new.
Yeah I intend to use these forums for that. I created an Announcements category, and a Releases subcategory for that. I believe new users are auto-subscribed to these categories. I just need to start posting to them.
EDIT: I just added the 0.14.3, 0.15.0, and 0.16.0 release topics with a little more detailed changelog than the snippet on the downloads page.
EDIT: aaaaand I just cut a 0.16.1 release, which clears the path for the 0.17.0 release. I’m trying to maintain good semver release hygiene such that .0 releases are only for new features and changes, so bugfixes should be released in .x patch versions.
So it occurs to me that environment variables as I’m approaching them might not address this use case. The HyperTemplates CMS uses the directory structure of content files for generating page paths (see Pages and page.path for more information). This approach is very similar to Hugo page bundles. There is currently no support for programatic “rewrites” of page paths. I’m not opposed to enabling rewrites, but I do like the simplicity of a 1:1 mapping of directories-with-page-index-files to generated pages.
In a previous life I have maintained documentation websites for open source software projects in which we used versioned paths for new releases; for example: /docs/v1/api/overview/ versus /docs/v2/api/overview/. These documentation websites were built on static site generators like Middleman (wayyyyy back in the day) and Hugo, and at one point even a custom Express web app that was more or less backed by files on disk. No matter which tooling we used, we almost always followed the same workflow of copying the current version content into a new version directory, then updating the new version content with any changes. Then we would just symlink a “latest” directory and the static site generators were none the wiser. Is that a different approach than you would take?
In version 0.17.0 I will be adding two new template data sources: build data and environment data. Build data is automatically provided and only includes two properties so far: a build.id and a build.date. But environment data will allow you construct complex template data objects from environment variables.
Instead of letting environment variable template data overwrite site. or data. properties, they can be added with a higher priority to templating attributes. For example:
In this example ht-content will use env.globals.meta.version if it is available, or site.version. I like this explicit approach where it is easy to find all the uses of environment variables in templates over an implicit approach where environment variables could overwrite a site. or data. property.
Does this make sense? And am I missing anything RE: what you’d imagine using environment variables for?
In this case. definitely no need for hard-coded defaults.
The defaults are in the site.json and can be overridden using ENV.
Great!
But, this approach where a comma means || is very new to me. I’m kind of used to comma being a series of sorts. It’s not that I have anything against this, I just think that it needs to be documented and explained to death in many, many examples so that people can grasp (and memorize!) the concept. Otherwise, I’m all for it.
On the other hand, If you are able to change comma , for OR || in your parser, in this case, that would make it even better/easier.
To answer your question about v1/v2: yes, that’s exactly what I’m on about. Keeping the tree of the old version always allows one to go back and dig up something of value there. Same thing with Git branches. As long as we can ad-hoc steer hyperctl to build version X or branch Y - we’re golden.
Aha! This was the piece I was missing. This is a little different than the examples I shared in that the versions were a subpath (e.g. content/docs/v1/ and content/docs/v2), so we were always building every version of the docs). If I’m following correctly, what you want is more like content/v1/docs/ and content/v2/docs/, yes? You want to version the entire content tree.
In HyperTemplates this is configurable in site.yaml or site.json via the site.config.content_dir property. You can basically specify where the content “root” is. This could be updated to content/v1 or content/v2, etc. And hyperctl build further supports a --config flag for managing which configuration file to use, so you could experiment with multiple build configurations in this way. But managing multiple site configuration files for anything more than an experiment feels messy.
I definitely don’t want to use the HT_* environment variables for overwriting configuration and template data (as I outlined above). I like keeping HT_* for template data only. But I could add a hyperctl build --contentdir flag with its own environment variable (e.g. HYPER_CONTENT_DIR) for managing this on a per-build basis, then you could easily build completely different (new/old) versions of a site without any code changes.