Metadata-Version: 2.4
Name: dpy-i18n
Version: 0.0.4
Summary: Auto-translating i18n for discord.py — just write keys, strings translate themselves
License-Expression: MIT
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Python: >=3.13
Description-Content-Type: text/markdown
Requires-Dist: discord.py>=2.3
Requires-Dist: PyYAML>=6.0

# dpy-i18n

Auto translating i18n for `discord.py`.
Write translation keys, and they are resolved automatically in messages, embeds, and component labels.

## Installation
Python 3.13 or higher is required
```bash
pip install dpy-i18n
```

## Example Usage

```python
import os
import discord
from dotenv import load_dotenv
from discord_i18n import I18nBot


class Bot(I18nBot):
    def __init__(self):
        load_dotenv()
        super().__init__(
            command_prefix="!",
            intents=discord.Intents.default(),
            lang_dir="lang",
            fallback="en",
        )

    async def setup_hook(self):
        await self.load_extension("cogs.test")
        await super().setup_hook()  # registers translator + syncs tree


if __name__ == "__main__":
    Bot().run(os.getenv("TOKEN"))
```

`I18nBot` automatically:
- loads translations from `lang/`
- patches Discord send/edit paths for auto-translation
- registers the slash-command translator

## Usage in Cogs

```python
import discord
from discord import app_commands
from discord_i18n import I18nCog


class MyCog(I18nCog):
    @app_commands.command(
        name=app_commands.locale_str("test"),
        description=app_commands.locale_str("test_description"),
    )
    async def test(self, interaction: discord.Interaction):
        # 1) Plain key as content (auto-translated)
        await interaction.response.send_message("embed.test.title")

        # 2) Key inside a string
        await interaction.followup.send("🎉 {embed.test.title}")

        # 3) Keys in Embed fields (auto-translated)
        embed = discord.Embed(
            title="embed.test.title",
            description="embed.test.description",
        )
        embed.set_footer(text="embed.test.footer")
        await interaction.followup.send(embed=embed)

        # 4) Keys in UI labels (auto-translated)
        view = discord.ui.View()
        view.add_item(discord.ui.Button(label="embed.test.title"))
        await interaction.followup.send(view=view)

        # 5) Manual translation via self.t()
        text_a = self.t(interaction, "embed.test.title")

        # 6) Manual translation via module-level t()
        text_b = t(interaction, "embed.test.description")
        await interaction.followup.send(f"{text_a} | {text_b}")
```

## Variables

`lang/en.yaml`:

```yaml
welcome:
  message: "Hello, {user}!"
```

Usage:

```python
await interaction.response.send_message("welcome.message", user=interaction.user.mention)
```

## Translation Files

```text
lang/
  en.yaml           # UI / message / embed keys
  de.yaml
  commands/
    en.yaml         # slash command names + descriptions
    de.yaml
```

Example `lang/en.yaml`:

```yaml
embed:
  test:
    title: "Test Embed"
    description: "This is an English test embed."
    footer: "English"
```

Example `lang/commands/en.yaml`:

```yaml
test: "test"
test_description: "Shows a test embed."
```

## Important Note for Slash Commands

For command names/descriptions to localize correctly:
- use `app_commands.locale_str("...")` in the decorator
- keep keys in `lang/commands/<locale>.yaml`
- sync commands after changes (`await bot.tree.sync()`)

## API

| Symbol | Description |
|---|---|
| `I18nBot(**kwargs)` | Bot subclass. Supports `lang_dir=` and `fallback=`. |
| `I18nCog` | Optional cog base class with `self.t(...)`. |
| `t(interaction_or_locale, key, **vars)` | Translate a key manually. |
| `I18n(lang_dir, fallback)` | Core translation loader and resolver. |
| `I18nTranslator` | Translator for slash command metadata. |
| `apply_patches()` | Apply monkey-patches manually (done by `I18nBot`). |
