Zola is a nice static site generator. In fact, so nice that I moved this site over from Pelican a few weeks back.
The one thing I was missing though was the ability to set target="_blank"
on
links within the content. There is a relevant Github issue from last year
which proposes this feature for Zola. But the general consensus from that thread
is that this functionality should ideally be supported by pulldown-cmark,
which is the Markdown rendering library that Zola uses.
While I do agree with that decision, the relevant issue from the
pulldown-cmark
issue tracker looks a little discouraging. It is referenced by
a different issue titled Extensible rendering prototype which is currently
marked as closed with a comment from the maintainer saying that it's unlikely
for there to be much progress on this in the foreseeable future.
I wasn't sure what to make of the whole thing, but I do understand how hard it can be to prioritize open-source projects in between daily work and personal life. And since my Rust skills at the moment are beginner-level (at best), I tried to work my way around it using JavaScript instead.
The first step was to define a configuration option called enable_target_blank
to control this setting. Zola allows arbitrary user-defined configuration
options, so this was rather straight forward.
[extra]
enable_target_blank = true
I then added the following JavaScript snippet in the base HTML template.
var enableTargetBlank = function() {
var parents = document.getElementsByClassName('with-target-blank');
for (let parent of parents) {
var links = parent.getElementsByTagName('a');
for (let link of links) {
if (link.hostname !== window.location.hostname && link.target === "") {
link.target = "_blank";
}
}
}
};
{% if config.extra.enable_target_blank %}
enableTargetBlank();
{% endif %}
This code snippet picks all the <a>
elements on the page which are direct /
indirect descendants of any elements containing the with-target-blank
CSS
class. For all such links, we set the target
attribute to _blank
, in case
the links are external and if the target
isn't set to something already. And
all this code is defined in the base template so that it's also available in all
the other templates (due to template inheritance).
As a result, you can now add the with-target-blank
class on container elements
in which you want all the links to open in a new tab. On this site, for
instance, I do this only on elements containing Markdown rendered from Zola.
Here's the relevant portion from the page.html
template that I use.
<div class="row">
<div class="col with-target-blank">
{{ page.content | safe }}
</div>
</div>
Note that for this to work, there are two pre-requisites.
- JavaScript needs to be enabled.
- You should be able to modify the template code. I'm not sure if you can put custom code in off-the-shelf themes that Zola provides. But since I use a custom theme for this site, I didn't have to look too much into this.
Other than that though, this approach is quite straight-forward and works exactly like one would expect.