Set frontmatter params in list template?

All pages does not have weight params in frontmatter.
I want to set weight params in code based on file name.
File name format is xx_String.md.
xx is 2 digits.
So, I can get xx from bellow code, and hope to know //**//

 {{ range .Pages }}
        {{ $weight := substr .File.BaseFileName 0 2}}
       // * what method can I use for setting every page's weight with above value *//           
 {{ end }}   

If anyone have experiences on this, please let me know kindly…
Warm Regards.

I don’t think you can set page-level variables in the front matter. But you can set page-scoped, writable variables using .Scratch

{{ range .Pages }}
  {{ $weight := substr .File.BaseFileName 0 2 }}
  {{ .Scratch.Set "weight" $weight }}         
{{ end }}  

Then, for example, if you wanted to print the weight of each page

{{ range .Pages }}
  {{ printf "%v" (.Scratch.Get "weight") }}
{{ end }}

Yes.
Btw, I want to use this weight for the ordering.
That is my issue.
could you let me know about that.
Thanks.

I don’t think what you want is currently possible in Hugo.

If you prefix the file names with numbers, the ordering should anyways happen based on those numbers.

(I am already using that trick in one of my sites, though for menu names. I then remove the prefix numbers when displaying the menu name.)

If that doesn’t work, you can run a custom script before running Hugo that sets the weight in the file’s front-matter based on the file name prefix.

Hi, Bep.
Thanks for your response.
Then, how can I order list based on filename?
Is it possible?

Thanks, Kaushalmodi.

Could you let me know specific samples?

Here’s a sample script. You’d run this in the same directory that has the content files you want edited. What it does:

  • Loops through all .md files in the directory
  • Sets a weight var with the first 2 chars of the filename
  • Calls an awk program that inserts the weight: xx into the front matter, right above the last ---
  • It then overwrites the file with the new changes

This assumes yaml for your front matter. If you use toml, you’ll need to adjust this script accordingly.

#!/bin/bash

for file in *.md; do
    weight=${file:0:2}
    awk -v weight=$weight '/---/{
        count++
        if(count == 2){
        sub("---","weight: " weight "\n---",$0)
        }
    }
    {print}' $file > tmp && mv tmp $file
done

Then you should be able to do

{{ range .Pages.ByWeight }}
<!-- some code -->
{{ end 
3 Likes

Hi @tania,

I’m trying to do exactly the same thing: setting some param (like date, weight and title) from the filename, so that I can for instance use them in a range in the context of a list of content.

Did you eventually come up with a workaround?

I thought it would have been easy to extract a $value from the .File.BaseFileName with functions like trim and replaceRE and use it to override a .Page.Param like .Weight, .Date or .Title (would it be set in the page front-matter or not)…

I would like to do so without an archetype nor a bash script because while they seem to be both working solutions they’re not so convenient/flexible as they require running ‘manual’ operations (creating the new page or executing the script).

@bep, is Hugo now offering such a possibility? Or is there another way to do so ?

If not, alternatively, maybe the function range .Pages.ByParam could be extended to something like this: range .Pages.By$value?
In which case we wouldn’t even need to be able to override any .Page.Param.

I believe filenames are great pieces of metadata.

Thank you for your help! and for developing this awesome tool that is Hugo :slight_smile:

Edit: Thanks @jmooring however i beleive discouraging doesn’t mean closing the discussion - but I’m not native locutor… If thats your policy, you should configure discourse to close inactive discussions by itself.

See https://discourse.gohugo.io/t/requesting-help/9132

We discourage reviving old topics because people who participated in those discussions of yesteryear are usually not here anymore and they rarely reply to questions. It is best to open a new topic rather than bumping an old one.