# Customizing Weblate

Extend and customize using Django and Python.
Contribute your changes upstream so that everybody can benefit. This reduces
your maintenance costs; code in Weblate is taken care of when changing internal
interfaces or refactoring the code.

#### HINT
You can also customize Weblate look in [Prilagođavanje prikaza](https://docs.weblate.org/hr/latest/admin/admin.md#manage-appearance).

#### WARNING
Neither internal interfaces nor templates are considered a stable API.
Please review your customizations for every upgrade, the interfaces or their
semantics might change without notice.

#### SEE ALSO
[Doprinošenje Weblateu](https://docs.weblate.org/hr/latest/contributing/index.md#contributing)

<a id="custom-module"></a>

## Creating a Python module

If you are not familiar with Python, you might want to look into [Python For
Beginners](https://www.python.org/about/gettingstarted/), explaining the
basics and pointing to further tutorials.

To write a file with custom Python code (called a module), a place to store it
is needed, either in the system path (usually something like
`/usr/lib/python3.12/site-packages/`) or in the Weblate directory, which
is also added to the interpreter search path.

#### HINT
When [using Docker](https://docs.weblate.org/hr/latest/admin/install/docker.md#docker-deploy), you can place Python modules in
`/app/data/python/` (see [Docker container volumes](https://docs.weblate.org/hr/latest/admin/install/docker.md#docker-volume)), so they can be loaded
by Weblate, for example from a [settings override file](https://docs.weblate.org/hr/latest/admin/install/docker.md#docker-settings-override).

Better yet, turn your customization into a proper Python package:

1. Create a folder for your package (we will use weblate_customization).
2. Within it, create a `pyproject.toml` file to describe the package:
   ```toml
   [build-system]
   requires = ["uv_build>=0.8.18,<0.9.0"]
   build-backend = "uv_build"

   [project]
   name = "weblate-customization"
   version = "0.1.0"
   description = "Add your description here"
   requires-python = ">=3.13"
   dependencies = []
   ```
3. Create a folder for the Python module: `src/weblate_customization`
4. Within it, create a `__init__.py` file to ensure Python can import the module.
5. This package can now be installed using **uv pip install -e**. More info to be found in [Editable packages documentation](https://docs.astral.sh/uv/pip/packages/#editable-packages).
6. Once installed, the module can be used in the Weblate configuration
   (for example `weblate_customization.checks.FooCheck`).

Your package structure should look like this:

```text
weblate_customization
├── pyproject.toml
└── src
    └── weblate_customization
        ├── __init__.py
        ├── addons.py
        └── checks.py
```

You can find an example of customizing Weblate at
<[https://github.com/WeblateOrg/customize-example](https://github.com/WeblateOrg/customize-example)>, it covers all the topics
described below.

## Changing the logo

1. Create a simple Django app containing the static files you want to overwrite
   (see [Creating a Python module](#custom-module)).

   Branding appears in the following files:

   `icons/weblate.svg`
   : Logo shown in the navigation bar.

   `logo-*.png`
   : Web icons depending on screen resolution and web-browser.

   `favicon.ico`
   : Web icon used by legacy browsers.

   `weblate-*.png`
   : Avatars for bots or anonymous users. Some web-browsers use these as shortcut icons.

   `email-logo.png`
   : Used in notifications e-mails.
2. Add it to [`INSTALLED_APPS`](https://docs.djangoproject.com/en/stable/ref/settings/#std-setting-INSTALLED_APPS):
   ```python
   INSTALLED_APPS = (
       # Add your customization as first
       "weblate_customization",
       # Weblate apps are here…
   )
   ```
3. Run `weblate collectstatic --noinput`, to collect static files served to
   clients.

#### SEE ALSO
* [How to manage static files (e.g. images, JavaScript, CSS)](https://docs.djangoproject.com/en/stable/howto/static-files/)
* [Serving static files](https://docs.weblate.org/hr/latest/admin/install.md#static-files)

<a id="custom-addon-modules"></a>

<a id="custom-check-modules"></a>

<a id="custom-modules"></a>

## Custom quality checks, add-ons, translation services and auto-fixes

To install your code for [Custom automatic fixups](https://docs.weblate.org/hr/latest/admin/checks.md#custom-autofix), [Writing own checks](https://docs.weblate.org/hr/latest/admin/checks.md#own-checks),
[Prilagođeno strojno prevođenje](https://docs.weblate.org/hr/latest/admin/machine.md#custom-machinery) or [Pisanje dodatka](https://docs.weblate.org/hr/latest/admin/addons.md#own-addon) in Weblate:

1. Place the files into your Python module containing the Weblate customization
   (see [Creating a Python module](#custom-module) or [Prilagođavanje koda](https://docs.weblate.org/hr/latest/admin/install/docker.md#docker-python-override)).
2. Add its fully-qualified path to the Python class in the dedicated settings:
   * [`WEBLATE_ADDONS`](https://docs.weblate.org/hr/latest/admin/config.md#std-setting-WEBLATE_ADDONS)
   * [`CHECK_LIST`](https://docs.weblate.org/hr/latest/admin/config.md#std-setting-CHECK_LIST)
   * [`WEBLATE_MACHINERY`](https://docs.weblate.org/hr/latest/admin/config.md#std-setting-WEBLATE_MACHINERY)
   * [`AUTOFIX_LIST`](https://docs.weblate.org/hr/latest/admin/config.md#std-setting-AUTOFIX_LIST)

```python
# Checks
CHECK_LIST += ("weblate_customization.checks.FooCheck",)

# Autofixes
AUTOFIX_LIST += ("weblate_customization.autofix.FooFixer",)

# Add-ons
WEBLATE_ADDONS += ("weblate_customization.addons.ExamplePreAddon",)

# Translation services
WEBLATE_MACHINERY += ("weblate_customization.machinery.SampleTranslation",)
```

#### SEE ALSO
* [Custom automatic fixups](https://docs.weblate.org/hr/latest/admin/checks.md#custom-autofix)
* [Writing own checks](https://docs.weblate.org/hr/latest/admin/checks.md#own-checks)
* [Pisanje dodatka](https://docs.weblate.org/hr/latest/admin/addons.md#own-addon)
* [Izvršavanje skripta dodatka](https://docs.weblate.org/hr/latest/admin/addons.md#addon-script)
