ການພັດທະນາອັດອອນ

ສ່ວນເສີມ ແມ່ນວິທີການປັບແຕ່ງຂັ້ນຕອນການແປພາສາໃນ Weblate.

class weblate.addons.base.BaseAddon(storage)

Base class for Weblate add-ons.

classmethod can_install(*, component=None, category=None, project=None) → bool

Check whether add-on is compatible with given component.

change_event(change, activity_log_id: int | None = None)

Event handler for change event.

check_change_action(change) → bool

Early filtering of Change actions before triggering change_event callback.

component_update(component, activity_log_id: int | None = None)

Event handler for component update.

configure(configuration) → None

Save configuration.

daily(component=None, category=None, project=None, activity_log_id: int | None = None)

Scope-aware daily entry point.

Override this for project-level logic, or override daily_component() for per-component logic.

daily_component(component, activity_log_id: int | None = None)

Per-component daily processing. Override this for component-level logic.

classmethod get_add_form(user, *, component=None, category=None, project=None, **kwargs)

Return configuration form for adding new add-on.

classmethod get_api_urls()

Return named Django URL patterns for this provider's API.

get_change_details(compared_configuration)

Return a public configuration snapshot and changed field names.

get_public_configuration()

Return configuration with non-public values redacted.

classmethod get_public_configuration_fields() → frozenset[str]

Return configuration fields which are safe for public use.

get_settings_form(user, **kwargs)

Return configuration form for this add-on.

manual(component=None, category=None, project=None, activity_log_id: int | None = None)

Scope-aware manual entry point.

By default this mirrors the daily handler and lets add-ons opt in explicitly by subscribing to the manual event.

manual_component(component, activity_log_id: int | None = None)

Per-component manual processing.

post_add(translation, activity_log_id: int | None = None)

Event handler after new translation is added.

post_commit(component, store_hash: bool, activity_log_id: int | None = None)

Event handler after changes are committed to the repository.

post_install(component, store_hash: bool, activity_log_id: int | None = None)

Event handler after add-on is installed.

post_push(component, activity_log_id: int | None = None)

Event handler after repository is pushed upstream.

post_remove(translation, activity_log_id: int | None = None)

Event handler after a translation is removed.

post_update(component, previous_head: str, skip_push: bool, changed_files: list[str], parse_after_update: bool = False, activity_log_id: int | None = None)

Event handler after repository is updated from upstream.

ພາຣາມິເຕີ:
  • previous_head (str) -- HEAD of the repository prior to update, can be blank on initial clone.

  • skip_push (bool) -- Whether the add-on operation should skip pushing changes upstream. Usually you can pass this to underlying methods as commit_and_push or commit_pending.

  • changed_files (list[str]) -- Files changed by the repository update.

pre_commit(translation, author: str, store_hash: bool, activity_log_id: int | None = None)

Event handler before changes are committed to the repository.

pre_push(component, activity_log_id: int | None = None)

Event handler before repository is pushed upstream.

pre_update(component, activity_log_id: int | None = None)

Event handler before repository is updated from upstream.

preview(workflow: object, component_id: int | None, change_id: int | None = None, actor=None) → dict[str, object]

Preview an operation without changing application state, if supported.

resolve_components(*, component=None, category=None, project=None)

Resolve scope to components iterator.

save_state() → None

Save add-on state information.

unit_pre_create(unit, activity_log_id: int | None = None)

Event handler before new unit is created.

update_component_state(component, updater: Callable[[dict[str, object]], None]) → None

Atomically merge component-scoped add-on state into the shared JSON field.

user()

Weblate user used to track changes by this add-on.

Add-on hooks ຮັບ ORM objects ຈາກໂມດູນ weblate.*.models, ລວມທັງ Addon, Component, Translation, Category, Project, Unit, Change, ແລະ User. ແບບຟອມການຕັ້ງຄ່າອັດອອນຄວນສືບທອດຈາກ weblate.addons.forms.BaseAddonForm.

ນີ້ແມ່ນຕົວຢ່າງອັດອອນ:

# Copyright © Michal Čihař <michal@weblate.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import annotations

from typing import TYPE_CHECKING, ClassVar

from django.utils.translation import gettext_lazy

