Hugo Page Resources - can't get a match - hugo

I want to write a generic shortcode for my hugo-powered webseite that adds a download section to my pages listing all the files in the downloads folder.
I have the website layed out like this:
.
├── content
│   └── press
│   ├── downloads
│ │ ├── presstext.pdf
│   │   └── presskit.zip
│   ├── _index.de.md
│   └── _index.en.md
└── layouts
   └── shortcodes
   └── downloads.html
My markdown file looks like this:
---
title: "Downloads"
date: 2019-10-26T09:59:26+01:00
draft: true
resources:
- src: downloads/presskit.zip
title: Presskit
params:
icon: pdf
- src: downloads/presstext.pdf
title: Presstext
params:
icon: pdf
---
Look at my awesome downloads:
{{< downloads >}}
And my shortcode looks like this:
<ul class="downloads">
{{ range .Page.Resources.Match "downloads/*" }}
<li>
<a target="_blank" href="{{ .Permalink }}">
<i class="far fa-file-{{ .Params.icon }}"></i> {{ .Title }}
</a>
</li>
{{ end }}
</ul>
But no document ever get's matched, so {{ range .Resources.Match "downloads/*" }} always returns empty. Am I overlooking something?
I already tried:
{{ range .Resources.Match "downloads/*" }}
{{ range .Resources.Match "/downloads/*" }}
{{ range .Resources.Match "**.zip" }}
{{ range .Resources.Match "**.pdf" }}
{{ range .Resources.Match "press/downloads/*" }}
{{ range .Resources.Match "/press/downloads/*" }}
Running on Hugo 0.59.0

I gave up on this and ended up doing this instead:
.
├── content
│ └── press
│ ├── presstext.pdf
│ ├── presskit.zip
│ ├── _index.de.md
│ └── _index.en.md
└── layouts
└── shortcodes
└── downloads.html
my markdown:
---
title: "Downloads"
date: 2019-10-26T09:59:26+01:00
draft: true
resources:
- src: presskit.zip
title: Press kit
params:
icon: archive
download: true
- src: presstext.pdf
title: Press text
params:
icon: pdf
download: true
---
Look at my awesome downloads:
{{< downloads >}}
Shortcode:
<ul class="downloads">
{{ range .Page.Resources }}
{{ if isset .Params "download" }}
<li>
<a target="_blank" href="{{ .Permalink }}">
<i class="far fa-file-{{ .Params.icon }}"></i> {{ .Title }}
</a>
</li>
{{ end }}
{{ end }}
</ul>

OK, this is an old one, but the right answer is that for branch bundles (_index.md) you can have resources ONLY in the same folder.
For leaf bundles (index.md) you can have resources in subfolders.
I guess it is because every subfolder in branch bundles is supposed to be a page with resources (leaf bundle).
Here is the source https://gohugo.io/content-management/page-bundles/ (see the table row Where can the Resources live?)

Related

How to render image using path from json in hugo

The project structures look like this.
/
|__ assets
| |__ imgs
| |__ pic-nodejs.jpg
| |__ pic-denojs.jpg
|
|__ data
| |__ products.json
|
|__ layouts
|__ _default
| |__ baseof.html
|
|__ partials
| |__ card.html
|
|__ index.html
The project goal is basically to display a list of products with a Bootstrap-ish card style in a grid layout.
Below are the snippets from the above files.
/data/products.json
[
{
"Uid": "110",
"Name": "Nodejs",
"Imgsrc": "imgs/pic-nodejs.jpg"
},
{
"Uid": "120",
"Name": "Denojs",
"Imgsrc": "imgs/pic-denojs.jpg"
}
]
index.html
{{ define "main" }}
<section>
{{ partial "card.html" . }}
</section>
{{ end }}
partials/card.html
{{ $data := getJSON "/data/products.json" }}
{{ range $data }}
<header>
<h2>{{ .Name }}</h2>
</header>
<img src={{ .Imgsrc }} alt={{ .Name }} />
{{ end }}
The expected output for card.html.
<section>
<header>
<h2>Nodejs</h2>
</header>
<img src="imgs/pic-nodejs.jpg" alt="Nodejs" />
</section>
I've got this instead.
<section>
<header>
<h2>Nodejs</h2>
</header>
<img src="" alt="Nodejs" />
</section>
No image being loaded.
Any idea how to do this?
I'm currently using HUGO v0.88.1 Extended.
Move the folder imgs inside static folder
check this branch of my repo

Nested list of sections and content - Hugo

I have a series of nested sections that contain recipes, grouped by type of dish, e.g.:
content
└─ recipes
  ├─ _index.md
  ├─ bread
  │  ├─ _index.md
  │  ├─ beer_rolls.md
  │  ├─ ciabatta.md
  │  └─ potato_bread.md
├─ dessert
  │  ├─ _index.md
