Skip to content

Add money filters - #963

Merged
sebastienros merged 2 commits into
sebastienros:mainfrom
lahma:money-filters
Jul 29, 2026
Merged

Add money filters#963
sebastienros merged 2 commits into
sebastienros:mainfrom
lahma:money-filters

Conversation

@lahma

@lahma lahma commented Jul 22, 2026

Copy link
Copy Markdown
Collaborator

Fixes #238

Implements the Shopify money filters, registered with the opt-in FilterCollection.WithMoneyFilters() (like WithColorFilters(), they are not added by the TemplateOptions constructor):

Filter Source Result
money {{ 1134.65 | money }} $1,134.65
money_with_currency {{ 1134.65 | money_with_currency }} $1,134.65 USD
money_without_currency {{ 1134.65 | money_without_currency }} 1,134.65
money_without_trailing_zeros {{ 10.00 | money_without_trailing_zeros }} $10

Configuration

A new TemplateOptions.MoneyOptions, mirrored on TemplateContext so a currency can be selected per rendering:

  • Culture based by default. The currency and the separators come from TemplateOptions.CultureInfo. The invariant culture has no region, so USD/$ is used, which matches Shopify's default ${{amount}} format.
  • Currency, an ISO 4217 code, also accepted as a filter argument: {{ 10 | money: 'EUR' }} and {{ 10 | money: currency: 'EUR' }}. Symbols and decimal digits come from an extensible Currencies collection seeded with the common codes; an unregistered code is rendered using the code itself as the symbol.
  • AmountsInCents (default false) divides the input by 100, for templates ported from Shopify where prices are stored as integers.
  • MoneyFormat / MoneyWithCurrencyFormat override the culture based formatting with the Shopify currency formatting placeholders ({{amount}}, {{amount_with_comma_separator}}, …), plus {{currency}} and {{currency_symbol}} so a single format works with a currency resolved at rendering time. Formats are parsed once, when assigned.

Notes

Amounts default to plain decimals rather than cents. The issue comment on #238 is a good illustration of what people expect: {{ item.Price | money_without_currency }} currently falls through unfiltered and renders 31.300 or 31.30 depending on the scale of the decimal that came out of the database. Money formatting pins the decimal count, and there is a test for it.

Two deliberate deviations from raw .NET currency formatting, both overridable with a format string:

  • Amounts are rounded away from zero, as Shopify does, instead of .NET's banker's rounding.
  • Negative amounts render as -$10.00 rather than the accounting ($10.00) that "C" produces for en-US and the invariant culture.

README.md has a new "Money filters" section, and CLAUDE.md is added.

Testing

70 new tests in Fluid.Tests/MoneyFiltersTests.cs. Full suite passes on both the regular and the Compiled=true pass, and the build is clean on all four TFMs including netstandard2.0.

Implements the Shopify money filters, registered with the opt-in
`FilterCollection.WithMoneyFilters()`:

- money
- money_with_currency
- money_without_currency
- money_without_trailing_zeros

Formatting is derived from `TemplateOptions.CultureInfo` by default, and
configured by the new `TemplateOptions.MoneyOptions`, which is mirrored on
`TemplateContext` so a currency can be selected per rendering.

- `Currency` and a per-call filter argument select an ISO 4217 currency,
  resolved against an extensible `Currencies` collection.
- `AmountsInCents` divides the input by 100, matching Shopify where prices
  are stored as integers.
- `MoneyFormat` and `MoneyWithCurrencyFormat` override the culture based
  formatting using the Shopify placeholders, plus `{{currency}}` and
  `{{currency_symbol}}`.

Fixes sebastienros#238
@hishamco

Copy link
Copy Markdown
Collaborator

Just a little note before reviewing why we simplify this by having one money filter, then use arguments to implement the others

@sebastienros

Copy link
Copy Markdown
Owner

AGENTS.md instead?

The two files were both agent guidance for this repository, with the
commands and testing sections overlapping. AGENTS.md is now the single
file, and CLAUDE.md is removed.
@lahma

lahma commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator Author

AGENTS.md instead?

Merged into AGENTS.md

@sebastienros
sebastienros merged commit e839db6 into sebastienros:main Jul 29, 2026
3 checks passed
@lahma
lahma deleted the money-filters branch July 30, 2026 05:52
sebastienros pushed a commit that referenced this pull request Aug 20, 2026
* Add money filters

Implements the Shopify money filters, registered with the opt-in
`FilterCollection.WithMoneyFilters()`:

- money
- money_with_currency
- money_without_currency
- money_without_trailing_zeros

Formatting is derived from `TemplateOptions.CultureInfo` by default, and
configured by the new `TemplateOptions.MoneyOptions`, which is mirrored on
`TemplateContext` so a currency can be selected per rendering.

- `Currency` and a per-call filter argument select an ISO 4217 currency,
  resolved against an extensible `Currencies` collection.
- `AmountsInCents` divides the input by 100, matching Shopify where prices
  are stored as integers.
- `MoneyFormat` and `MoneyWithCurrencyFormat` override the culture based
  formatting using the Shopify placeholders, plus `{{currency}}` and
  `{{currency_symbol}}`.

Fixes #238

* Merge CLAUDE.md into AGENTS.md

The two files were both agent guidance for this repository, with the
commands and testing sections overlapping. AGENTS.md is now the single
file, and CLAUDE.md is removed.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: ee9c8775-0354-41dd-8226-89a69c60241c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Money filters

3 participants