from weblate.addons.base import BaseAddon
from weblate.addons.events import AddonEvent

if TYPE_CHECKING:
    from weblate.addons.base import CompatDict
    from weblate.trans.models import Translation


class ExampleAddon(BaseAddon):
    # Filter for compatible components, every key is
    # matched against property of component
    compat: ClassVar[CompatDict] = {
        "file_format": {"po", "po-mono"},
    }
    # List of events add-on should receive
    events: ClassVar[set[AddonEvent]] = {
        AddonEvent.EVENT_PRE_COMMIT,
    }
    # Add-on unique identifier
    name = "weblate.example.example"
    # Verbose name shown in the user interface
    verbose = gettext_lazy("Example add-on")
    # Detailed add-on description
    description = gettext_lazy("This add-on does nothing it is just an example.")

    # Callback to implement custom behavior
    def pre_commit(
        self,
        translation: Translation | None,
        author: str,
        store_hash: bool,
        activity_log_id: int | None = None,
    ) -> None:
        return

Documenting automation operations

The Automation reference and cookbook uses the schema in weblate/automation/schema.py as its reference source. Built-in actions are registered in weblate/automation/operations.py, which supplies their settings and result schemas, validation, and execution. Keep this registry internal; it does not load third-party operations. When adding an action, set its title and version added to the Weblate release in which it first appears. Preserve that version when extending the action later. Control blocks keep their title and x-version-added metadata in the workflow schema.

Declare the action's supported string scopes in its registry entry. The default is component; opt in to trigger and result when execution accepts the runtime unit selection. Pass the scope to normalization so query defaults and requirements match the selection. Report affected unit IDs through the runtime collector, not the public result schema or activity log.

Run make -C docs update-automation-schema update-automation-docs to update the downloadable schema and reference. Add explanations and examples after the corresponding AUTOGENERATED END marker in docs/admin/automation.rst. The list_automation generator preserves this manual content. Keep section identifiers stable so descriptions remain attached to their operations.

ການພິມຕັ້ງຄ່າອັດອອນ

ການຕັ້ງຄ່າອັດອອນຖືກເກັບໄວ້ໃນຟິວ JSON Addon.configuration, ດັ່ງນັ້ນໂມເດວຈຶ່ງເກັບຂໍ້ມູນໄວ້ເປັນ JSON ດິບ. ການຈັດຕັ້ງປະຕິບັດອັດອອນສາມາດພິມການຕັ້ງຄ່າຂອງຕົນເອງໂດຍການກຳນົດພາຣາມິເຕີ BaseAddon ແລະ BaseAddonForm.

ໃຊ້ສອງຄລາສ TypedDict ເມື່ອ JSON ທີ່ເກັບໄວ້ອາດແຕກຕ່າງຈາກຮູບແບບເວລາແລ່ນ (runtime): ຟັງຊັນທີ່ມີຄວາມຍືດຫຍຸ່ນ, ໂດຍປົກກະຕິແມ່ນ total=False, ການຕັ້ງຄ່າທີ່ເກັບໄວ້ສຳລັບຄ່າເກົ່າ ຫຼື ຄ່າທີ່ຂາດຫາຍໄປ, ແລະ ການຕັ້ງຄ່າ runtime ເຕັມທີ່ສົ່ງຄືນໂດຍ normalize_configuration(). ໂຄ້ດອັດອອນໃນເວລາແລ່ນຄວນອ່ານ self.configuration ຫຼື self.get_configuration() ເພື່ອໃຫ້ເຫັນຄ່າເລີ່ມຕົ້ນທີ່ຖືກປັບໃຫ້ເປັນມາດຕະຖານແທນທີ່ຈະເປັນ JSON ດິບ.

ສຳລັບອັດອອນແບບງ່າຍໆທີ່ຮູບແບບການເກັບໄວ້ ແລະ runtime ເໝືອນກັນ, ໃຫ້ກຳນົດ TypedDict ດຽວ ແລະ ໃຊ້ສຳລັບພາຣາມິເຕີປະເພດ BaseAddon ທັງສອງ. ຮັກສາປະເພດການສົ່ງຄືນຂອງ serialize_form() ຂອງແບບຟອມໃຫ້ສອດຄ່ອງກັບປະເພດການຕັ້ງຄ່າທີ່ເກັບໄວ້.