│  ├─ chocolate_brownies.md
│  ├─ elderberry_pie.md
│  └─ victoria_sponge_cake.md
└─ mains
├─ _index.md
├─ bean_chilli.md
├─ braised_leeks.md
└─ yorkshire_pudding.md
I want to write a list.html for content/recipes/_index.md, to produce a nested list that reflects the directory structure in recipes/, such that the first level of the list links to the subsection e.g. bread or dessert, and the second level of the list links to the individual recipes, e.g. bread/beer_rolls.md or mains_bean_chilli.md.
What does the list.html contain? Do I need to have multiple list.html files, one for each nested subsection?
With help from this example, I constructed the following system, which works well for me:
in layouts/recipes/list.html I included this:
{{ if (eq .Title "Recipes") }}
<ul class="postlist">
{{ range .Sections.ByTitle }}
<li>
{{ .Title }}
{{ partial "recursive.html" . }}
</li>
{{ end }}
</ul>
{{ else }}
<ul class="postlist">
{{ range .RegularPages }}
<li>
{{ .Title | markdownify }}
</li>
{{ end }}
</ul>
{{ end }}
And in layouts/partials/recursive.html I included this:
{{ $child_pages := union .Sections .Pages }}
<ul>
{{ range $child_pages.ByTitle }}
<li>
{{ .Title }}
{{ if or (.Sections) (.Pages) }}
{{ partial "recursive.html" . }}
{{ end }}
</li>
{{ end }}
</ul>
content/recipes/_index.md looks like this:
---
title: "Recipes"
---
and for example content/recipes/drinks/_index.md looks like this:
---
title: "Drinks"
---
This produces a page at ./recipes which contains a grouped list, where the first level includes links to further list pages (e.g. ./recipes/bread), which themselves contain links to the recipes in that group. All recipes are also listed below their parent group on ./recipes.

How to add a single HUGO page independent of theme and also add reference to SCSS?

I want to add a custom HTML page completely independent of the theme but at the same time want to reference the SCSS file for style.
What I have tried till now:
As per https://gohugo.io/hugo-pipes/scss-sass/ added below in HTML, not in the layout file but the actual content HTML file.
{{ $sass := resources.Get "sass/main.scss" }}
{{ $style := $sass | resources.ToCSS }}
This output the above code without parsing.
For that custom page, you can create a new directory with the name of the page in the layouts folder and add a single.html file inside it. Also add the sass implementation in that single.html file. The folder structure will be like this:
Hugo Project
├── content
├── layouts
├── ├── _default
├── ├── partial
│ └── custom_dir(the url outside of the theme)
│ └── single.html
├── static
├── themes
└──config.toml
Sass implementation:
{{ $sass := resources.Get "sass/main.scss" }}
{{ $style := $sass | resources.ToCSS }}
<link rel="stylesheet"
href="{{ $style.Permalink }}">

Hugo not rendering the summary from the front matter

According to the Hugo content summary guide, I can define a summary in 3 ways (listed in order of highest preference):
Use the <!--more--> tag to tell how much of the article Hugo should use as the summary
Use the summary variable in the front matter in order to use a custom summary
Let Hugo by default use the first 70 words of the article
First and foremost, here is the template I have for individual pages:
{{ partial "header" . }}
{{ partial "nav" . }}
<section class="section">
<div class="container">
<div class="subtitle tags is-6 is-pulled-right">
{{ if .Params.tags }}
{{ partial "tags" .Params.tags }}
{{ end }}
</div>
{{if not .Date.IsZero }}
<h2 class="subtitle is-6">{{ .Date.Format "January 2, 2006" }}</h2>
{{ end }}
<h1 class="title">{{ .Title }}</h1>
{{ if .Site.Params.Info.related }}
<div class="related">{{ partial "related" . }}</div>
{{ end }}
<div class="content">
<h1 id="summary">Summary</h1>
{{ .Summary }}
<h1 id="toc">Table of Contents</h1>
{{ .TableOfContents }}
{{ .Content }}
</div>
</div>
</section>
{{ partial "footer" . }}
Here is a sample article I made:
---
title: "Test"
date: 2019-11-23T19:51:44-06:00
draft: true
summary: "This is a simple placeholder summary defined in the front matter"
---
This is a simple placeholder written in the article
# Section 1
Hello world!
The title and date render just fine, however, the summary is ignored and the words from the article as used as the summary:
I then used the <!--more--> tag like so:
---
title: "Test"
date: 2019-11-23T19:51:44-06:00
draft: true
summary: "This is a simple placeholder summary defined in the front matter"
---
This is a simple placeholder written in the article
<!--more-->
# Section 1
Hello world!
It worked like a charm...
So methods 1 and 3 for content summaries work, but method 2 does not. Is there a reason why I can't get the summary front matter to render?
This feature was introduce in Hugo 0.55.0 via issue #5800.
Upgrade to Hugo 0.55.0 or above to solve the issue

Resize image in Hugo (v 0.32.x) in markdown

