]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Clean up the css related template funcs package structure
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Sun, 23 Jun 2024 10:10:35 +0000 (12:10 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Tue, 25 Jun 2024 13:48:02 +0000 (15:48 +0200)
Deprecate and move:

* resources.ToCSS => css.SASS
* resources.PostProcess => css.PostProcess
* resources.Babel => js.Babel

Updates #12618

tpl/css/css.go
tpl/internal/templatefuncsRegistry.go
tpl/js/init.go
tpl/js/js.go
tpl/resources/init.go
tpl/resources/resources.go
tpl/tplimpl/template_funcs.go

index 51fa1d518549e8593a3088861bfc73c8b6c2c5f2..145cb3aadac0aa21c3aa1f4e981434b76fd71f31 100644 (file)
@@ -2,17 +2,40 @@ package css
 
 import (
        "context"
+       "errors"
+       "fmt"
+       "sync"
 
+       "github.com/gohugoio/hugo/common/maps"
+       "github.com/gohugoio/hugo/common/paths"
        "github.com/gohugoio/hugo/common/types/css"
        "github.com/gohugoio/hugo/deps"
+       "github.com/gohugoio/hugo/resources"
+       "github.com/gohugoio/hugo/resources/resource"
+       "github.com/gohugoio/hugo/resources/resource_transformers/babel"
+       "github.com/gohugoio/hugo/resources/resource_transformers/postcss"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/dartsass"
+       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/scss"
        "github.com/gohugoio/hugo/tpl/internal"
+       "github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
        "github.com/spf13/cast"
 )
 
 const name = "css"
 
 // Namespace provides template functions for the "css" namespace.
-type Namespace struct{}
+type Namespace struct {
+       d                 *deps.Deps
+       scssClientLibSass *scss.Client
+       postcssClient     *postcss.Client
+       babelClient       *babel.Client
+
+       // The Dart Client requires a os/exec process, so  only
+       // create it if we really need it.
+       // This is mostly to avoid creating one per site build test.
+       scssClientDartSassInit sync.Once
+       scssClientDartSass     *dartsass.Client
+}
 
 // Quoted returns a string that needs to be quoted in CSS.
 func (ns *Namespace) Quoted(v any) css.QuotedString {
@@ -26,17 +49,135 @@ func (ns *Namespace) Unquoted(v any) css.UnquotedString {
        return css.UnquotedString(s)
 }
 
+// PostCSS processes the given Resource with PostCSS.
+func (ns *Namespace) PostCSS(args ...any) (resource.Resource, error) {
+       if len(args) > 2 {
+               return nil, errors.New("must not provide more arguments than resource object and options")
+       }
+
+       r, m, err := resourcehelpers.ResolveArgs(args)
+       if err != nil {
+               return nil, err
+       }
+
+       return ns.postcssClient.Process(r, m)
+}
+
+// Sass processes the given Resource with Sass.
+func (ns *Namespace) Sass(args ...any) (resource.Resource, error) {
+       if len(args) > 2 {
+               return nil, errors.New("must not provide more arguments than resource object and options")
+       }
+
+       const (
+               // Transpiler implementation can be controlled from the client by
+               // setting the 'transpiler' option.
+               // Default is currently 'libsass', but that may change.
+               transpilerDart    = "dartsass"
+               transpilerLibSass = "libsass"
+       )
+
+       var (
+               r          resources.ResourceTransformer
+               m          map[string]any
+               targetPath string
+               err        error
+               ok         bool
+               transpiler = transpilerLibSass
+       )
+
+       r, targetPath, ok = resourcehelpers.ResolveIfFirstArgIsString(args)
+
+       if !ok {
+               r, m, err = resourcehelpers.ResolveArgs(args)
+               if err != nil {
+                       return nil, err
+               }
+       }
+
+       if m != nil {
+               if t, _, found := maps.LookupEqualFold(m, "transpiler"); found {
+                       switch t {
+                       case transpilerDart, transpilerLibSass:
+                               transpiler = cast.ToString(t)
+                       default:
+                               return nil, fmt.Errorf("unsupported transpiler %q; valid values are %q or %q", t, transpilerLibSass, transpilerDart)
+                       }
+               }
+       }
+
+       if transpiler == transpilerLibSass {
+               var options scss.Options
+               if targetPath != "" {
+                       options.TargetPath = paths.ToSlashTrimLeading(targetPath)
+               } else if m != nil {
+                       options, err = scss.DecodeOptions(m)
+                       if err != nil {
+                               return nil, err
+                       }
+               }
+
+               return ns.scssClientLibSass.ToCSS(r, options)
+       }
+
+       if m == nil {
+               m = make(map[string]any)
+       }
+       if targetPath != "" {
+               m["targetPath"] = targetPath
+       }
+
+       client, err := ns.getscssClientDartSass()
+       if err != nil {
+               return nil, err
+       }
+
+       return client.ToCSS(r, m)
+}
+
 func init() {
        f := func(d *deps.Deps) *internal.TemplateFuncsNamespace {
-               ctx := &Namespace{}
+               scssClient, err := scss.New(d.BaseFs.Assets, d.ResourceSpec)
+               if err != nil {
+                       panic(err)
+               }
+               ctx := &Namespace{
+                       d:                 d,
+                       scssClientLibSass: scssClient,
+                       postcssClient:     postcss.New(d.ResourceSpec),
+                       babelClient:       babel.New(d.ResourceSpec),
+               }
 
                ns := &internal.TemplateFuncsNamespace{
                        Name:    name,
                        Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil },
                }
 
+               ns.AddMethodMapping(ctx.Sass,
+                       []string{"toCSS"},
+                       [][2]string{},
+               )
+
+               ns.AddMethodMapping(ctx.PostCSS,
+                       []string{"postCSS"},
+                       [][2]string{},
+               )
+
                return ns
        }
 
        internal.AddTemplateFuncsNamespace(f)
 }
+
+func (ns *Namespace) getscssClientDartSass() (*dartsass.Client, error) {
+       var err error
+       ns.scssClientDartSassInit.Do(func() {
+               ns.scssClientDartSass, err = dartsass.New(ns.d.BaseFs.Assets, ns.d.ResourceSpec)
+               if err != nil {
+                       return
+               }
+               ns.d.BuildClosers.Add(ns.scssClientDartSass)
+       })
+
+       return ns.scssClientDartSass, err
+}
index fc02a6ef90212f491fb1d142aa4e508c6cc9021b..1b74bf443a158db57250d70838a9b5a03060f742 100644 (file)
@@ -51,6 +51,9 @@ type TemplateFuncsNamespace struct {
        // This is the method receiver.
        Context func(ctx context.Context, v ...any) (any, error)
 
+       // OnCreated is called when all the namespaces are ready.
+       OnCreated func(namespaces map[string]any)
+
        // Additional info, aliases and examples, per method name.
        MethodMappings map[string]TemplateFuncMethodMapping
 }
index 16e6c7efad126452cb1fd2d2652e2dbc39d88b92..69d7c7275d6a183298ffcf841cf0d841e04549c8 100644 (file)
@@ -31,6 +31,11 @@ func init() {
                        Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil },
                }
 
