It works but i would like to do something else and am too inept to adjust the code to my desires. Maybe someone can help me with that.
What i would like to do is:
range through titles of specific section {{ range where .Site.Pages.ByTitle "Section" "section-name" }}
if {{ .Title }} is found within the {{ .Content }}<p>
change that text into <a> and link it to it’s title
if {{ .Title }} of the current content equals, do not link anything
So if content with title “X” has a text which at one point states “Elon Musk likes anime” and there exists a content with title “Elon Musk”, the short code should do the following:
What you ask is a pretty complex feature that is not built into Hugo. It can be done alas with a few caveats.
First of all I assume that you are looking to cross link various single pages and I am going to give you some pointers:
Hugo has a Related Content feature that even though it does not index the Content of a page it can be used to store the Permalink and Title variables of every page in a project.
Content is a monolithic variable. Meaning that you have to manually split it if it contains the value of one of the Titles stored in the previous step. If the keyword appears somewhere in the middle then you will split the Content in 2 parts and then index them with the cross link HTML in between.
You would probably need to use .Scratch to store the variables and retrieve them from the outside of the .Related range
Also you would need to use the printf function so that you can cast the variable strings without error inside the .Content string.
All of the above will be done directly in the single.html template and not from a shortcode.
However this poor man’s search engine might slow down the build time of your project if you have tons of pages.
Anyway I have given you a way of how to go about it without the code. If someone more skilled than me has a simpler approach maybe they could offer some advice.
Perhaps rather than doing all that maybe it would be best to have a look at the ref and relref shortcodes to create your cross links.
Also my previous post outlined a pretty complex way of going about it and the results are not guaranteed.
I have found a way to use Related Content for creating links across articles by detecting keywords but unfortunately there is a limitation. See my other topic
Bottom line keyword detection is possible so that .Content can be split and the link inserted. But you would need to use a front matter parameter for all the content files that do not have a cross link. Unless this issue finds a solution.
If you don’t mind adding a front matter parameter to your content files I could post a working snippet for generating those links.
You will need to add a front matter parameter to content files that you want to crosslink:
i.e. crosslink = "true"
Then in layouts/_default/single.html
{{ $related := .Site.RegularPages.Related . }}
{{ with $related }}
{{ range . }}
{{ $title := .Params.title }}
{{ $permalink := .Permalink }}
{{- if and (strings.Contains $.Content $title) (ne $title $.Params.title) -}}
<li>{{ $content := split $.Content $title }}{{ index $content 0 | safeHTML }}<a href="{{ $permalink }}">{{ $title }}</a>{{ index $content 1 | safeHTML }}</li>
{{ end }}
{{ end }}
{{ end }}
{{ if not $related }}
<li>{{ .Content }}</li>
{{ end }}
With the above if the title parameter of a content file is found in the .Content then it will be turned into a link. If the keyword is in a content file with the same title parameter it will not be turned into a link.
Content files that do not belong in the related index crosslink will have their content displayed normally.
And that’s it.
I had a hard time figuring out the if not $related condition because I hadn’t removed a content file from the related index.
So this is my take into an automatic internal links generator based on keyword.
A quick note: If you have several indices, you might want to use the RelatedTo method to make sure you use only one index (if that is what you’re after).
For some reason when I use this method {{ $related := .Site.RegularPages.RelatedTo ( keyVals "crosslink" "true") }} the if not $related condition renders empty.
But {{ $related := .Site.RegularPages.RelatedIndices . "crosslink" }} works fine.
And I tested with another Related index defined and everything again works fine.
Ah apologies my yaml syntax was wrong. I managed to set it up properly now, i think. There however is a slight problem. i am not sure as how to describe it so i will use a real example
first two paragraph text:
`Described as XYZ by Name One. Described as real life ABC by Name Two.
According to Name Two, events began on a…`
This turns first occurrence of Name Two into a link. Name One not set up yet. Next, second paragraph, where Name Two occurs again is cut just before the name, it does not show any content (every paragraph gone)
So it becomes:
`Described as XYZ by Name One. Described as real life ABC by Name Two.
According to`
If i add crosslink: "true" to Name One it is not linked in the first paragraph. The first paragraph is repeated after the second one in which Name One is linked but Name Two is not.
After it, the second paragraph is repeated in full with Name Two in it not linked and then follows the rest of the entire content.
Sorry if i am being annoying with this. I realize it might be something rather complicating to do or i am doing something wrong. I understand if there is no easy solution. It is not very important, was just an idea about a nice thing to have.