2017-09-27 14:37:17 +00:00
+++
title = "Internal links & deep linking"
weight = 50
+++
2019-06-06 17:49:31 +00:00
## Heading id and anchor insertion
2019-12-21 09:44:13 +00:00
While rendering the Markdown content, a unique id will automatically be assigned to each heading.
2020-04-02 17:53:08 +00:00
This id is created by converting the heading text to a [slug ](https://en.wikipedia.org/wiki/Semantic_URL#Slug ) if `slugify.anchors` is set to `"on"` (the default).
If `slugify.paths` is set to `"safe"` , whitespaces are replaced by `_` and the following characters are stripped: `#` , `%` , `<` , `>` , `[` , `]` , `(` , `)` , \`, `^` , `{` , `|` , `}` .
If `slugify.paths` is set to `"off"` , no modifications are made, and you may be left with nominally illegal ids.
2019-12-21 09:44:13 +00:00
A number is appended at the end if the slug already exists for that article
For example:
2017-09-27 14:37:17 +00:00
```md
# Something exciting! <- something-exciting
## Example code <- example-code
# Something else <- something-else
## Example code <- example-code-1
```
2019-06-06 17:49:31 +00:00
You can also manually specify an id with a `{#…}` suffix on the heading line:
Allow manual specification of header IDs (#685)
Justification for this feature is added in the docs.
Precedent for the precise syntax: Hugo.
Hugo puts this syntax behind a preference named headerIds, and automatic
header ID generation behind a preference named autoHeaderIds, with both
enabled by default. I have not implemented a switch to disable this.
My suggestion for a workaround for the improbable case of desiring a
literal “{#…}” at the end of a header is to replace `}` with `}`.
The algorithm I have used is not identical to [that
which Hugo uses][0], because Hugo’s looks to work at the source level,
whereas here we work at the pulldown-cmark event level, which is
generally more sane, but potentially limiting for extremely esoteric
IDs.
Practical differences in implementation from Hugo (based purely on
reading [blackfriday’s implementation][0], not actually trying it):
- I believe Hugo would treat `# Foo {#*bar*}` as a heading with text
“Foo” and ID `*bar*`, since it is working at the source level; whereas
this code turns it into a heading with HTML `Foo {#<em>bar</em>}`, as
it works at the pulldown-cmark event level and doesn’t go out of its
way to make that work (I’m not familiar with pulldown-cmark, but I get
the impression that you could make it work Hugo’s way on this point).
The difference should be negligible: only *very* esoteric hashes would
include magic Markdown characters.
- Hugo will automatically generate an ID for `{#}`, whereas what I’ve
coded here will yield a blank ID instead (which feels more correct to
me—`None` versus `Some("")`, and all that).
In practice the results should be identical.
Fixes #433.
[0]: https://github.com/russross/blackfriday/blob/a477dd1646916742841ed20379f941cfa6c5bb6f/block.go#L218-L234
2019-05-20 20:08:49 +00:00
```md
# Something manual! {#manual}
```
2019-11-26 19:30:30 +00:00
This is useful for making deep links robust, either proactively (so that you can later change the text of a heading
without breaking links to it) or retroactively (keeping the slug of the old header text when changing the text). It
can also be useful for migration of existing sites with different header id schemes, so that you can keep deep
links working.
Allow manual specification of header IDs (#685)
Justification for this feature is added in the docs.
Precedent for the precise syntax: Hugo.
Hugo puts this syntax behind a preference named headerIds, and automatic
header ID generation behind a preference named autoHeaderIds, with both
enabled by default. I have not implemented a switch to disable this.
My suggestion for a workaround for the improbable case of desiring a
literal “{#…}” at the end of a header is to replace `}` with `}`.
The algorithm I have used is not identical to [that
which Hugo uses][0], because Hugo’s looks to work at the source level,
whereas here we work at the pulldown-cmark event level, which is
generally more sane, but potentially limiting for extremely esoteric
IDs.
Practical differences in implementation from Hugo (based purely on
reading [blackfriday’s implementation][0], not actually trying it):
- I believe Hugo would treat `# Foo {#*bar*}` as a heading with text
“Foo” and ID `*bar*`, since it is working at the source level; whereas
this code turns it into a heading with HTML `Foo {#<em>bar</em>}`, as
it works at the pulldown-cmark event level and doesn’t go out of its
way to make that work (I’m not familiar with pulldown-cmark, but I get
the impression that you could make it work Hugo’s way on this point).
The difference should be negligible: only *very* esoteric hashes would
include magic Markdown characters.
- Hugo will automatically generate an ID for `{#}`, whereas what I’ve
coded here will yield a blank ID instead (which feels more correct to
me—`None` versus `Some("")`, and all that).
In practice the results should be identical.
Fixes #433.
[0]: https://github.com/russross/blackfriday/blob/a477dd1646916742841ed20379f941cfa6c5bb6f/block.go#L218-L234
2019-05-20 20:08:49 +00:00
2017-09-27 14:37:17 +00:00
## Anchor insertion
2019-11-26 19:18:59 +00:00
It is possible to have Zola automatically insert anchor links next to the heading, as you can see on this documentation
2019-11-26 19:30:30 +00:00
if you hover a title.
2017-09-27 14:37:17 +00:00
2018-10-18 21:09:32 +00:00
This option is set at the section level: the `insert_anchor_links` variable on the
2019-11-26 19:30:30 +00:00
[section front matter page ](@/documentation/content/section.md#front-matter ).
2017-09-27 14:37:17 +00:00
2018-10-18 21:09:32 +00:00
The default template is very basic and will need CSS tweaks in your project to look decent.
2019-11-26 19:30:30 +00:00
If you want to change the anchor template, it can be easily overwritten by
2020-04-29 17:40:25 +00:00
creating an `anchor-link.html` file in the `templates` directory.
The anchor link template has the following variables:
- `id` : the heading's id after applying the rules defined by `slugify.anchors`
- `level` : the heading level (between 1 and 6)
2017-09-27 14:37:17 +00:00
## Internal links
2019-06-06 17:49:31 +00:00
Linking to other pages and their headings is so common that Zola adds a
2019-05-27 12:35:14 +00:00
special syntax to Markdown links to handle them: start the link with `@/` and point to the `.md` file you want
2017-09-27 14:37:17 +00:00
to link to. The path to the file starts from the `content` directory.
2019-05-27 12:35:14 +00:00
For example, linking to a file located at `content/pages/about.md` would be `[my link](@/pages/about.md)` .
2019-11-26 19:30:30 +00:00
You can still link to an anchor directly; `[my link](@/pages/about.md#example)` will work as expected.