+               ns.AddMethodMapping(ctx.Babel,
+                       []string{"babel"},
+                       [][2]string{},
+               )
+
                return ns
        }
 
index 63a6765328fcd9f626d8a0fb4a22790e93e5bd5a..c68e0af9272673a1c01ad7b3e5cd54d5ce7da23e 100644 (file)
 package js
 
 import (
+       "errors"
+
        "github.com/gohugoio/hugo/deps"
        "github.com/gohugoio/hugo/resources"
        "github.com/gohugoio/hugo/resources/resource"
+       "github.com/gohugoio/hugo/resources/resource_transformers/babel"
        "github.com/gohugoio/hugo/resources/resource_transformers/js"
        "github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
 )
@@ -28,13 +31,15 @@ func New(deps *deps.Deps) *Namespace {
                return &Namespace{}
        }
        return &Namespace{
-               client: js.New(deps.BaseFs.Assets, deps.ResourceSpec),
+               client:      js.New(deps.BaseFs.Assets, deps.ResourceSpec),
+               babelClient: babel.New(deps.ResourceSpec),
        }
 }
 
 // Namespace provides template functions for the "js" namespace.
 type Namespace struct {
-       client *js.Client
+       client      *js.Client
+       babelClient *babel.Client
 }
 
 // Build processes the given Resource with ESBuild.
