Use filesystem paths for everything

In #3094 Keats mentioned that they were planning on reworking how internal links work after the terra2 refactor.

I’m here to make the case for treating all schema-/protocol-less paths as internal links, and drop the special @/ syntax entirely. Instead, Zola would always translate absolute (eg. </foo>) and relative (eg. <../foo>) paths according to the internal link rules.

I wasn’t around for the ./@/ discussion (#686, #19) so apologies if this is reopening a closed issue.

Here are my arguments:

  1. When a markdown file is displayed in a git forge (eg. GitHub), @/ links are always broken, making it harder to navigate through the markdown. If links are encoded as file system paths, they’ll work in the markdown previews. Note: this is only true for relative paths unless / means the root of the repository and not /content/.
  2. Relative paths are more resilient than absolute paths. If I have a folder of posts that interlink and I decide I want to reorganize them, I’d have to change every absolute path. Relative paths don’t suffer from this problem.
  3. It’s intuitive. Users don’t need to learn a new syntax. You just link to the file. The user doesn’t need to consider aliases, path overrides, slugs, etc.
  4. Strict by default. The normal tool users reach for (standard markdown links) becomes the safer option, and that means less broken links.
  5. Pages and assets behave the same.

Some downsides:

  • You cannot make protocol-less links to files not managed to Zola, you always have to include the domain. Personally, this feels like an uncommon thing to do anyway?
  • Extremely breaking change, though it would be pretty easy to write helpful error messages or even make a tool to do the migration.

Anyways, thanks for giving this a read, and thanks for making a great tool!

for whatever reason, I can’t include links in my post; sorry!

I personally like @/ being explicit about what’s in the Zola site.

I’m not sure about that? If you move a lot of things around, @/ links will error while if you have ../_index.md it might still work but point to a different file. How do you refer to a specific .md file from a template for get_url? Relative paths don’t work there.

It’s not that uncommon to have Zola on a subsite (eg /blog) and refer to assets that are not present in Zola itself. Without @/ you’d need a way to ignore it in the link checker

Yeah I think this would be too big of a breaking change IMO for not a super compelling win. I’ll probably add support for Support wiki-style internal page links · Issue #2104 · getzola/zola · GitHub which is another way to link things

1 Like

I guess there are actually two distinct-but-related things I’m promoting:

  • Allow relative internal links, and
  • Treat links as internal by default.

They could be implemented separately, and should probably be considered separately. Unfortunately I already wrote the following, so they’re gonna be mixed together for now.


I initially preferred it as well, but now that I’ve tried porting a rather large and unwieldy site from Jekyll to Zola, I’ve changed my mind. I believe using a special character to escape Zola is safer and more intuitive than using a special character to remain within Zola.

There’s a use for both absolute and relative links (and both should be checked by the link checker).

Absolute links are most useful when you’re referring to a far flung topic, like an appendix or another section/chapter entirely. They are indicated by the red arrows above.

Relative links are more useful when linking within a tightly related group of topics, say within the same chapter. The blue arrows above.

For example, without relative links, if you renamed Flowers to Angiosperms, you’d need to change every link within the Flowers section, even though no structural change happened.

True, but I think that’s kind of my point. You can choose whether a link points semantically or structurally (or somewhere in between):

  • ../_index.md is “my parent”
  • ./daisy.md is “the related concept ‘daisies’”
  • ./violet.jpg is “the related image for violets”
  • /trees/pine.md is “pine trees, no matter how deep into the specifics of flowers I get”

I didn’t mean to imply that Zola should parse HTML and rewrite every URL it finds while rendering templates. My bad!

get_url would still be necessary in templates, and I think that makes sense.

I am, without any evidence, assuming that links within the /blog subsite that stay within /blog will be much more common than links within /blog that point outside of /blog. Another way of putting it would be that blog pages are more likely to link to other blog pages than to non-blog pages.

You’re the expert here though, so I’ll defer to your experience.

Good point! I was initially thinking you could use full URLs for that (eg. //example.com/non-zola.html or https://example.com/non-zola.html), but a specific prefix would be way less annoying. Maybe !/non-zola.html?

Fortunately the transition can be automated, maybe as a Zola subcommand that hangs around for a major version or so.

The big wins, for me at least, are:

  • unifying the path resolution of assets and markdown files, both in Zola itself and for users
  • stronger link checking by default
  • previews in GitHub
  • relative links for closely related topics

The Case for Relative Internal Links

Intro

Here’s a real-world example of why the current behaviour is unintuitive. This doesn’t work with Zola today, because .../complexity_analysis.md ends up rendered to .../complexity_analysis/, making the ./ resolve to the wrong directory.

Example

content/07549/assets/complexity_analysis.md

![image](./max_attestations.png)

content/07549/assets/max_attestations.png

Solutions

Today

The intended pattern, as I understand it, would be to:

  • move .../complexity_analysis.md to .../complexity_analysis/index.md, and
  • move .../max_attestations.png to .../complexity_analysis/max_attestations.png.

This makes sense once you understand a little bit about Zola, but to a new author who knows nothing about our rendering pipeline, it’s very unexpected.

With Relative Internal Links

If Zola supported relative internal links (with or without the @ syntax), this wouldn’t be a problem:

![image](@./max_attestations.png)

Though I’d prefer if the syntax from the initial example page (without @) worked.