New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add template funcs namespaces #3042

Closed
bep opened this Issue Feb 16, 2017 · 6 comments

Comments

Projects
None yet
4 participants
@bep
Member

bep commented Feb 16, 2017

See #3040

I don't mind adding more template funcs, but we should have some kind of name spacing to make them easier to manage/document, i.e. strings.trimPrefix etc. Not sure how the "." works in this case, but then find something else ("_"?)

We should keep the "old" names as aliases, of course, but this will lead to more natural names like:

  • image.config
  • image.resize
  • etc.

@moorereason @digitalcraftsman

@bep bep changed the title from Add tempalte funcs namespaces to Add template funcs namespaces Feb 16, 2017

@thiagomgd

This comment has been minimized.

Show comment
Hide comment
@thiagomgd

thiagomgd Feb 16, 2017

I think it's way easier to have fewer functions, but with the namespaces to add more options. Thumbs up for this issue!

thiagomgd commented Feb 16, 2017

I think it's way easier to have fewer functions, but with the namespaces to add more options. Thumbs up for this issue!

@moorereason

This comment has been minimized.

Show comment
Hide comment
@moorereason

moorereason Feb 17, 2017

Contributor

I made a proof of concept locally that allows strings.TrimPrefix. The trick is to create a func that returns a struct which has the namespace funcs defined on it:

func stringsNS() *stringsNamespace {
	// should probably use a global instead of a new instance
	return &stringsNamespace{}
}

type stringsNamespace struct{}

// TrimPrefix returns s without the provided leading prefix string. If s doesn't
// start with prefix, s is returned unchanged.
func (_ *stringsNamespace) TrimPrefix(prefix, s interface{}) (string, error) {
	p, err := cast.ToStringE(prefix)
	if err != nil {
		return "", err
	}

	ss, err := cast.ToStringE(s)
	if err != nil {
		return "", err
	}

	return strings.TrimPrefix(ss, p), nil
}

// funcMap := template.FuncMap{
//     "strings":  stringsNS,

Usage:

{{ strings.TrimPrefix "$" "$BatMan" }}
{{ "$BatMan" | strings.TrimPrefix "$" }}

So, we can accomplish what we want. We just need to come up with a more formal proposal to redo the funcmap with namespaces.

Contributor

moorereason commented Feb 17, 2017

I made a proof of concept locally that allows strings.TrimPrefix. The trick is to create a func that returns a struct which has the namespace funcs defined on it:

func stringsNS() *stringsNamespace {
	// should probably use a global instead of a new instance
	return &stringsNamespace{}
}

type stringsNamespace struct{}

// TrimPrefix returns s without the provided leading prefix string. If s doesn't
// start with prefix, s is returned unchanged.
func (_ *stringsNamespace) TrimPrefix(prefix, s interface{}) (string, error) {
	p, err := cast.ToStringE(prefix)
	if err != nil {
		return "", err
	}

	ss, err := cast.ToStringE(s)
	if err != nil {
		return "", err
	}

	return strings.TrimPrefix(ss, p), nil
}

// funcMap := template.FuncMap{
//     "strings":  stringsNS,

Usage:

{{ strings.TrimPrefix "$" "$BatMan" }}
{{ "$BatMan" | strings.TrimPrefix "$" }}

So, we can accomplish what we want. We just need to come up with a more formal proposal to redo the funcmap with namespaces.

@digitalcraftsman

This comment has been minimized.

Show comment
Hide comment
@digitalcraftsman

digitalcraftsman Feb 17, 2017

Member

Adding namespaces is a good idea if we add more functionality to the templates. The docs already loosely groups template functions by "namespaces" / usecases.

However, do you want to put every function in a namespace, even standard ones like div in math.div?

How do we handle this redundancy of template functions from a long-term perspective?

Will we depecrate them (not immediately, but one day in the future) or do we continue with this double-barreled approach? Deprecating them would be affect nearly every Hugo site.

While introducing namespaces, should we document the functions by namespaces and just mention that the aliases still exist? Or will it be done vice versa by leaving the docs as they are and note that the usage of namespaces if preferred/advised?

Member

digitalcraftsman commented Feb 17, 2017

Adding namespaces is a good idea if we add more functionality to the templates. The docs already loosely groups template functions by "namespaces" / usecases.

However, do you want to put every function in a namespace, even standard ones like div in math.div?

How do we handle this redundancy of template functions from a long-term perspective?

Will we depecrate them (not immediately, but one day in the future) or do we continue with this double-barreled approach? Deprecating them would be affect nearly every Hugo site.