ການເຜີຍແຜ່ການຕັ້ງຄ່າສ່ວນເສີມ

ປະຫວັດການປ່ຽນແປງຂອງສ່ວນເສີມ ສາມາດເບິ່ງເຫັນໄດ້ໂດຍບໍ່ຕ້ອງມີສິດຈັດການສ່ວນເສີມ. ໃຫ້ລະບຸຟິວການຕັ້ງຄ່າທີ່ປອດໄພໃນການເຜີຍແຜ່ໄວ້ໃນຄຸນລັກສະນະ public_configuration_fields ຂອງຟອມ. ຟິວທີ່ບໍ່ໄດ້ລະບຸໄວ້ຢ່າງຊັດເຈນ ຈະຖືກເກັບໄວ້ໃນ snapshot ດ້ວຍຄ່າ null ແລະ ຖືກລະບຸວ່າ ຖືກປົກປິດໄວ້ (redacted). ຄ່າເລີ່ມຕົ້ນແມ່ນຊຸດວ່າງ ເພື່ອບໍ່ໃຫ້ການຕັ້ງຄ່າທີ່ເພີ່ມເຂົ້າມາໃໝ່ ຖືກເຜີຍແຜ່ໂດຍບໍ່ຕັ້ງໃຈ.

ໃຫ້ໃຊ້ BaseAddon.get_public_configuration() ທຸກຄັ້ງທີ່ມີການສະແດງການຕັ້ງຄ່າ ຢູ່ນອກໂຄ້ດຈັດການສ່ວນເສີມທີ່ໜ້າເຊື່ອຖື. ສຳລັບການດຳເນີນການພາຍໃນ ທີ່ຕັ້ງໃຈຈະໂຄລນສ່ວນເສີມ ທີ່ກຳລັງເຮັດວຽກຢູ່ ແມ່ນຍັງສາມາດໃຊ້ການຕັ້ງຄ່າທີ່ເກັບໄວ້ຕໍ່ໄປໄດ້.

Component-mounted add-on APIs

Declare an api_name and return named Django URL patterns from get_api_urls(). Use ordinary Django converters and DRF views. Patterns are registered for every provider enabled in WEBLATE_ADDONS, regardless of whether the add-on is installed on a component.

Routes are mounted under /api/components/<project>/<component>/addons/<api_name>/. For categorized components, encode the full category and component path in the component segment, as for the component REST API. Use the installation's api_url instead of constructing this URL manually. API names must contain 1 to 64 ASCII letters, digits, underscores, or hyphens, and must be globally unique among enabled provider classes. Weblate validates these declarations at startup, without querying the database, and rejects invalid or conflicting names. Providers must declare needs_component = True, repo_scope = False, and multiple = False. The same provider can be installed on many components, but only once on each component.

Subclass weblate.addons.api.InstalledAddonAPIView and set its addon_name to the provider's internal add-on name. The base view authenticates the request, checks component access, and resolves the installation as self.addon. An absent or incompatible installation returns HTTP 404. Its permission defaults to component.edit and is checked before request data is parsed. The default JSON parser bounds requests to 5 MiB, including requests without a Content-Length header.

Use normal DRF serializer validation in the view methods. Document the full contract using drf_spectacular.utils.extend_schema and serializer field help text: OpenAPI discovers the same views used for runtime routing. Reverse endpoints using api:<api_name>:<pattern_name>, providing project__slug, slug, and any endpoint parameters. API names are public contracts and should remain stable across implementation changes. Restart Weblate after changing provider registration; tests overriding registrations must rebuild their URL configuration and clear Django's URL caches.

The existing /api/addons/<id>/ management API remains available. Its read-only api_name and api_url fields reflect the enabled provider's current declaration. Both are null when the provider is disabled or incompatible.

Testing Kotlin SDK resources

Run uv run pytest weblate/kotlin_sdk/tests.py with the test environment configured to test resource extraction, preparation, and publication, including the Kotlin SDK API.

Binary writer tests, AAPT2 validation, and Android instrumentation tests are maintained in arsc-writer. See its development guide for instructions.