Hi everyone,
I’m trying to implement similar effects with a shortcode and a render hook. I wrote two blog posts like this:
+++
date = '2025-01-12T02:38:06-05:00'
draft = true
title = 'Test1'
+++
1. Test with shortcode
{{< testlink "/posts/test2" >}}
2. Test with render hook
[click](/posts/test2)
and,
+++
date = '2025-01-12T02:38:08-05:00'
draft = true
title = 'Test2'
+++
**I'm here!**
So my idea was, when I click no matter which link, the content of page ‘Test2’ will show up under the link.
Here’s how I implemented the shortcode:
{{ with .Get 0 }}
{{ $page := $.Page.GetPage . }}
<p>
<a href="/" onclick="handleClick('{{ $page.Content }}'); return false;">click</a>
</p>
<div id="shortcode"></div>
<script type="text/javascript">
function handleClick(content) {
var shortcodeElement = document.getElementById("shortcode");
shortcodeElement.innerHTML = content;
}
</script>
{{ end }}
It seems to work fine. But when I tried the similar code in a render hook:
{{- $u := urls.Parse .Destination -}}
{{- $href := $u.String -}}
{{ $page := $.Page.GetPage $href }}
<a href="{{ $href }}" onclick="call('{{ $page.Content }}'); return false;">
{{ .Text | safeHTML }}
</a>
<div id="render"></div>
<script type="text/javascript">
function call(content) {
var div = document.getElementById('render');
div.innerHTML = content;
}
</script>
It seems the render hook doen’t know how to compile the page content and falls into an infinite building process. Is it not the correct way to call $page.Content
in a render hook? How should I find the correct way?
Try call('{{ $page.Content | | safeHTMLAttr }}')
or safe.JSStr
and see if that works.
Let’s assume this serves the purpose of your test, but it’s very unlikely that you want an entire page’s content on the onclick
of a link. The ways that can go bad because of unexpected characters are too many to count.
1 Like
Exactly, it’s recursion by definition, so of course it’s going to loop infinitely.
Instead of keeping each target pages data inside each link, you may want to create a JSON file with the respective data, and query that file from your script with the url
key.
For example that JSON Feed template would do it:
{{/* layouts/index.json */}}
{
"version": "https://jsonfeed.org/version/1.1",
"title": "{{ if eq .Title .Site.Title }}{{ .Site.Title | plainify }}{{ else }}{{ with .Title }}{{ . | plainify }} • {{ end }}{{ .Site.Title | plainify }}{{ end }}",
"home_page_url": "{{- with .Site.BaseURL }}{{ . | absLangURL }}{{ end -}}",
"feed_url": "{{ .Permalink | absLangURL }}",
{{ with .Site.Params.Author -}}
"authors": [{
"name": "{{ .name }}"{{ if .email }},
"url": "mailto:{{ .email }}"{{ end }}{{ if .image }},
"avatar": "{{ .image | absLangURL }}" {{ end }}
}],
{{- end }}
"items":
{{- $index := slice -}}
{{- $pages := where .Site.RegularPages.ByDate.Reverse "Type" "not in" (slice "page" "section") -}}
{{- $limit := .Site.Config.Services.RSS.Limit -}}
{{- if ge $limit 1 -}}
{{- $pages = $pages | first $limit -}}
{{- end -}}
{{- range $pages -}}
{{- if .Params.dateCreated -}}
{{ $.Store.Set "date_created" (.Params.dateCreated) }}
{{- else -}}
{{- if isset site.Params "date_format" -}}
{{- $.Store.Set "date_created" (.Date.Format site.Params.date_format) -}}
{{- else -}}
{{- $.Store.Set "date_created" (.Date.Format "2006-01-02") -}}
{{- end -}}
{{- end -}}
{{- if .Description -}}
{{ $.Store.Set "content" (.Description | $.RenderString) }}
{{- else if .Summary -}}
{{ $.Store.Set "content" (.Summary | $.RenderString) }}
{{- else if .Content -}}
{{ $.Store.Set "content" (.Content | $.RenderString) }}
{{- else -}}
{{ $.Store.Set "content" "no content" }}
{{- end -}}
{{- $index = $index | append (dict
"title" ( .Title | plainify )
"id" (md5 .Permalink)
"url" .Permalink
"types" (i18n .Page.Type )
"tags" (apply .Params.tags "i18n" "." )
"content_text" ($.Store.Get "content" | $.RenderString | plainify)
"date_created" ($.Store.Get "date_created")
"date_published" (.Date.Format "2006-01-02T15:04:05Z07:00")
) -}}
{{- end -}}
{{- $index | jsonify -}}
}
Interesting, I haven’t tried this way. Thanks for your advice!
How about using a details
HTML element? Hide everything except the summary and then take the InnerHTML
from the content to inject into your container. Advantage: Search engines see your content. Advantage 2: You can have as much other HTML and scripts in that content as you wish. It has click and toggle events and can be styled by status (open/closed).
3 Likes