Assuming the following urls.toml file in data folder:
[Group]
link = "http://example.com"
[Group.A]
link = "http://example.com"
I know that I can access the link value in Group.A in my shortcode like this:
{{ index .Site.Data.urls.Group.A "link" }}
But, I would like to access the link in a way similar to the following:
{{ index .Site.Data.urls "Group.A.link" }}
The reason for this is to enable me to pass the "Group.A.link" as a parameter to my "url" shortcode within the content markdown like this:
{{< url "Group.A.link" >}}
Otherwise, I won't be able to use nesting for logical organisation in the urls.toml data file.
Thanks in advance.
You can use nested calls of index COLLECTION "key" to narrow your way down.
Meaning,
(index (index (index .Site.Data.urls "Group") "A") "link")
would work given your urls.toml structure.
The trick is making it somewhat dynamic, so you don't need to worry too much about depth.
The snippet below might serve as a potential starting point for a shortcode. However, it doesn't have any safe-guards. I'd recommend to add a few checks to get meaningful errors/warnings if things go wrong.
{{ $path := .Get 0 }}
{{/* split the string to have indices to follow the path */}}
{{/* if $path is "A.B.C", $pathSlice wil be ["A" "B" "C"] */}}
{{ $pathSlice := split $path "." }}
{{ $currentValue := .Site.Data.urls }}
{{ range $pathSlice }}
{{/* recommended homework: check that $currentValue is a dict otherwise handle with defaults and/or warnings */}}
{{ $currentValue = index $currentValue . }}
{{ end }}
<p>et voila: {{ $currentValue }}</p>
After having looked at Hugo's code (Index function) I found a very simple solution.
If we want to pass a complex comma-separated key, all we need to do is split it when calling index. Example:
Using the url shortcode in markdown:
{{< url "Group.A.link" >}}
Code of the url shortcode:
{{ index .Site.Data.urls (split (.Get 0) ".")}}
Related
I'd like to list all the pages that do not have a type of featured. If I want only the featured pages, I would use the following:
{{ range ( where .Site.RegularPages "Type" "featured" ) }}
...
{{ end }}
What's the opposite of that? I know I can list all the pages and then put an if inside of the range, but I'm thinking there must be a way to do it in the range expression itself.
OK...figured this out. The operator needed to be in quotation marks, so this works:
{{ range ( where .Site.RegularPages "Type" "!=" "featured" ) }}
...
{{ end }}
I had tried using the operator without the quotation marks and it kept throwing an error.
I'm using hugo 0.73.0, and the Paginator doesn't seem to override the global paginate value.
Question 1:
In my config.toml
paginate = 4
In my list template
{{ range (.Paginator 2).Pages -}}
{{ partial "listing.html" .}}
{{- end }}
Here I want to use 2 post per page but it still shows 4 as defined by the global setting in config.
Question 2:
When I try
{ range sort (.Paginate (.Site.Taxonomies.tags.Alphabetical)).Pages.ByTitle -}}
{{ partial "listing.html" .}}
{{- end }}
The list sorts my posts by name. But as soon as pagination kicks in, it messes up the sorting order. Eg. If I have 4 posts (A, B, C, D) and paginate is set to 3. then the pages are like this:
page 1: posts B, C, D
page 2: posts A
What I want is something like this
page 1: posts A, B, C
page 2: posts D
Any help will be appreciated. Thanks
The gohugo-theme-ananke shows 3 articles per pages, using layouts/posts/list.html with:
{{ $paginator := .Paginate (where .Data.Pages "Section" .Section)}}
Check if overriding the Paginate option would work in that theme example site, for testing.
Then you can try and integrate .Site.Taxonomies.tags.Alphabetical
I'm trying to use a variable within the content of a Hugo statically generated site. For example, the content looks like the following:
Go to your site's url ({{ .Site.BaseURL }})
Enter your credentials
.....(blah blah blah)
When this gets rendered, the {{ .... }} part doesn't get processed...it stays the same as I put above. I've tried it with a $ in front as well. Variables within templates seem to work just fine. Do I need to create a shortcode to use within content pages?
So it looks like a shortcode is the way to do this. For what it's worth, I changed the document to look like the following:
Go to your site's url ({{< siteurl >}})
In layouts/shortcodes, I created the file siteurl.html. It looks like the following:
{{ .Page.Site.BaseURL }}
I needed to add .Page in there to get access to the Site variables. See this Issue Report for more details.
In Hugo, When you want to use a variable in markdown (.md) file then you need to create a shortcode for that first.
You can follow these steps:-
create shortcode
layouts/shortcodes/siteurl.html
{{ .Page.Site.BaseURL }}
usage
content/post/myblogpost.md
---
# front-matter
---
1. Go to your site's url ({{< siteurl >}})
2. Enter your credentials
3. .....(blah blah blah)
result
post/myblogpost.html
1. Go to your site's url (https://codingnconcepts.com)
2. Enter your credentials
3. .....(blah blah blah)
Source: https://codingnconcepts.com/hugo/custom-shortcode-hugo/
I had the same problem, and this post helped me.
I wanted to display a site param in my site content, and discovered you cannot use regular templating inside content files.
In the end I created a shortcode to load the requested site param. Who knows this information might help someone.
/config.yml
params:
appName: My app
/content/about.html
<p>My app's name is {{< param "appName" >}}</p>
/layouts/shortcodes/param.html
{{/* Usage: {{< param "siteParamName" }} */}}
{{ index .Site.Params (.Get 0) }}
Result
<p>My app's name is My app</p>
This is an attempt to slightly improve #minitauros answer with a simplistic example to lookup a (site) parameter sub-key (aka walk the YAML tree, infer an element, etc.).
I would like Hugo to have a JSONPath or jq syntax and, obviously, this example is far from competing with either solutions.
config.yml
params:
mode: one
support:
mailing: info#example.net
layouts/shortcodes/param.html
{{ $v := .Site.Params }}
{{ range (split (.Get 0) ".") }}{{ $v = index $v (.) }}{{ end }}
{{ $v }}
content/_index.md
We are in mode {{< param "mode" >}}.
In case of turbulence, [reach the support](mailto:{{< param "support.mailing" >}}) for help.
I am new to Twig and Symfony2 (and PHP as well). I currently have an array of objects where I can access an attribute by doing {{result.attribute1}} after a {for result in results} statement.
I would like to use a variable {{var| removePath}} (where removePath is an extension I made in Twig), and use it to iterate over the results array. What I would like to do is return the row if {{var| removePath}} == result.attribute1.
Is this possible to do in Twig? If so, how should I approach this? I have already tried something similar to the code found below, but the "else" statement is executed (saying there's no match). I also tried var == result.attribute, but this didn't work either.
{% for result in results %}
{% if var|removePath in result.attribute1 %}
{{ var | removePath }} exists.
{% else %}
{{ var | removePath }} doesn't exist in array.
{% endif %}{% endfor %}
Thus I think I have 2 questions;
1) Is it possible in TWIG (if so, how)
2) Is there an easier/better way to get the whole row (object array also contains attributes 2, 3 & 4, and I would like to return those that are in common with attribute 1 (if it matches var))
See schema of my array recently added
Thank you in advance for your help! I hope my question is understandable :S
Just surround the expression with brackets.
use (var|removePath) which groups an expression.
example:
{% if ( 1+1 ) == 2 %}
And you can use the attribute() function to access properties and methods of an object/array.
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
attribute chapter in the twig docs.
Further shorten template code using the ternary operator like this:
{% set strippedVar = var|removePath %}
{{ strippedVar }}{{ (strippedVar in result.attribute1) ? 'exists' : 'does not exist' }}.
Setting the filtered variable to another prevents executing the filter multiple times.
I'm trying to print out value of the variable passed to the twig template. I'm using this code:
{{ naziv[0] }} Index is 0 because passed array has only one element. Mentioned code produces following error:
Key "0" for array with keys "title" does not exist in...
but when I use for loop like this:
{% for key,value in naziv %}
{{ value }}
{% endfor %}
I get what I want.
What's wrong with {{naziv[0]}} ?
Based on the var_dump of array(1) { ["title"]=> string(11) "SpaceVision" }
You should access your array in this way: {{ naziv['title'] }}.
The key of your array is associative and not a numerically indexed array. That is why you cannot use naziv[0].
You can also use: {{ naziv.title }} aswell.
See the documentation.
Your array is not number indexed, thus naziv[0] is not defined. Access it as naziv.title.