Vývoj doplnkov¶
Doplnky sú spôsobom prispôsobenia pracovného postupu lokalizácie vo 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_execution_form(data: Mapping[str, object] | None = None) Form | None¶
Provide optional component/change context and preview controls.
- 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.
- Parametre:
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_pushorcommit_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.
- schedule_manual_run(user_id: int | None = None, *, component_id: int | None = None, change_id: int | None = None) None¶
Queue the default manual handler; providers can consume run context.
- 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.
Háčiky doplnkov prijímajú objekty ORM z modulov weblate.*.models, vrátane Addon, Component, Translation, Category, Project, Unit, Change a User. Formuláre konfigurácie doplnkov by mali dediť od weblate.addons.forms.BaseAddonForm.
Tu je príklad doplnku:
# 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
Dokumentovanie operácií automatizácie¶
Referencia automatizácie a kuchárska kniha používa schému v weblate/automation/schema.py ako svoj referenčný zdroj. Vstavané akcie sú registrované v weblate/automation/operations.py, ktorý poskytuje ich nastavenia a schémy výsledkov, validáciu a vykonávanie. Tento register uchovávajte interne; nenačítava operácie tretích strán. Pri pridávaní akcie nastavte jej názov a verziu pridanú do vydania Weblate, v ktorom sa prvýkrát objaví. Túto verziu zachovajte aj pri neskoršom rozširovaní akcie. Riadiace bloky si v schéme pracovného postupu uchovávajú svoje metadáta title a x-version-added.
V položke registra deklarujte podporované rozsahy reťazcov akcie. Predvolená hodnota je component; zvoľte trigger a result, keď vykonávanie akceptuje výber jednotky za behu. Rozsah odovzdajte normalizácii, aby predvolené hodnoty a požiadavky dotazu zodpovedali výberu. Nahláste ovplyvnené ID jednotiek prostredníctvom zberača za behu, nie cez verejnú schému výsledkov alebo protokol aktivít.
Spustite make -C docs update-automation-schema update-automation-docs na aktualizáciu schémy a referencie na stiahnutie. Pridajte vysvetlenia a príklady po zodpovedajúci marker AUTOGENERATED END v docs/admin/automation.rst. Generátor list_automation zachováva tento manuálny obsah. Udržiavajte identifikátory sekcií stabilné, aby popisy zostali priradené k svojim operáciám.
Typovanie konfigurácie doplnku¶
Konfigurácia doplnku je uložená v poli JSON Addon.configuration, takže model uchováva persistované dáta ako surové JSON. Implementácie doplnkov môžu typovať svoju vlastnú konfiguráciu parametrizáciou BaseAddon a BaseAddonForm.
Použite dve triedy TypedDict, keď sa uložené JSON môže líšiť od runtime tvaru: permisivnú, zvyčajne total=False, uloženú konfiguráciu pre staré alebo chýbajúce hodnoty a úplnú runtime konfiguráciu vrátenú normalize_configuration(). Runtime kód doplnku by mal čítať self.configuration alebo self.get_configuration(), aby videl normalizované predvolené hodnoty namiesto surového persistovaného JSON.
Pre jednoduché doplnky, kde sú uložený a runtime tvar identické, definujte jediný TypedDict a použite ho pre oba typové parametre BaseAddon. Udržujte návratový typ serialize_form() formulára v súlade s typom uloženej konfigurácie.
Zverejnenie konfigurácie doplnku¶
Add-on change history can be visible without add-on management permission.
List configuration fields that are safe to publish in the form’s
public_configuration_fields attribute. Fields not explicitly listed are
kept in the snapshot with a null value and identified as redacted. The default
is an empty set so that newly added settings are not published accidentally.
Allowlisting a structured field publishes all its nested values. Only list such
a field when every value it can contain is safe to publish.
Použite BaseAddon.get_public_configuration() vždy, keď je konfigurácia vystavená mimo dôveryhodného kódu na správu doplnkov. Interné operácie, ktoré zámerne klonujú funkčný doplnok, môžu naďalej používať uloženú konfiguráciu.
API doplnkov pripojených ku komponentu¶
Deklarujte api_name a vráťte pomenované vzory URL Django z get_api_urls(). Používajte bežné konvertory Django a pohľady DRF. Vzory sú registrované pre každého poskytovateľa povoleného v WEBLATE_ADDONS, bez ohľadu na to, či je doplnok nainštalovaný na komponente.
Trasy sú namontované pod /api/components/<projekt>/<komponent>/addons/<api_name>/. Pre kategorizované komponenty zakódujte celú cestu kategórie a komponentu v segmente komponentu, ako pre REST API komponentu. Použite api_url inštalácie namiesto manuálneho zostavovania tejto URL. Názvy API musia obsahovať 1 až 64 znakov ASCII písmen, číslic, podčiarkovníkov alebo pomlčiek a musia byť globálne jedinečné medzi povolenými triedami poskytovateľov. Weblate validuje tieto deklarácie pri spustení bez dopytovania databázy a odmieta neplatné alebo konfliktné názvy. Poskytovatelia musia deklarovať needs_component = True, repo_scope = False a multiple = False. Ten istý poskytovateľ môže byť nainštalovaný na mnohých komponentoch, ale na každom komponente iba raz.
Vytvorte podtriedu weblate.addons.api.InstalledAddonAPIView a nastavte jej addon_name na interný názov doplnku poskytovateľa. Základný pohľad autentifikuje požiadavku, kontroluje prístup ku komponentu a rieši inštaláciu ako self.addon. Chýbajúca alebo nekompatibilná inštalácia vracia HTTP 404. Jeho permission má predvolenú hodnotu component.edit a kontroluje sa pred analýzou údajov požiadavky. Predvolený analyzátor JSON obmedzuje požiadavky na 5 MiB, vrátane požiadaviek bez hlavičky Content-Length.
Používajte bežnú validáciu serializátora DRF v metódach pohľadu. Zdokumentujte celú zmluvu pomocou drf_spectacular.utils.extend_schema a pomocného textu polí serializátora: OpenAPI objavuje rovnaké pohľady používané na smerovanie za behu. Obráťte koncové body pomocou api:<api_name>:<pattern_name> a poskytnite project__slug, slug a všetky parametre koncového bodu. Názvy API sú verejné zmluvy a mali by zostať stabilné naprieč zmenami implementácie. Po zmene registrácie poskytovateľa reštartujte Weblate; testy prepisujúce registrácie musia znovu zostaviť svoju konfiguráciu URL a vyčistiť cache URL Django.
Existujúce manažérske API /api/addons/<id>/ zostáva dostupné. Jeho polia iba na čítanie api_name a api_url odrážajú aktuálnu deklaráciu povoleného poskytovateľa. Obe sú nulové, keď je poskytovateľ zakázaný alebo nekompatibilný.
Testovanie zdrojov Kotlin SDK¶
Spustite uv run pytest weblate/kotlin_sdk/tests.py s nakonfigurovaným testovacím prostredím na testovanie extrakcie, prípravy a publikovania zdrojov, vrátane API Kotlin SDK.
Testy binárneho zapisovača, validácia AAPT2 a inštrumentačné testy Androidu sa udržiavajú v arsc-writer. Inštrukcie nájdete v jeho vývojovej príručke.