# `GettextSigils.Modifier`
[🔗](https://github.com/zebbra/gettext_sigils/blob/v0.5.1/lib/gettext_sigils/modifier.ex#L1)

Behaviour for `~t` sigil modifiers.

Implement this behaviour to extend the `~t` sigil with per-call
transformations: validate opts (`init/1`), compute the Gettext
domain/context (`domain_context/3`), rewrite the message at compile time
(`preprocess/2`), turn it into a plural form (`pluralize/2`), or
transform the final translated string at runtime (`postprocess/2`).

All callbacks are optional. `use GettextSigils.Modifier` installs no-op
defaults; override only what you need:

    defmodule MyApp.UpcaseModifier do
      use GettextSigils.Modifier

      @impl true
      def postprocess(string, _opts), do: {:ok, String.upcase(string)}
    end

Wire it up via the `:modifiers` option:

    use GettextSigils,
      backend: MyApp.Gettext,
      sigils: [
        modifiers: [
          u: MyApp.UpcaseModifier,
          # with opts:
          s: {MyApp.ShoutModifier, intensity: 3}
        ]
      ]

Every callback returns `{:ok, value}` or `{:error, reason}`, where
`reason` is either a string or any exception struct (e.g. a
`NimbleOptions.ValidationError`). Exception structs are normalized to
strings via `Exception.message/1`. `init/1` errors raise a
`NimbleOptions.ValidationError` at `use GettextSigils` time; all other
errors raise `ArgumentError` at the respective compile or runtime stage.

See the [Modifiers guide](modifiers.html) for full callback semantics,
chaining rules, timing, and examples.

# `bindings`

```elixir
@type bindings() :: keyword()
```

# `context`

```elixir
@type context() :: binary() | nil
```

# `domain`

```elixir
@type domain() :: binary() | :default | nil
```

# `domain_context`

```elixir
@type domain_context() :: {domain(), context()}
```

# `input`

```elixir
@type input() :: {msgid(), bindings()}
```

# `msgid`

```elixir
@type msgid() :: binary()
```

# `opts`

```elixir
@type opts() :: keyword()
```

# `pluralized`

```elixir
@type pluralized() :: input() | {msgid(), msgid(), Macro.t(), bindings()}
```

# `reason`

```elixir
@type reason() :: String.t() | Exception.t()
```

# `result`

```elixir
@type result(value) :: {:ok, value} | {:error, reason()}
```

# `domain_context`

```elixir
@callback domain_context(input(), opts(), domain_context()) :: result(domain_context())
```

# `init`

```elixir
@callback init(opts()) :: result(opts())
```

# `pluralize`

```elixir
@callback pluralize(input(), opts()) :: result(pluralized())
```

# `postprocess`

```elixir
@callback postprocess(String.t(), opts()) :: result(term())
```

# `preprocess`

```elixir
@callback preprocess(input(), opts()) :: result(input())
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
