# How to Localize

The `*i18n.Localizer` returned by the `bot.SettingsProvider` we created on the previous page is now available in the `*plugin.Context`.

## Using the `Localizer`

Localized text is generated using `*i18n.Config`s. Usually, these are placed in a `terms.go` file in your package. If you have many configs, it might also be advisable to group terms into `foo_terms.go`, `bar_terms.go` etc.

In your command's `Invoke` method, you can then use those `*i18n.Configs` to generate messages.

{% code title="plugins/sum/terms.go" %}

```go
package sum

import "github.com/mavolin/adam/pkg/i18n"

var (
    shortDescription = i18n.NewFallbackConfig(
        "plugin.sum.short_description", "Add numbers together")
    
    argsNumbersName = i18n.NewFallbackConfig(
        "plugin.sum.args.numbers.name", "Numbers")
    argsNumbersDescription = i18n.NewFallbackConfig(
        "plugin.sum.arg.numbers.description", 
        "The numbers that shall be added.")
)

var (
    errorNotEnoughNumbers = i18n.NewFallbackConfig(
        "plugin.sum.error.not_enough_numbers", // term
        "I need at least 2 numbers to calculate a sum!") // fallback
    
    result = i18n.NewFallbackConfig(
        "plugin.sum.result", "The sum is {{.sum}}.")
)

// The recommended way to fill placeholders is by using data structs.
// All exported fields will by put into snake_case and given to the Localizer
// as placeholders.
// If you want to use custom names, use the `i18n:"my_custom_name"` struct tag.

type resultPlaceholders struct {
    Sum int
}
```

{% endcode %}

{% code title="plugins/sum/sum.go" %}

```go
package sum

import (
    "github.com/mavolin/adam/pkg/i18n"
    "github.com/mavolin/adam/pkg/impl/arg"
)

type Sum struct {
    command.Meta
}

func New() *Sum {
    return &Sum{
        Meta: command.LocalizedMeta{
            Name: "sum",
            ShortDescription: shortDescription,
            Args: &arg.LocalizedConfig{
                RequiredArgs: []arg.LocalizedRequiredArg{
                    {
                        Name: argsNumbersName,
                        Type: arg.Integer,
                        Description: argsNumbersDescription,
                    },
                },
                Variadic: true,
            },
        },
    }
}

func (s *Say) (_ *state.State, ctx *plugin.Context) (interface{}, error) {
    nums := ctx.Args.Ints(0)
    if len(nums) >= 1 {
        return nil, errors.NewUserErrorl(errorNotEnoughNumbers)
    }
    
    var sum int
    
    for _, num := range nums {
        sum += num
    }
    
    return result.WithPlaceholders(resultPlaceholders{
        Sum: sum,
    }, nil
}
```

{% endcode %}

## Working with `Localizer`s

As you might have already noticed, there are a lot of utilities for working with localized text. Structs typically come in two versions `X` and `LocalizedX` to provide localization support. If they are constructor-based, they might also use constructors like `NewX`, `NewXl`, and `NewXlt` where `NewX` creates an unlocalized version, `NexXl` uses a `*i18n.Config`, and `NewXlt` uses a `i18n.Term`.

The same also applies to other functions. For example `plugin.Context` provides `Reply`, `Replyl` and `Replylt`.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://go-adam.gitbook.io/adam/localization/using-localizers.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
