gohugoio / hugo

The world’s fastest framework for building websites.
https://gohugo.io
Apache License 2.0
73.64k stars 7.39k forks source link

Improve the cond func #5792

Open bep opened 5 years ago

bep commented 5 years ago

There are two items that I want to address:

  1. Make it use the same "truth" function as if/with/not/and -- but we should think a little if this would break stuff
  2. Lazily invocation of passed funcs/methods

Basically I want to be able to do something ala:

n := cond .File .File.Filename .Name

Maybe not the best example, but imagine a nilpointer scenario etc.

jamesgeorge007 commented 5 years ago

@bep I would love to give it a try :clap: I'm new here :beginner: It would be great if you could point me to the right files to work with :+1:

bep commented 5 years ago

@jamesgeorge007 this is a particulary hard problem. I don't know how to do it myself.

regisphilibert commented 5 years ago

One line is always better than 4, especially in Go Template.

{{ $n := .Name }}
{{ with .File }}
  {{ $n = .Filename }}
{{ end }}
jamesgeorge007 commented 5 years ago

@bep @regisphilibert if that's the case, can you point me to something that is good to start with :clap:

moorereason commented 5 years ago

Given:

n := cond .File .File.Filename .Name

@bep, as I under the existing implementation, it would blow up if .File is nil because the text/template engine would resolve .File.Filename before sending it to cond. Correct?

bep commented 5 years ago

@moorereason It would 2 days ago ... I changed it from a pointer to a struct (which is how was in 0.54) for a very similar reason.

But you are right, there are (at least) 2 reasons why I want to fix this:

The problem, I have no idea how to do this without making modifications to Go's stdlib, so I might bring it up with them (would not be too hopeful). Because now:

{{ if and .Foo .Bar }}{{ end }}

(same with or)

Is very different from:

if .Foo && .Bar {
}
bep commented 5 years ago

https://github.com/gohugoio/hugo/issues/5792

bep commented 5 years ago

I think any help from the Go stdlib in this area is long down the road. But for cond I think we could solve it by handling it as (another) special case in the AST transformer:

{{ $n := cond .File .File.Filename .Name }}

Becomes

{{ $_tmp := "" }}
{{ if .File }}
{{ $_tmp = .File.Filename }}
{{ else }}
{{ $_tmp = .Name }}
{{ end }}
{{ $n := $_tmp }}

Or similar.

moorereason commented 3 years ago

Upstream: https://github.com/golang/go/issues/31103

willfaught commented 1 year ago

What's needed to get this done? If you sketch out the likely changes that need to be made, and where to make them, I can give it a shot.