Returning decimal number from site data as-is

I’m pulling in numbers from a data file that look like this:

  • 1.2
  • 0.1
  • 0.0046
  • 0.000084

All was going well until I hit that last example; by default Hugo outputs that number as “8.4e-05”

I know about lang.NumFmt but that requires specifying the level of precision, which tacks on trailing 0s to fill it out. So if I do lang.NumFmt 6 $var I get:

  • 1.200000
  • 0.100000
  • 0.004600
  • 0.000084

And of course if a number came along in the future that was greater than 6 decimal places out, it would get rounded, which I don’t want.

How can I tell Hugo to return a float64 number as-is without formatting or changing it?

Storing the numbers as strings in my data (the only workaround I can find for now) feels kludgy, and of course means I can’t format or calculate with those numbers when I do want to do that.

Thanks!

Cast to string:

{{ range site.Data.foo.numbers }}
  {{ . | string }}
{{ end }}
3 Likes

OK but what if I don’t want them as strings? What if I want them to continue to be numbers that I can, say, perform math operations on? There’s no way to tell Hugo “print my number just how it was entered” and it remain a number?

Then keep them as numbers while you’re doing your calculations, and cast to string when you’re ready to display the results.

The fmt equivalent is:

{{ range site.Data.foo.numbers }}
  {{ . | printf "%f" | strings.TrimRight "0" }}
{{ end }}
1 Like

OK, thanks.

I don’t suppose Hugo would consider creating a formatter that just outputs the number? (Like a shortcut for the fmt syntax you gave me above.)

Having Hugo modify the display of a decimal number by default is unexpected, and I wouldn’t have caught it at all if I hadn’t been editing the CSS of the data table. I’ve definitely never run across the advice “make sure to cast your numbers to strings if you don’t want Hugo to modify their format”…

Internal and external (printed) representations of numbers are two different things.

…right. I’m not sure how that addresses a) the request for a formatter outputting the number or b) doing something different by default, or at least documenting what happens by default.

Remember that all of these produce strings:

{{ 0.00001 | printf "%18.9f" }}                          --> 0.000010000
{{ 0.00001 | printf "%18.9f" | strings.TrimRight "0" }}  --> 0.00001
{{ 0.00001 | string }}                                   --> 0.00001

If you want a new “formatter” the Go team would need to implement a new verb for printf, essentially a hybrid of v, f and g where:

  • The input can be an int or float[1]
  • The result is presented without scientific notation
  • The number of significant digits is determined automatically
  • No trailing zeros

What I’ve described is what you get with:

{{ 0.00001 | string }}

You’re welcome to open an issue with the Go team, though I wouldn’t hold my breath.


  1. When using data files (e.g., site.Data.foo) to store numbers, the data type is dependent on format. While TOML and YAML support int and float data types, JSON only supports floats. So if you’re using TOML or YAML, and you have an integer, the f and g verbs will cause printf to throw an error. ↩︎

OK, I understand what you’re saying about the formatter in Go, thanks. I was talking about something akin to lang.NumFmt but maybe my terminology was confusing.

In any case, if Hugo developers don’t see a value in establishing their own…system for displaying numbers untouched by formatting…is there any objection to at a minimum documenting somewhere that numbers, if they are not cast to strings, will be by default outputted according to x formatting rules? (Such as the scientific notation beyond a certain number of decimal points.) Even if that’s rooted in Go’s behavior, it seems like it’s not unreasonable to want some documentation of how it shows up when Hugo renders data.

You’re welcome to create an issue in the Hugo docs repository, though I’m not really sure where this would go.

The default is the same as the v verb for printf.

{{ 0.00001 }}               --> 1e-05
{{ 0.00001 | printf "%v"}}  --> 1e-05

Thanks. Since issues in the repos tend to get shut down pretty quickly, I wanted to make sure there was a go-ahead before I spent any time on an issue/PR.

FYI. PHP does the same thing…

$num = 0.00001;
echo $num;              // 1.0E-5
printf("%f", $num);     // 0.000010
printf("%18.9f", $num); // 0.000010000

@jmooring True! But, for instance, I don’t believe that WordPress, Drupal or Joomla do, even when fed data via an API.

And while I realize using site data in Hugo is a little closer to the bare (programming) metal, I’d see Hugo as akin to these other systems that use a programming language rather than are a programming language. Somewhere along the line each of those projects decided that while PHP did one thing, with good reason as a programming language, they would do something else, with good reason as site generators.

I get why Go does it as a language. But I think site editors are a layer removed from the language used to build the system in which they work, and I think most would be surprised to see their data being changed by default.