Skip to content

Add ScribanRegistrationCallback to register custom Scriban functions - #1516

Merged
StefH merged 1 commit into
wiremock:masterfrom
Quattordici:feature/1515-scriban-registration-callback
Oct 18, 2026
Merged

StefH merged 1 commit into
wiremock:masterfrom
Quattordici:feature/1515-scriban-registration-callback

Conversation

@Quattordici

Copy link
Copy Markdown
Contributor

Fixes #1515

Before

Handlebars templates could be extended with custom helpers through WireMockServerSettings.HandlebarsRegistrationCallback, but Scriban and Scriban-DotLiquid templates had no way to add custom functions.

After

WireMockServerSettings.ScribanRegistrationCallback (Action<object, IFileSystemHandler>?) lets code-configured servers add functions, objects or variables to a Scriban ScriptObject. Those members are available in both TransformerType.Scriban and TransformerType.ScribanDotLiquid templates, for responses, webhooks, proxy URL replacement and WebSockets.

var settings = new WireMockServerSettings
{
    ScribanRegistrationCallback = (scriptObject, fileSystemHandler) =>
        ((ScriptObject)scriptObject).Import("fake_name", new Func<string>(() => "Jane Doe"))
};

// or, strongly typed:
settings.WithScribanRegistration((scriptObject, fileSystemHandler) =>
    scriptObject.Import("fake_name", new Func<string>(() => "Jane Doe")));

The first argument is a Scriban.Runtime.ScriptObject from Scriban.Signed. It is typed as object so that WireMock.Net.Shared does not depend on Scriban. The registered globals sit beneath the template model, so request, response, mapping and data always win on a name clash. Template assignments write to the model scope and never change the registered globals.

How

  • WireMockServerSettings gets the new ScribanRegistrationCallback property ([PublicAPI], [JsonIgnore]), next to HandlebarsRegistrationCallback.
  • TransformerFactory now passes the settings to ScribanContextFactory. The factory invokes the callback with a new ScriptObject each time it creates a transformer context, the same lifetime as the Handlebars callback.
  • ScribanContext builds the TemplateContext itself when custom globals exist (LiquidTemplateContext for DotLiquid), pushing the custom globals first and the model second. When no callback is configured, it still calls Template.Render(model, renamer) exactly as before, so existing users see no change.
  • New WireMockServerSettingsExtensions.WithScribanRegistration(Action<ScriptObject, IFileSystemHandler>) in WireMock.Net.Minimal gives a strongly typed alternative. It keeps any callback that is already configured and runs it first, so several libraries can register functions.
  • The .NET 8 console example shows a greet function used from a Scriban mapping.

Tests

  • ScribanContextFactoryTests: callback invoked once per context with a ScriptObject and the settings' IFileSystemHandler, and a new ScriptObject per context.
  • ScribanContextTests (new): custom functions with and without arguments (Liquid as a filter), model precedence over custom globals, custom globals over Scriban built-ins, template assignments not mutating custom globals, and output parity with and without an empty set of custom globals for both Scriban types.
  • ResponseWithScribanTests: the custom function in the body, a header and a JSON body, for both Scriban types.
  • WireMockServerSettingsTests: an HTTP round trip against a running server, for both Scriban types.
  • WireMockServerSettingsExtensionsTests (new): typed callback, chaining order and argument guards.

Test reliability fixes

These tests failed in environments without outbound internet or IPv6, independent of this feature:

  • WireMockServerProxyTests: seven tests proxied to http://www.google.com. They now proxy to a local WireMockServer started per test, so they no longer depend on the network. Two of them (..._Should_Not_SaveMapping) and WireMockServer_Proxy_Should_proxy_responses previously passed even when the proxy call failed; they now exercise a real proxied response, and the latter asserts the exact proxied body.
  • WireMockServer_Should_respond_to_ipv6_loopback is skipped at runtime with Assert.SkipUnless(Socket.OSSupportsIPv6, ...) when the OS has no IPv6 support, instead of failing with a socket error.

…iremock#1515)

- Add WireMockServerSettings.ScribanRegistrationCallback
  (Action<object, IFileSystemHandler>?) so code-configured servers can add
  functions, objects or variables to Scriban and Scriban-DotLiquid templates.
- Pass the settings to ScribanContextFactory, which invokes the callback with
  a new ScriptObject per transformer context.
- Push the custom globals beneath the template model in ScribanContext so
  request, response, mapping and data take precedence; keep the original
  Template.Render call when no callback is configured.
- Add the strongly typed WithScribanRegistration extension method.
- Add a Scriban example to the .NET 8 console app.
- Make the proxy tests use a local target server instead of www.google.com,
  and skip the IPv6 loopback test when the OS has no IPv6 support.
@StefH StefH added the feature label Oct 18, 2026
@StefH
StefH merged commit 0132ec8 into wiremock:master Oct 18, 2026
6 checks passed
@Quattordici
Quattordici deleted the feature/1515-scriban-registration-callback branch October 18, 2026 18:43
This was referenced Oct 24, 2026
This was referenced Oct 28, 2026
hangy pushed a commit to hangy/NLog.Targets.ApplicationInsights that referenced this pull request Nov 1, 2026
Updated [WireMock.Net](https://github.com/wiremock/WireMock.Net) from
2.18.0 to 2.21.0.

<details>
<summary>Release notes</summary>

_Sourced from [WireMock.Net's
releases](https://github.com/wiremock/WireMock.Net/releases)._

## 2.21.0

## What's Changed
* Update Scriban to 7.5.3 by @​StefH in
wiremock/WireMock.Net#1526


**Full Changelog**:
wiremock/WireMock.Net@2.20.0...2.21.0

## 2.20.0

## What's Changed
* Add ScribanRegistrationCallback to register custom Scriban functions
by @​Quattordici in wiremock/WireMock.Net#1516
* Bump MessagePack from 2.5.302 to 2.5.303 by @​StefH in
wiremock/WireMock.Net#1519
* Downgrade JsonPath.Net from 3.0.2 to 2.2.0 to avoid Open Source
Maintenance Fee issues by @​StefH in
wiremock/WireMock.Net#1522
* Fix workflow permissions by @​StefH in
wiremock/WireMock.Net#1523
* Add near-miss diagnostics and request count/unmatched endpoints to the
admin API by @​Quattordici in
wiremock/WireMock.Net#1521

## New Contributors
* @​Quattordici made their first contribution in
wiremock/WireMock.Net#1516

**Full Changelog**:
wiremock/WireMock.Net@2.19.0...2.20.0

## 2.19.0

## What's Changed
* Add example /test by @​StefH in
wiremock/WireMock.Net#1513
* Use IDateTimeUtils in WireMockWebSocketContext by @​StefH in
wiremock/WireMock.Net#1512
* Fix DateTime in Response by @​StefH in
wiremock/WireMock.Net#1514


**Full Changelog**:
wiremock/WireMock.Net@2.18.0...2.19.0

Commits viewable in [compare
view](wiremock/WireMock.Net@2.18.0...2.21.0).
</details>

[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=WireMock.Net&package-manager=nuget&previous-version=2.18.0&new-version=2.21.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow registering custom Scriban functions (ScribanRegistrationCallback), like HandlebarsRegistrationCallback

2 participants