@@ -62,3 +67,24 @@ func (ns *Namespace) Build(args ...any) (resource.Resource, error) {
 
        return ns.client.Process(r, m)
 }
+
+// Babel processes the given Resource with Babel.
+func (ns *Namespace) Babel(args ...any) (resource.Resource, error) {
+       if len(args) > 2 {
+               return nil, errors.New("must not provide more arguments than resource object and options")
+       }
+
+       r, m, err := resourcehelpers.ResolveArgs(args)
+       if err != nil {
+               return nil, err
+       }
+       var options babel.Options
+       if m != nil {
+               options, err = babel.DecodeOptions(m)
+               if err != nil {
+                       return nil, err
+               }
+       }
+
+       return ns.babelClient.Process(r, options)
+}
index db51b0287e570077268a27ed5276200f444b6dbe..5cea482acc36ff47bb0bc57a867749cae478f8ac 100644 (file)
@@ -17,7 +17,9 @@ import (
        "context"
 
        "github.com/gohugoio/hugo/deps"
+       "github.com/gohugoio/hugo/tpl/css"
        "github.com/gohugoio/hugo/tpl/internal"
+       "github.com/gohugoio/hugo/tpl/js"
 )
 
 const name = "resources"
@@ -33,6 +35,22 @@ func init() {
                ns := &internal.TemplateFuncsNamespace{
                        Name:    name,
                        Context: func(cctx context.Context, args ...any) (any, error) { return ctx, nil },
+                       OnCreated: func(m map[string]any) {
+                               for _, v := range m {
+                                       switch v := v.(type) {
+                                       case *css.Namespace:
+                                               ctx.cssNs = v
+                                       case *js.Namespace:
+                                               ctx.jsNs = v
+                                       }
+                               }
+                               if ctx.cssNs == nil {
+                                       panic("css namespace not found")
+                               }
+                               if ctx.jsNs == nil {
+                                       panic("js namespace not found")
+                               }
+                       },
                }
 
                ns.AddMethodMapping(ctx.Get,
@@ -57,21 +75,6 @@ func init() {
                        [][2]string{},
                )
 
-               ns.AddMethodMapping(ctx.ToCSS,
-                       []string{"toCSS"},
-                       [][2]string{},
-               )
-
-               ns.AddMethodMapping(ctx.PostCSS,
-                       []string{"postCSS"},
-                       [][2]string{},
-               )
-
-               ns.AddMethodMapping(ctx.Babel,
-                       []string{"babel"},
-                       [][2]string{},
-               )
-
                return ns
        }
 
index 34b4464be27b06ecda434d2a5fc70a3a55702e46..78340b1ff2b99a064f9400919d8e21c91b1f0209 100644 (file)
@@ -18,12 +18,12 @@ import (
        "context"
        "errors"
        "fmt"
-       "sync"
 
+       "github.com/gohugoio/hugo/common/hugo"
        "github.com/gohugoio/hugo/common/maps"
-       "github.com/gohugoio/hugo/common/paths"
 
-       "github.com/gohugoio/hugo/tpl/internal/resourcehelpers"
+       "github.com/gohugoio/hugo/tpl/css"
+       "github.com/gohugoio/hugo/tpl/js"
 
        "github.com/gohugoio/hugo/resources/postpub"
 
@@ -33,13 +33,9 @@ import (
 
        "github.com/gohugoio/hugo/resources/resource_factories/bundler"
        "github.com/gohugoio/hugo/resources/resource_factories/create"
-       "github.com/gohugoio/hugo/resources/resource_transformers/babel"
        "github.com/gohugoio/hugo/resources/resource_transformers/integrity"
        "github.com/gohugoio/hugo/resources/resource_transformers/minifier"
-       "github.com/gohugoio/hugo/resources/resource_transformers/postcss"
        "github.com/gohugoio/hugo/resources/resource_transformers/templates"
-       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/dartsass"
-       "github.com/gohugoio/hugo/resources/resource_transformers/tocss/scss"
 
        "github.com/spf13/cast"
 )
@@ -50,26 +46,18 @@ func New(deps *deps.Deps) (*Namespace, error) {
                return &Namespace{}, nil
        }
 
-       scssClient, err := scss.New(deps.BaseFs.Assets, deps.ResourceSpec)
-       if err != nil {
-               return nil, err
-       }
-
        minifyClient, err := minifier.New(deps.ResourceSpec)
        if err != nil {
                return nil, err
        }
 
        return &Namespace{
-               deps:              deps,
-               scssClientLibSass: scssClient,
-               createClient:      create.New(deps.ResourceSpec),
-               bundlerClient:     bundler.New(deps.ResourceSpec),
-               integrityClient:   integrity.New(deps.ResourceSpec),
-               minifyClient:      minifyClient,
-               postcssClient:     postcss.New(deps.ResourceSpec),
-               templatesClient:   templates.New(deps.ResourceSpec, deps),
-               babelClient:       babel.New(deps.ResourceSpec),
+               deps:            deps,
+               createClient:    create.New(deps.ResourceSpec),
+               bundlerClient:   bundler.New(deps.ResourceSpec),
+               integrityClient: integrity.New(deps.ResourceSpec),
+               minifyClient:    minifyClient,
+               templatesClient: templates.New(deps.ResourceSpec, deps),
        }, nil
 }
 
@@ -79,33 +67,16 @@ var _ resource.ResourceFinder = (*Namespace)(nil)
 type Namespace struct {
        deps *deps.Deps
 
-       createClient      *create.Client
-       bundlerClient     *bundler.Client
-       scssClientLibSass *scss.Client
-       integrityClient   *integrity.Client
-       minifyClient      *minifier.Client
-       postcssClient     *postcss.Client
-       babelClient       *babel.Client
-       templatesClient   *templates.Client
-
-       // The Dart Client requires a os/exec process, so  only
-       // create it if we really need it.
-       // This is mostly to avoid creating one per site build test.
-       scssClientDartSassInit sync.Once
-       scssClientDartSass     *dartsass.Client
-}
-
-func (ns *Namespace) getscssClientDartSass() (*dartsass.Client, error) {
-       var err error
-       ns.scssClientDartSassInit.Do(func() {
-               ns.scssClientDartSass, err = dartsass.New(ns.deps.BaseFs.Assets, ns.deps.ResourceSpec)
-               if err != nil {
-                       return
-               }
-               ns.deps.BuildClosers.Add(ns.scssClientDartSass)
-       })
+       createClient    *create.Client
+       bundlerClient   *bundler.Client
+       integrityClient *integrity.Client
+       minifyClient    *minifier.Client
+       templatesClient *templates.Client
 
-       return ns.scssClientDartSass, err
+       // We moved some CSS and JS related functions to the css and js package in Hugo 0.128.0.
+       // Keep this here until the deprecation period is over.
+       cssNs *css.Namespace
+       jsNs  *js.Namespace
 }
 
 // Copy copies r to the new targetPath in s.
@@ -337,89 +308,17 @@ func (ns *Namespace) Minify(r resources.ResourceTransformer) (resource.Resource,
 // ToCSS converts the given Resource to CSS. You can optional provide an Options object
 // as second argument. As an option, you can e.g. specify e.g. the target path (string)
 // for the converted CSS resource.
+// Deprecated: Moved to the css namespace in Hugo 0.128.0.
 func (ns *Namespace) ToCSS(args ...any) (resource.Resource, error) {
-       if len(args) > 2 {
-               return nil, errors.New("must not provide more arguments than resource object and options")
-       }
-
-       const (
-               // Transpiler implementation can be controlled from the client by
-               // setting the 'transpiler' option.
-               // Default is currently 'libsass', but that may change.
-               transpilerDart    = "dartsass"
-               transpilerLibSass = "libsass"
-       )
-
-       var (
-               r          resources.ResourceTransformer
-               m          map[string]any
-               targetPath string
-               err        error
-               ok         bool
-               transpiler = transpilerLibSass
-       )
-
-       r, targetPath, ok = resourcehelpers.ResolveIfFirstArgIsString(args)
-
-       if !ok {
-               r, m, err = resourcehelpers.ResolveArgs(args)
-               if err != nil {
-                       return nil, err
-               }
-       }
-
-       if m != nil {
-               if t, _, found := maps.LookupEqualFold(m, "transpiler"); found {
-                       switch t {
-                       case transpilerDart, transpilerLibSass:
-                               transpiler = cast.ToString(t)
-                       default:
-                               return nil, fmt.Errorf("unsupported transpiler %q; valid values are %q or %q", t, transpilerLibSass, transpilerDart)
-                       }
-               }
-       }
-
-       if transpiler == transpilerLibSass {
-               var options scss.Options
-               if targetPath != "" {
-                       options.TargetPath = paths.ToSlashTrimLeading(targetPath)
-               } else if m != nil {
-                       options, err = scss.DecodeOptions(m)
-                       if err != nil {
-                               return nil, err
-                       }
-               }
-
-               return ns.scssClientLibSass.ToCSS(r, options)
-       }
-
-       if m == nil {
-               m = make(map[string]any)
-       }
-       if targetPath != "" {
-               m["targetPath"] = targetPath
-       }
-
-       client, err := ns.getscssClientDartSass()
-       if err != nil {
-               return nil, err
-       }
-
-       return client.ToCSS(r, m)
+       hugo.Deprecate("resources.ToCSS", "Use css.SASS.", "v0.128.0")
+       return ns.cssNs.Sass(args...)
 }
 
-// PostCSS processes the given Resource with PostCSS
+// PostCSS processes the given Resource with PostCSS.
+// Deprecated: Moved to the css namespace in Hugo 0.128.0.
 func (ns *Namespace) PostCSS(args ...any) (resource.Resource, error) {
-       if len(args) > 2 {
-               return nil, errors.New("must not provide more arguments than resource object and options")
-       }
-
-       r, m, err := resourcehelpers.ResolveArgs(args)
-       if err != nil {
-               return nil, err
-       }
-
-       return ns.postcssClient.Process(r, m)
+       hugo.Deprecate("resources.PostCSS", "Use css.PostCSS.", "v0.128.0")
+       return ns.cssNs.PostCSS(args...)
 }
 
 // PostProcess processes r after the build.
@@ -428,22 +327,8 @@ func (ns *Namespace) PostProcess(r resource.Resource) (postpub.PostPublishedReso
 }
 
 // Babel processes the given Resource with Babel.
+// Deprecated: Moved to the js namespace in Hugo 0.128.0.
 func (ns *Namespace) Babel(args ...any) (resource.Resource, error) {
-       if len(args) > 2 {
-               return nil, errors.New("must not provide more arguments than resource object and options")
-       }
-
-       r, m, err := resourcehelpers.ResolveArgs(args)
-       if err != nil {
-               return nil, err
-       }
-       var options babel.Options
-       if m != nil {
-               options, err = babel.DecodeOptions(m)
-               if err != nil {
-                       return nil, err
-               }
-       }
-
-       return ns.babelClient.Process(r, options)
+       hugo.Deprecate("resources.Babel", "Use js.Babel.", "v0.128.0")
+       return ns.jsNs.Babel(args...)
 }
index e5ee4d54f80be5716e54e9ec082b8c855260f04d..815270631499fb12a8596a88c7be919507c285e3 100644 (file)
@@ -252,6 +252,9 @@ func newTemplateExecuter(d *deps.Deps) (texttemplate.Executer, map[string]reflec
 func createFuncMap(d *deps.Deps) map[string]any {
        funcMap := template.FuncMap{}
 
+       nsMap := make(map[string]any)
+       var onCreated []func(namespaces map[string]any)
+
        // Merge the namespace funcs
        for _, nsf := range internal.TemplateFuncsNamespaceRegistry {
                ns := nsf(d)
@@ -259,6 +262,11 @@ func createFuncMap(d *deps.Deps) map[string]any {
                        panic(ns.Name + " is a duplicate template func")
                }
                funcMap[ns.Name] = ns.Context
+               contextV, err := ns.Context(context.Background())
+               if err != nil {
+                       panic(err)
+               }
+               nsMap[ns.Name] = contextV
                for _, mm := range ns.MethodMappings {
                        for _, alias := range mm.Aliases {
                                if _, exists := funcMap[alias]; exists {
@@ -267,6 +275,14 @@ func createFuncMap(d *deps.Deps) map[string]any {
                                funcMap[alias] = mm.Method
                        }
                }
+
+               if ns.OnCreated != nil {
+                       onCreated = append(onCreated, ns.OnCreated)
+               }
+       }
+
+       for _, f := range onCreated {
+               f(nsMap)
        }
 
        if d.OverloadedTemplateFuncs != nil {