While introducing namespaces, should we document the functions by namespaces and just mention that the aliases still exist? Or will it be done vice versa by leaving the docs as they are and note that the usage of namespaces if preferred/advised?

@bep

This comment has been minimized.

Show comment
Hide comment
@bep

bep Feb 17, 2017

Member

How do we handle this redundancy of template functions from a long-term perspective?

I think we leave the once we have as aliases -- some of them may make sense to deprecate at some point, but some of them is obviously good as "short form" (where being one example).

When we redo the docs, we might put emphasis on the "namespaced" versions.

  • For future template funcs, they will be put in its namespace and only there
  • If it is in the "where league", it may get a shortform alias
Member

bep commented Feb 17, 2017

How do we handle this redundancy of template functions from a long-term perspective?

I think we leave the once we have as aliases -- some of them may make sense to deprecate at some point, but some of them is obviously good as "short form" (where being one example).

When we redo the docs, we might put emphasis on the "namespaced" versions.

  • For future template funcs, they will be put in its namespace and only there
  • If it is in the "where league", it may get a shortform alias
@bep

This comment has been minimized.

Show comment
Hide comment
@bep

bep Feb 18, 2017

Member

Here is the suggested game plan:

  • Add an interface in /tpl, say:
interface TplFuncsNamespacer {
   NewNamespace(d *deps.Deps) TplFuncsNameSpace // name + interface{} + global TemplateFuncs aliases
}

Then

  • Create a package below /tpl for each logical unit (if we wrap funcs from the Go stdlib, we should name them the same), so /tpl/strings /tpl/math etc.
  • Add a top level NamespaceRegister and add to that register from each package's init() func.
  • Do a blank import of those packages etc. from /tplimpl
Member

bep commented Feb 18, 2017

Here is the suggested game plan:

  • Add an interface in /tpl, say:
interface TplFuncsNamespacer {
   NewNamespace(d *deps.Deps) TplFuncsNameSpace // name + interface{} + global TemplateFuncs aliases
}

Then

  • Create a package below /tpl for each logical unit (if we wrap funcs from the Go stdlib, we should name them the same), so /tpl/strings /tpl/math etc.
  • Add a top level NamespaceRegister and add to that register from each package's init() func.
  • Do a blank import of those packages etc. from /tplimpl

@bep bep added this to the v0.20 milestone Mar 1, 2017

@moorereason moorereason referenced this issue Mar 14, 2017

Merged

tpl: Add namespaced template functions #3177

3 of 3 tasks complete
@moorereason

This comment has been minimized.

Show comment
Hide comment
@moorereason
Contributor

moorereason commented Mar 15, 2017

Related discussion: https://discuss.gohugo.io/t/5800

@bep bep modified the milestones: v0.21, v0.20 Mar 31, 2017

moorereason added a commit to moorereason/hugo that referenced this issue Apr 30, 2017

tpl: Add template function namespaces
This commit moves almost all of the template functions into separate
packages under tpl/ and adds a namespace framework.  All changes should
be backward compatible for end users, as all existing function names in
the template funcMap are left intact.

Seq and DoArithmatic have been moved out of the helpers package and into
template namespaces.

Most of the tests involved have been refactored, and many new tests have
been written.  There's still work to do, but this is a big improvement.

I got a little overzealous and added some new functions along the way:

- strings.Contains
- strings.ContainsAny
- strings.HasSuffix
- strings.TrimPrefix
- strings.TrimSuffix

Documentation is forthcoming.

Fixes gohugoio#3042

@bep bep closed this in de7c32a Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

tpl: Add TemplateFuncsNamespaceRegistry
As a first step to remove the hard ties between `tplimpl` and the different namespace packages.

The `lang` package is used as the first example use case.

See gohugoio#3042

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue Apr 30, 2017

bep added a commit to bep/hugo that referenced this issue May 1, 2017

bep added a commit that referenced this issue May 1, 2017

tpl: Add TemplateFuncsNamespaceRegistry
As a first step to remove the hard ties between `tplimpl` and the different namespace packages.

The `lang` package is used as the first example use case.

See #3042

bep added a commit that referenced this issue May 1, 2017

bep added a commit that referenced this issue May 1, 2017

bep added a commit that referenced this issue May 1, 2017

bep added a commit that referenced this issue May 1, 2017

bep added a commit that referenced this issue May 1, 2017

bep added a commit that referenced this issue May 1, 2017

@ghost ghost referenced this issue May 22, 2017

Open

spf13/hugo v0.21 released #10

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment