From b4afb26d28562e798a54813f23279e648fa8a08a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Amate=20Ram=C3=ADrez?= Date: Tue, 18 Nov 2025 16:05:08 +0100 Subject: [PATCH 1/9] feat: add RemoveTag engine method --- engine.go | 4 ++++ engine_examples_test.go | 18 ++++++++++++++++++ render/tags.go | 5 +++++ 3 files changed, 27 insertions(+) diff --git a/engine.go b/engine.go index 8e1cfe2a..274f0421 100644 --- a/engine.go +++ b/engine.go @@ -173,3 +173,7 @@ func (e *Engine) ParseTemplateAndCache(source []byte, path string, line int) (*T func (e *Engine) SetAutoEscapeReplacer(replacer render.Replacer) { e.cfg.SetAutoEscapeReplacer(replacer) } + +func (e *Engine) RemoveTag(name string) { + e.cfg.RemoveTag(name) +} diff --git a/engine_examples_test.go b/engine_examples_test.go index d977abfa..a7f7cd03 100644 --- a/engine_examples_test.go +++ b/engine_examples_test.go @@ -305,3 +305,21 @@ func TestIssue63_UnicodeVariableNames(t *testing.T) { require.Equal(t, "content", string(result)) }) } + +func TestRemoveTag(t *testing.T) { + template := NewEngine() + template.RegisterTag("echo", func(c render.Context) (string, error) { + return c.TagArgs(), nil + }) + + source := `{% echo hello world %}` + + out, err := template.ParseAndRenderString(source, emptyBindings) + require.NoError(t, err) + require.Equal(t, "hello world", out) + + template.RemoveTag("echo") + + _, err = template.ParseAndRenderString(source, emptyBindings) + require.Error(t, err) +} diff --git a/render/tags.go b/render/tags.go index 871e04a2..832b626c 100644 --- a/render/tags.go +++ b/render/tags.go @@ -18,3 +18,8 @@ func (c *Config) FindTagDefinition(name string) (TagCompiler, bool) { td, ok := c.tags[name] return td, ok } + +// RemoveTag removes a tag definition. +func (c *Config) RemoveTag(name string) { + delete(c.tags, name) +} From 5c93d92927127ecce33aa8d52c43d5285fcc1d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaime=20Amate=20Ram=C3=ADrez?= Date: Tue, 18 Nov 2025 16:10:40 +0100 Subject: [PATCH 2/9] fix: remove value assertion --- engine_examples_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/engine_examples_test.go b/engine_examples_test.go index a7f7cd03..e9ee94b6 100644 --- a/engine_examples_test.go +++ b/engine_examples_test.go @@ -314,9 +314,8 @@ func TestRemoveTag(t *testing.T) { source := `{% echo hello world %}` - out, err := template.ParseAndRenderString(source, emptyBindings) + _, err := template.ParseAndRenderString(source, emptyBindings) require.NoError(t, err) - require.Equal(t, "hello world", out) template.RemoveTag("echo") From aedae6bdfa0211f083527ada3d092ca888b99f6b Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Tue, 18 Nov 2025 16:24:36 +0100 Subject: [PATCH 3/9] fix: rename engine variable in test --- engine_examples_test.go | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/engine_examples_test.go b/engine_examples_test.go index e9ee94b6..fc1f0c89 100644 --- a/engine_examples_test.go +++ b/engine_examples_test.go @@ -307,18 +307,23 @@ func TestIssue63_UnicodeVariableNames(t *testing.T) { } func TestRemoveTag(t *testing.T) { - template := NewEngine() - template.RegisterTag("echo", func(c render.Context) (string, error) { + engine := NewEngine() + engine.RegisterTag("echo", func(c render.Context) (string, error) { return c.TagArgs(), nil }) + // Register a tag that always returns an error + engine.RegisterTag("include", func(c render.Context) (string, error) { + return "", fmt.Errorf("Tag include is not allowed") + }) + source := `{% echo hello world %}` - _, err := template.ParseAndRenderString(source, emptyBindings) + _, err := engine.ParseAndRenderString(source, emptyBindings) require.NoError(t, err) - template.RemoveTag("echo") + engine.RemoveTag("echo") - _, err = template.ParseAndRenderString(source, emptyBindings) + _, err = engine.ParseAndRenderString(source, emptyBindings) require.Error(t, err) } From a79eab41fb123d1303d7fb1bd055cd4935fe3223 Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Tue, 18 Nov 2025 16:30:30 +0100 Subject: [PATCH 4/9] fix: remove not needed tag registration in test --- engine_examples_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/engine_examples_test.go b/engine_examples_test.go index fc1f0c89..9a2e4273 100644 --- a/engine_examples_test.go +++ b/engine_examples_test.go @@ -311,12 +311,6 @@ func TestRemoveTag(t *testing.T) { engine.RegisterTag("echo", func(c render.Context) (string, error) { return c.TagArgs(), nil }) - - // Register a tag that always returns an error - engine.RegisterTag("include", func(c render.Context) (string, error) { - return "", fmt.Errorf("Tag include is not allowed") - }) - source := `{% echo hello world %}` _, err := engine.ParseAndRenderString(source, emptyBindings) From 0922fc8da71fb58d32558b3e4e75431b228cf422 Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Tue, 18 Nov 2025 16:32:55 +0100 Subject: [PATCH 5/9] chore: add description for RemoveTag method --- engine.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/engine.go b/engine.go index 274f0421..71044cdd 100644 --- a/engine.go +++ b/engine.go @@ -174,6 +174,10 @@ func (e *Engine) SetAutoEscapeReplacer(replacer render.Replacer) { e.cfg.SetAutoEscapeReplacer(replacer) } +// RemoveTag removes the named tag definition from the engine's configuration. +// After calling RemoveTag the tag will no longer be recognized by subsequent +// parsing or rendering operations. The call is idempotent — removing a tag +// that is not registered is a no-op. func (e *Engine) RemoveTag(name string) { e.cfg.RemoveTag(name) } From b5111dc25af7aea3b0f72735dd855802c9dca257 Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Fri, 5 Dec 2025 20:37:51 +0100 Subject: [PATCH 6/9] fix: rename removeTag to unregisterTag --- engine.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine.go b/engine.go index 71044cdd..bd3be431 100644 --- a/engine.go +++ b/engine.go @@ -178,6 +178,6 @@ func (e *Engine) SetAutoEscapeReplacer(replacer render.Replacer) { // After calling RemoveTag the tag will no longer be recognized by subsequent // parsing or rendering operations. The call is idempotent — removing a tag // that is not registered is a no-op. -func (e *Engine) RemoveTag(name string) { +func (e *Engine) UnregisterTag(name string) { e.cfg.RemoveTag(name) } From 139ca945b9f84e024e1e6f26d2cbaa11dbe30d08 Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Fri, 5 Dec 2025 20:40:48 +0100 Subject: [PATCH 7/9] chore: move test to engine_test file --- engine_examples_test.go | 16 ---------------- engine_test.go | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/engine_examples_test.go b/engine_examples_test.go index 9a2e4273..d977abfa 100644 --- a/engine_examples_test.go +++ b/engine_examples_test.go @@ -305,19 +305,3 @@ func TestIssue63_UnicodeVariableNames(t *testing.T) { require.Equal(t, "content", string(result)) }) } - -func TestRemoveTag(t *testing.T) { - engine := NewEngine() - engine.RegisterTag("echo", func(c render.Context) (string, error) { - return c.TagArgs(), nil - }) - source := `{% echo hello world %}` - - _, err := engine.ParseAndRenderString(source, emptyBindings) - require.NoError(t, err) - - engine.RemoveTag("echo") - - _, err = engine.ParseAndRenderString(source, emptyBindings) - require.Error(t, err) -} diff --git a/engine_test.go b/engine_test.go index fcb028b8..82dc5d20 100644 --- a/engine_test.go +++ b/engine_test.go @@ -9,6 +9,7 @@ import ( "strings" "testing" + "github.com/osteele/liquid/render" "github.com/stretchr/testify/require" ) @@ -183,3 +184,19 @@ func Test_template_store(t *testing.T) { out, _ := engine.ParseAndRenderString(string(template), params) require.Equal(t, "Message Text: filename from: template.liquid.", out) } + +func TestEngine_UnregisterTag(t *testing.T) { + engine := NewEngine() + engine.RegisterTag("echo", func(c render.Context) (string, error) { + return c.TagArgs(), nil + }) + source := `{% echo hello world %}` + + _, err := engine.ParseAndRenderString(source, emptyBindings) + require.NoError(t, err) + + engine.UnregisterTag("echo") + + _, err = engine.ParseAndRenderString(source, emptyBindings) + require.Error(t, err) +} From e48475094a47d2388a3c0ecd758369ffc9b0b136 Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Fri, 5 Dec 2025 20:43:59 +0100 Subject: [PATCH 8/9] chore: update comments for method name --- engine.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/engine.go b/engine.go index bd3be431..33c34cf6 100644 --- a/engine.go +++ b/engine.go @@ -174,9 +174,9 @@ func (e *Engine) SetAutoEscapeReplacer(replacer render.Replacer) { e.cfg.SetAutoEscapeReplacer(replacer) } -// RemoveTag removes the named tag definition from the engine's configuration. -// After calling RemoveTag the tag will no longer be recognized by subsequent -// parsing or rendering operations. The call is idempotent — removing a tag +// UnregisterTag removes the named tag definition from the engine's configuration. +// After calling UnregisterTag the tag will no longer be recognized by subsequent +// parsing or rendering operations. The call is idempotent — unregistering a tag // that is not registered is a no-op. func (e *Engine) UnregisterTag(name string) { e.cfg.RemoveTag(name) From 1292ca6dad2f71d48ba9214e64180abc60d14f0c Mon Sep 17 00:00:00 2001 From: jaime-amate Date: Fri, 5 Dec 2025 20:47:03 +0100 Subject: [PATCH 9/9] fix: rename tags method to unregisterTag --- engine.go | 2 +- render/tags.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/engine.go b/engine.go index 33c34cf6..e77591d2 100644 --- a/engine.go +++ b/engine.go @@ -179,5 +179,5 @@ func (e *Engine) SetAutoEscapeReplacer(replacer render.Replacer) { // parsing or rendering operations. The call is idempotent — unregistering a tag // that is not registered is a no-op. func (e *Engine) UnregisterTag(name string) { - e.cfg.RemoveTag(name) + e.cfg.UnregisterTag(name) } diff --git a/render/tags.go b/render/tags.go index 832b626c..fdba4e13 100644 --- a/render/tags.go +++ b/render/tags.go @@ -19,7 +19,7 @@ func (c *Config) FindTagDefinition(name string) (TagCompiler, bool) { return td, ok } -// RemoveTag removes a tag definition. -func (c *Config) RemoveTag(name string) { +// UnregisterTag removes a tag definition. +func (c *Config) UnregisterTag(name string) { delete(c.tags, name) }