Skip to content

Commit

Permalink
Clean up the css related template funcs package structure
Browse files Browse the repository at this point in the history
Deprecate and move:

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

Updates #12618
  • Loading branch information
bep committed Jun 25, 2024
1 parent 1687a9a commit eddcd2b
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 162 deletions.
145 changes: 143 additions & 2 deletions tpl/css/css.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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
}
3 changes: 3 additions & 0 deletions tpl/internal/templatefuncsRegistry.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
5 changes: 5 additions & 0 deletions tpl/js/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
30 changes: 28 additions & 2 deletions tpl/js/js.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
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"
)
Expand All @@ -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.
Expand Down Expand Up @@ -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)
}
33 changes: 18 additions & 15 deletions tpl/resources/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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,
Expand All @@ -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
}

Expand Down
Loading

0 comments on commit eddcd2b

Please sign in to comment.