I am trying to resize an image in Hugo (not using HTML / CSS), which is apparently available in the v 0.32 update. Beneath the "Image Processing" heading at the link in the last sentence, the following "Resize" method is described:
Resize to the given dimension, {{ $logo.Resize "200x" }} will resize to 200 pixels wide and preserve the aspect ratio. Use {{ $logo.Resize "200x100" }} to control both height and width.
I'm having some trouble implementing this in my Hugo site. In particular, I am using a .md file, and am trying to add an image which is stored somewhere else in the site's source files.
For example, here's how I would add the (not-resized) image in the .md file:
![pdf image](../static/_media/images/pdf.png)
How could I add this same file, resized to 50x50 pixels, using the resize method in the v0.32 release?
Using my newer version of Hugo (v0.53) I had to adapt the answer by JoostS a bit:
Created a page bundle
Modified the shortcode to look like this at the start:
{{ $original := .Page.Resources.GetMatch (print "images/" (.Get 0) "*") }}
You can not use it like this (in markdown). Resizing only works on resources. A resource is a file in the resource directory or a file in a page bundle. To access resources in markdown you will have to use a shortcode.
Note that you can define the static dir as the resources directory. Once you do that, you can just use the static directory and write something like:
(.Site.Resources.GetMatch "_media/images/pdf.png").Resize "50x50"
However, you should access this through a shortcode, like Talves did. I simplified his code a little for extra readability:
{{< imgresize "_media/images/pdf.png" >}}
Calling this shortcode (layouts/shortcodes/imgresize.html):
{{ $image := (.Site.Resources.GetMatch (.Get 0)).Resize "50x50" }}
<img src="{{ $image.RelPermalink }}">
As of 2022, if all you need is displaying the image in a different size, maybe Hugo’s Built-in "figure" Shortcode would do?
{{< figure src="/media/spf13.jpg" title="Steve Francia" >}}
You will need to make sure you have included your images within the content of your page usually at the level of the page itself unless you reference them using the answer I link in the note below.
NOTE: You can access resources from an outside section as in this answer
Write a shortcode
layouts/shortcodes/imgresize.html
{{ $original := .Page.Resources.GetByPrefix (.Get 0) }}
{{ $options := .Get 1 }}
{{ .Scratch.Set "image" ($original.Resize $options) }}
{{ $image := .Scratch.Get "image" }}
<img src="{{ $image.RelPermalink }}" width="{{ $image.Width }}" height="{{ $image.Height }}">
[Alternative] Shortcode accessing resource under content/media section
{{ $imagename := (.Get 0) }}
{{ $options := .Get 1 }}
{{ with .Site.GetPage "section" "media" }}
{{ $original := .Resources.GetByPrefix $imagename }}
{{ with ($original.Resize $options) }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}
{{ end }}
Call the shortcode from within the markdown of the page.
{{< imgresize pdf "50x50" >}}
pdf refers to the image by its name prefix to get the resource.
Using a sub folder page to access the resources
In the next example shortcode you must have a page at the same level as your images. Include an index.md at the same level (example: content/media/logos/index.md)
add layouts/shortcodes/logo-resize.html
{{ $imagename := (.Get 0) }}
{{ $options := .Get 1 }}
{{ with .Site.GetPage "page" "media/logos/index.md" }}
{{ $original := .Resources.GetByPrefix $imagename }}
{{ with ($original.Resize $options) }}
<img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}
{{ end }}
Call the shortcode
{{< logo-resize pdf "50x50" >}}
GitHub Example
If you're using Page Bundles you can reference any file in the page's folder, whether or not it is declared in front matter:
.
|- This is the Page (a folder)
|- index.md
|- photo1.jpg
\- photo2.jpg
INside index.md
{{< imgresize photo1.jpg "350x350" "Alternate Text" >}}
The shortcode (same as #Talves but uses GetMatch and Fit, and includes alternate text for image.)
{{ $original := .Page.Resources.GetMatch (.Get 0) }}
{{ $options := .Get 1 }}
{{ .Scratch.Set "image" ($original.Fit $options) }}
{{ $image := .Scratch.Get "image" }}
{{ $title := .Get 2 }}
<img src="{{ $image.RelPermalink }}" width="{{ $image.Width }}" height="{{ $image.Height }}" alt="{{ $title }}">
UPDATE! There is a new and better way: render hooks!
Create a render hook
For images in the markdown, you can use a ‘render hook’. This is a file that describes/overrides how markdown images are handled. To use the above approach in the render hook you should create the following file:
/layouts/_default/_markup/render-image.html
… and put this logic inside:
{{ if (resources.GetMatch .Destination) }}
<img src="
{{ ((resources.GetMatch .Destination).Fit `600x600 jpg Smart q50`).RelPermalink | safeURL }}
" alt="{{ .Text }}" />
{{ end }}
Note that we use ‘.Destination’ for the source of the original image and ‘.Text’ for the alt text defined in the markdown. Once you added the render hook all images in your Hugo project can and will be resized.
More info can be found at Hugo Codex and in the official docs.

Resources