.File.Path on zero object warning

Is there a way to debug (as in step through) templates? Because from reading the code I don’t see the problem.

{{ $self := . }}
{{ $related := len (.Params.related | default "") }}
{{ $cols := 3 }}
{{ $show := 3 }}
{{ $mod := mod $related $cols }}
{{ $sum := add $related $mod }}
{{ $total := cond (ge $sum $show) $sum $show }}

{{ $.Scratch.Set "tiles" (dict $self.File.Path 1) }}

<section class="more">
  <ol>

  {{ range .Params.related }}
    {{ with $.Site.GetPage "page" . }}
      {{ if not (index ($.Scratch.Get "tiles") .File.Path) }}
        <li class="related">
          {{ partial "article_tile.html" (dict "text" "related" "article" .) }}
          {{ $.Scratch.SetInMap "tiles" .File.Path 1 }}
        </li>
      {{ end }}
    {{ end }}
  {{ end }}

  {{ range $post := first 10 (where $.Site.Pages "Section" "posts") }}
    {{ if le (len ($.Scratch.Get "tiles")) $show }}
      {{ with $.Site.GetPage "page" $post.File.Path }}
        {{ if not (index ($.Scratch.Get "tiles") .File.Path) }}
          <li class="recent">
            {{ partial "article_tile.html" (dict "text" "recent" "article" $post) }}
            {{ $.Scratch.SetInMap "tiles" .File.Path 1 }}
          </li>
        {{ end }}
      {{ end }}
    {{ end }}
  {{ end }}

  </ol>
</section>

I would think $self being . should never be a zero object, $post should never be zero as it’s coming from range (unless I misunderstand the first 10 ) and all other .File.Path are wrapped in a with . And shouldn’t a .File always have a .Path anyway?

Only pages backed by a content file have a .File.

Before I added this warning, the File interface was embeded on Page making a monstrous big API that was only relevant for some (most, I guess, but …).

So, this was a way of cleaning up the API: If you have/need a file, do {{ .File.Filename }} (but it also warns about what’s probably a logical bug in your template: It does not make sense to apply file logic when it’s no file there …

Your problem is that you have templates that apply to both “content backed” pages and those that are not.

I don’t understand your template well enough to say for sure, but you should be able to use .Path instead of .File.Path.

Thanks, @bep. Super helpful!

This whole path thing is quite confusing. Even more so GetPage. The map just needs a unique key. So .Path seems to work fine there. But I am still unsure about using $.Site.GetPage "page" correctly.

$.Site.GetPage "page" $post.File.Path works (and is the last .File.Path reference now)
$.Site.GetPage "page" $post.Path does not work.
$.Site.GetPage "page" $post.Filename does not work either.