Substr Calculates Length of String to 0 in baseof.html

I need to access data files belonging to a content file. I followed this post: Pulling a data file based on filename

I have a strange behaviour:
If I add the following line:

{{ $company := substr $.File.LogicalName 0 -3 }}

to one of my layout files it works fine.

BUT if I add it to my baseof.html I get the following error:

<substr $.File.LogicalName 0 -3>: error calling substr: calculated start position greater than end position: 0 > -3

I checked the content of the strings end calculated lengths and it seams to be ok:

{{ $filename := printf "%s" $.File.LogicalName }} -->
{{ $strlen := len $filename }} --> 11
{{ $namelen := sub $strlen 3 }} --> 8
{{ $company := substr $filename 0 $namelen }} -->  calculated start position greater than end position: 0 > -3

Same behaviour with slicestr. In baseof.html the length of the string seams to be calculated to 0.

baseof.html template executed for all pages.
then there is a page that not backed with content file.

no content file means .File.LogicalName value is nil/0,
then substr doesnt work

better wrap the whole logic inside {{ with }}

{{ with .File }}
{{ end }}

If you want to remove the file extension, then maybe you’ll find .File.BaseFileName more convenient. (

@pamubay is probably right, the problem is not coming from, but from somewhere else. In my case, I didn’t have a file under /posts, and this was the full error:

Error building site:
failed to render pages:
*render of “section” failed:
execute of template failed: template: _default/list.html:14:7:
executing “_default/list.html” at <substr $.File.LogicalName 0 -3>:
error calling substr:
calculated start position greater than end position: 0 > -3

And the bold part is the only clue of what is missing😅

The problem is, that this substr var 0 -3 scheme was introduced just recently (I believe in 0.79.0).

Which is probably a good reason to remind to always include your Hugo version :slight_smile:

Sorry, yes I used the latest version 0.79.0

Then it should work though. You could try to debug what is inside of $.File - maybe one of your posts does not have a LogicalName value. But @acanalis is right: You should use the proper file function. It will be safer with weird file names.

Another “black box” thought: if you appoint variables with := they can’t be re-appointed later on. With a more complete sample of your file it might be possible to see, if that is happening. From a non-Go-developers mind: I always appoint a variable once with := and then overwrite the value with =.

1 Like

I found a solution.
@pamubay was right. I realised that I tried to access the File handle outside my block definitions and that doesn’t work.

My workaround is as follows:

  1. in the baseof.html file I define blocks for all the parts I want to replace later, e.g. the favicon and the title.

    {{ block “favicon” . }}
    {{ partial “site-favicon.html” . }}
    {{ end }}

  2. in the layout template I overwrite that blocks and inside the block I have access to the filename:

    {{ define “favicon” }}
    {{ partial “page-favicon.html” . }}
    {{ end }}

With page-favicon.html:

{{ $company := substr $.File.BaseFileName 0 -3 }}
{{ $staticData := (index .Site.Data.v $company) }}
{{ if $staticData }}
<link rel="shortcut icon" href="/{{ $staticData.favicon }}" type="image/x-icon" />
{{ end }}

Then I’ll use that instead. Thanx

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.