Handbuch: Entwickeln von Erweiterungen

This page is a translated version of the page Manual:Developing extensions and the translation is 100% complete.
Other languages:
Bahasa Indonesia • ‎Deutsch • ‎English • ‎Latina • ‎Nederlands • ‎español • ‎français • ‎italiano • ‎polski • ‎português • ‎português do Brasil • ‎Ελληνικά • ‎български • ‎русский • ‎العربية • ‎سنڌي • ‎हिन्दी • ‎中文 • ‎日本語 • ‎한국어
Entwicklung Tag extensions Handbuch:Parser functions Hooks Spezialseiten Handbuch:Oberflächen Handbuch:Magische Wörter API Content models
MediaWiki-Erweiterungen

Jede extension besteht aus drei Teilen:

  1. Einrichtung
  2. Ausführung
  3. Lokalisierung

Eine minimale Erweiterung besteht aus drei Dateien. Für jeden Bereich eine:

MyExtension/extension.json
Speichert die setup-Anleitung. Der Dateiname muss "extension.json" lauten. (Vor MediaWiki 1.25 befanden sich die Setup-Anweisungen in einer MyExtension/MyExtension.php-Datei, die nach der Erweiterung benannt wurde. Viele Erweiterungen haben in dieser PHP-Datei noch Abwärtskompatibilitäten.)
MyExtension/MyExtension.php
Enthält den auszuführenden Code für die Erweiterung. Der Dateiname MyExtension.php ist üblich, aber nicht zwingend vorgeschrieben. Wenn deine Erweiterung komplex ist und viele PHP-Dateien beinhaltet, solltest du die Konvention einhalten, diesen Code in einem Unterverzeichnis MyExtension/includes abzulegen (auch wenn die Erweiterungen Example und BoilerPlate dieser Konvention nicht folgen). Siehe z. B. die SemanticMediaWiki-Erweiterung.
MyExtension/i18n/*.json
Enthält Lokalisierungsinformation für die Erweiterung.

Wenn du eine Erweiterung entwickelst, ersetze MyExtension durch den tatsächlichen Namen deiner Erweiterung. Benutze UpperCamelCase-Namen für das Verzeichnis und die PHP-Datei(en); das entspricht der allgemeinen Dateinamenskonvention.[1] (Ein guter Ausgangspunkt für eine eigene Erweiterung ist die BoilerPlate extension. Man kann auch mit MWStew ein Grundgerüst für eine Erweiterung erstellen. Schau dir auch die cookiecutter-Vorlage für MediaWiki-Erweiterungen auf GitHub an.)

Während der Entwicklungsphase kann es sinnvoll sein, das Caching mit $wgMainCacheType = CACHE_NONE und $wgCacheDirectory = false abzuschalten, sonst werden Systemmeldungen und andere Änderungen möglicherweise nicht angezeigt.

Einrichtung

Ihr Ziel beim Schreiben des Setup-Teils ist es, die Installation der Erweiterung so einfach wie möglich zu gestalten, sodass Benutzer diese Zeile nur zu LocalSettings.php hinzufügen müssen:

wfLoadExtension( 'MyExtension' );

Wenn Sie Ihren Erweiterungsbenutzer konfigurierbar machen möchten, müssen Sie einige Konfigurationsparameter definieren und dokumentieren. Das Setup Ihrer Benutzer sollte ungefähr so aussehen:

wfLoadExtension( 'MyExtension' );
$wgMyExtensionConfigThis = 1;
$wgMyExtensionConfigThat = false;

Um diese Einfachheit zu erreichen, muss Ihre Setup-Datei eine Reihe von Aufgaben ausführen (die in den folgenden Abschnitten ausführlich beschrieben werden):

  • Registrieren Sie einen beliebigen Medienhandler, Parser-Funktion, Spezialseite, benutzerdefiniertes XML-Tag und Variable durch Ihre Erweiterung.
  • Definieren und / oder validieren Sie alle Konfigurationsvariablen, die Sie für Ihre Erweiterung definiert haben.
  • Bereiten Sie die von Ihrer Erweiterung verwendeten Klassen für das automatische Laden vor
  • Legen Sie fest, welche Teile Ihres Setups sofort ausgeführt werden sollen und welche zurückgestellt werden müssen, bis der MediaWiki-Kern initialisiert und konfiguriert wurde
  • Definieren Sie alle zusätzlichen hooks, die von Ihrer Erweiterung benötigt werden
  • Erstellen oder überprüfen Sie alle neuen Datenbanktabellen, die für Ihre Erweiterung erforderlich sind.
  • Richten Sie die Lokalisierung für Ihre Erweiterung ein

Registrieren von Funktionen bei MediaWiki

MediaWiki listet alle Erweiterungen auf, die auf der Seite Special:Version installiert wurden. Beispielsweise können Sie alle in diesem Wiki installierten Erweiterungen unter Special:Version anzeigen. Es ist eine gute Form, um sicherzustellen, dass Ihre Erweiterung auch auf dieser Seite aufgeführt ist.

MediaWiki version: 1.24

Um dies in Versionen zu tun, die älter als MW 1.25 sind, müssen Sie $ ExtensionCredits für 'jedes' Medienhandler, Parser-Funktion, spezielle Seite, benutzerdefiniertes XML-Tag und Variable, die von Ihrer Erweiterung verwendet werden. Ausführliche Informationen zu den Funktionen dieser Felder finden Sie unter 1$.

MediaWiki version: 1.25

Fügen Sie dazu in neueren Versionen die Erweiterungsdetails zu extension.json hinzu. Der Eintrag sieht ungefähr so aus:

{
	"name": "Example",
	"author": "John Doe",
	"url": "https://www.mediawiki.org/wiki/Extension:Example",
	"description": "This extension is an example and performs no discernible function",
	"version": "1.5",
	"license-name": "GPL-2.0-or-later",
	"type": "validextensionclass",
	"manifest_version": 1
}


Viele der Felder sind optional, aber es wird immer noch empfohlen, sie auszufüllen. Die manifest_version</ code> bezieht sich auf die Version des Schemas, für das die $ json-Datei geschrieben wurde. Ab sofort (Januar 2018) sind die Versionen 1 und 2 verfügbar. Die Dokumentation zu dieser Funktion finden Sie in hier.

Zusätzlich zu der oben genannten Registrierung müssen Sie Ihre Funktion auch in MediaWiki "einbinden". Das Obige richtet nur die Seite Special: Version ein. Wie Sie dies tun, hängt von dem Typ Ihrer Erweiterung ab. Einzelheiten finden Sie in der Dokumentation zu den einzelnen Erweiterungstypen:

Entwicklung Tag extensions Handbuch:Parser functions Hooks Spezialseiten Handbuch:Oberflächen Handbuch:Magische Wörter API Content models

Machen Sie Ihre Erweiterung konfigurierbar

Wenn Ihr Benutzer Ihre Erweiterung konfigurieren kann, müssen Sie eine oder mehrere Konfigurationsvariablen angeben. Es ist eine gute Idee, diesen Variablen einen eindeutigen Namen zu geben. Sie sollten auch MediaWiki Namenskonventionen folgen (z. B. sollten globale Variablen mit $wg beginnen).

Wenn Ihre Erweiterung beispielsweise "Sehr dumme Erweiterung, die nichts tut" heißt, möchten Sie möglicherweise alle Konfigurationsvariablen benennen, um mit $wgVsetdn oder $wgVSETDN zu beginnen. Es spielt keine Rolle, was Sie auswählen, solange 'none' 'des MediaWiki-Kerns seine Variablen auf diese Weise beginnt und Sie eine vernünftige Arbeit geleistet haben, um zu überprüfen, ob keine der veröffentlichten Erweiterungen ihre Variablen auf diese Weise beginnt . Benutzer müssen sich nicht zwischen Ihrer Erweiterung und einigen anderen Erweiterungen entscheiden, da Sie überlappende Variablennamen ausgewählt haben.

Es ist auch eine gute Idee, eine ausführliche Dokumentation aller Konfigurationsvariablen in Ihre Installationshinweise aufzunehmen.

  Warnung: Um register_globals -Schwachstellen zu vermeiden, setzen Sie IMMER explizit alle Konfigurationsvariablen Ihrer Erweiterung in der Erweiterungs-Setup-Datei. Konstrukte wie if ( !isset( $wgMyLeetOption ) ) $wgMyLeetOption = somevalue; schützen nicht vor register_globals!

Hier ist ein Beispiel für eine Kesselplatte, mit der Sie loslegen können:

{
	"name": "BoilerPlate",
	"version": "0.0.0",
	"author": [
		"Your Name"
	],
	"url": "https://www.mediawiki.org/wiki/Extension:BoilerPlate",
	"descriptionmsg": "boilerplate-desc",
	"license-name": "MIT",
	"type": "other",
	"AutoloadClasses": {
		"BoilerPlateHooks": "BoilerPlateHooks.php",
		"SpecialHelloWorld": "specials/SpecialHelloWorld.php"
	},
	"config": {
		"BoilerPlateEnableFoo": true
	},
	"callback": "BoilerPlateHooks::onExtensionLoad",
	"ExtensionMessagesFiles": {
		"BoilerPlateAlias": "BoilerPlate.i18n.alias.php"
	},
	"Hooks": {
		"NameOfHook": [
			"BoilerPlateHooks::onNameOfHook"
		]
	},
	"MessagesDirs": {
		"BoilerPlate": [
			"i18n"
		]
	},
	"ResourceModules": {
		"ext.boilerPlate.foo": {
			"scripts": [
				"modules/ext.boilerPlate.js",
				"modules/ext.boilerPlate.foo.js"
			],
			"styles": [
				"modules/ext.boilerPlate.foo.css"
			]
		}
	},
	"ResourceFileModulePaths": {
		"localBasePath": "",
		"remoteExtPath": "BoilerPlate"
	},
	"SpecialPages": {
		"HelloWorld": "SpecialHelloWorld"
	},
	"manifest_version": 1
}

Beachten Sie, dass nach dem Aufruf von wfLoadExtension ('Dumme Erweiterung, die nichts bewirkt') </ code> die globale Variable $ wfBoilerPlateEnableFoo </ code> nicht vorhanden ist. Wenn Sie die Variable einstellen, z. in LocalSettings.php </ code> dann den in der

	"config": {
		"BoilerPlateEnableFoo": true
	},

wird nicht verwendet.

Weitere Informationen zur Verwendung globaler Variablen in benutzerdefinierten Erweiterungen finden Sie unter $ 1.

Klassen für das automatische Laden vorbereiten

Wenn Sie Klassen zum Implementieren Ihrer Erweiterung verwenden, bietet MediaWiki einen vereinfachten Mechanismus, mit dem PHP die Quelldatei finden kann, in der sich Ihre Klasse befindet. In den meisten Fällen sollte dies die Notwendigkeit beseitigen, eine eigene $ autoload-Methode zu schreiben.

Um den Autoloading-Mechanismus von MediaWiki zu verwenden, fügen Sie dem Feld $ AutoloadClasses Einträge hinzu. Der Schlüssel jedes Eintrags ist der Klassenname. Der Wert ist die Datei, in der die Definition der Klasse gespeichert ist. Bei einer einfachen Erweiterung mit einer Klasse erhält die Klasse normalerweise denselben Namen wie die Erweiterung, sodass Ihr Abschnitt zum automatischen Laden möglicherweise folgendermaßen aussieht (die Erweiterung heißt "MyExtension"):

{
	"AutoloadClasses": {
		"MyExtension": "MyExtension.php"
	}
}

Der Dateiname bezieht sich auf das Verzeichnis, in dem sich die Datei extension.json befindet.

Zusätzliche Hooks definieren

Siehe Manual:Hooks .

Datenbank Tabellen hinzufügen

Make sure the extension doesn't modify the core database tables. Instead, extension should create new tables with foreign keys to the relevant MW tables.

  Warnung: Wenn Ihre Erweiterung in einem von WMF gehosteten Produktions-Wiki verwendet wird, befolgen Sie bitte die [$ url Schemaänderungsanleitung].

Wenn Ihre Erweiterung eigene Datenbanktabellen hinzufügen muss, verwenden Sie den Hook $ LoadExtensionSchemaUpdates. Weitere Informationen zur Verwendung finden Sie auf der Handbuchseite.

Lokalisierung einrichten

Siehe:

Logs hinzufügen

In MediaWiki werden alle Aktionen von Benutzern im Wiki auf Transparenz und Zusammenarbeit hin verfolgt. Siehe $ 1 für die Vorgehensweise.

Lokalisierung

Während der Entwicklung möchten Sie möglicherweise beide Caches deaktivieren, indem Sie $ wgMainCacheType = CACHE_NONE </ code> und $ wgCacheDirectory = false </ code> festlegen. Andernfalls werden Ihre Systemnachrichtenänderungen möglicherweise nicht angezeigt.

Wenn Sie möchten, dass Ihre Erweiterung in Wikis mit mehrsprachiger Leserschaft verwendet wird, müssen Sie Ihrer Erweiterung Lokalisierungsunterstützung hinzufügen.

Speichern Sie Nachrichten in <Sprachschlüssel>.json

Speichern Sie Nachrichtendefinitionen in einer Lokalisierungs-JSON-Datei, eine für jeden Sprachschlüssel, in den Ihre Erweiterung übersetzt wird. Die Nachrichten werden mit einem Nachrichtenschlüssel und die Nachricht selbst im Standard-JSON-Format gespeichert. Jede Nachrichten-ID sollte in Kleinbuchstaben geschrieben sein und darf keine Leerzeichen enthalten. Ein Beispiel, das Sie z.B. in Erweiterung MobileFrontend. Hier ist ein Beispiel für eine minimale JSON-Datei (in diesem Fall en.json:

en.json

{
	"myextension-desc": "Adds the MyExtension great functionality.",
	"myextension-action-message": "This is a test message"
}

Speichern Sie die Nachrichtendokumentation in qqq.json

Die Dokumentation für Nachrichtenschlüssel kann in der JSON-Datei für die Pseudosprache mit dem Code qqq gespeichert werden. Eine Dokumentation des obigen Beispiels kann sein:

qqq.json:

{
	"myextension-desc": "The description of MyExtension used in Extension credits.",
	"myextension-action-message": "Adds 'message' after 'action' triggered by user."
}

Nachrichten definieren

  • Weisen Sie jeder Nachricht eine eindeutige Nachrichten-ID in Kleinbuchstaben und ohne Leerzeichen zu. z.B.uploadwizard-desc
  • Definieren Sie für jede dem Benutzer angezeigte Textzeichenfolge eine Nachricht.
  • MediaWiki unterstützt parametrisierte Nachrichten. Diese Funktion sollte verwendet werden, wenn eine Nachricht von zur Laufzeit generierten Informationen abhängt. Parameterplatzhalter werden mit $n angegeben, wobei n den Index des Platzhalters darstellt; z.B.
"mwe-upwiz-api-warning-was-deleted": "There was a file by this name, '$1', but it was deleted and you cannot reupload the file. If your file is different, try renaming it."

Nachrichtendokumentation definieren

Jeder von Ihnen definierten Nachricht muss ein Eintrag für die Nachrichtendokumentation zugeordnet sein Nachrichtendokumentation. in 'qqq.json' z.B.

"uploadwizard-desc": "Description of extension. It refers to [//blog.wikimedia.org/blog/2009/07/02/ford-foundation-awards-300k-grant-for-wikimedia-commons/ this event], i.e. the development was paid with this $300,000 grant."

Laden Sie die Lokalisierungsdatei

Definieren Sie in Ihrer Setup-Routine den Speicherort Ihrer Nachrichtendateien (z. B. im Verzeichnis i18n/):

{
	"MessagesDirs": {
		"MyExtension": [
			"i18n"
		]
	}
}

Verwenden Sie wfMessage in PHP

Ersetzen Sie in Ihrem Setup- und Implementierungscode jede wörtliche Verwendung der Nachricht durch einen Aufruf von wfMessage( $msgID, $param1, $param2, ... ). In Klassen, die IContextSource implementieren (sowie in einigen anderen, z. B. Unterklassen von SpecialPage), können Sie stattdessen $this->msg( $msgID, $param1, $param2, ... ) verwenden. Beispiel:

wfMessage( 'myextension-addition', '1', '2', '3' )->parse()

Verwenden Sie mw.message in JavaScript

Es ist auch möglich, i18n-Funktionen in JavaScript zu verwenden. Schauen Sie sich $ 1 für Details an.

Erweiterungstypen

Entwicklung Tag extensions Handbuch:Parser functions Hooks Spezialseiten Handbuch:Oberflächen Handbuch:Magische Wörter API Content models

Erweiterungen können basierend auf den Programmiertechniken kategorisiert werden, mit denen ihre Wirkung erzielt wird. Die meisten komplexen Erweiterungen verwenden mehr als eine dieser Techniken:

  • Unterklasse: MediaWiki erwartet, dass bestimmte Arten von Erweiterungen als Unterklassen einer von MediaWiki bereitgestellten Basisklasse implementiert werden:
    • Special pages – Unterklassen der SpecialPage -Klasse werden zum Erstellen von Seiten verwendet, deren Inhalt mithilfe einer Kombination aus dem aktuellen Systemstatus, Benutzereingabeparametern und Datenbankabfragen dynamisch generiert wird. Es können sowohl Berichte als auch Dateneingabeformulare generiert werden. Sie werden sowohl für Berichts- als auch für Verwaltungszwecke verwendet.
    • Handbuch:Oberflächen – Skins ändern das Erscheinungsbild von MediaWiki, indem sie den Code ändern, der Seiten ausgibt, indem sie die MediaWiki-Klasse SkinTemplate unterordnen.
  • Hooks – Eine Technik zum Einfügen von benutzerdefiniertem PHP-Code an wichtigen Punkten der MediaWiki-Verarbeitung. Sie werden häufig vom Parser von MediaWiki, seiner Lokalisierungs-Engine, seinem Erweiterungsverwaltungssystem und seinem Seitenpflegesystem verwendet.
  • Tag-Funktions-Assoziationen XML Stil-Tags, die einer PHP-Funktion zugeordnet sind, die HTML-Code ausgibt. Sie müssen sich nicht darauf beschränken, den Text in den Tags zu formatieren. Sie müssen es nicht einmal anzeigen. Viele Tag-Erweiterungen verwenden den Text als Parameter für die Generierung von HTML, in das Google-Objekte, Dateneingabeformulare, RSS-Feeds und Auszüge aus ausgewählten Wiki-Artikeln eingebettet sind.
  • Handbuch:Magische Wörter – Eine Technik zum Zuordnen einer Vielzahl von Wiki-Textzeichenfolgen zu einer einzelnen ID, die einer Funktion zugeordnet ist. Sowohl Variablen als auch Parser-Funktionen verwenden diese Technik. Der gesamte dieser ID zugeordnete Text wird durch den Rückgabewert der Funktion ersetzt. Die Zuordnung zwischen den Textzeichenfolgen und der ID wird im Array $magicWords gespeichert. Die Interpretation der ID ist ein etwas komplexer Prozess - siehe Handbuch:Magische Wörter für weitere Informationen.
    • Variable – Variablen sind eine Art Fehlbezeichnung. Es handelt sich um Wikitext-Bits, die wie Vorlagen aussehen, jedoch keine Parameter haben und fest codierte Werte erhalten haben. Standard-Wiki-Markups wie {{PAGENAME}} oder {{SITENAME}} sind Beispiele für Variablen. Sie erhalten ihren Namen von der Quelle ihres Wertes: eine PHP-Variable oder etwas, das einer Variablen zugewiesen werden könnte, z. eine Zeichenfolge, eine Zahl, ein Ausdruck oder ein Funktionsrückgabewert.
    • Handbuch:Parser functions {{functionname: argument 1 | argument 2 | argument 3...}}. Ähnlich wie bei Tag-Erweiterungen verarbeiten Parser-Funktionen Argumente und geben einen Wert zurück. Im Gegensatz zu Tag-Erweiterungen ist das Ergebnis von Parser-Funktionen wikitext.
  • API Module – Sie können der action API von MediaWiki benutzerdefinierte Module hinzufügen, die von JavaScript, Bots oder Clients von Drittanbietern aufgerufen werden können.
  • Manual:Page content models – If you need to store data in formats other than wikitext, JSON, etc. then you can create a new Manual:ContentHandler .

Unterstützt andere Kernversionen

Es gibt zwei weit verbreitete Konventionen zur Unterstützung älterer Versionen von MediaWiki Core:

  • Master: Der Master-Zweig der Erweiterung ist mit so vielen alten Core-Versionen wie möglich kompatibel. Dies führt zu einem Wartungsaufwand (Abwärtskompatibilitäts-Hacks müssen lange Zeit beibehalten werden, und Änderungen an der Erweiterung müssen mit mehreren MediaWiki-Versionen getestet werden). Websites, auf denen alte MediaWiki-Versionen ausgeführt werden, profitieren jedoch von den kürzlich hinzugefügten Funktionen Erweiterung.
  • Freigabezweige: Freigabezweige der Erweiterung sind mit übereinstimmenden Zweigen des Kerns kompatibel, z. Sites, die MediaWiki Template:MW Stable Branch Number verwenden, müssen den Zweig Template:MW Stable Branch Git der Erweiterung verwenden. (Bei Erweiterungen, die auf gerrit gehostet werden, werden diese Zweige automatisch erstellt, wenn neue Versionen von MediaWiki veröffentlicht werden.) Dies führt zu sauberem Code und einer schnelleren Entwicklung, aber Benutzer alter Kernversionen profitieren nur dann von Bugfixes und neuen Funktionen, wenn dies der Fall ist Backported manuell.

Erweiterungsbetreuer sollten mit dem Parameter Kompatibilitätsrichtlinie </ code> der Vorlage {{ Erweiterung}} angeben, welcher Konvention sie folgen.

Lizenz

MediaWiki is an open-source project and users are encouraged to make any MediaWiki extensions under an Open Source Initiative (OSI) approved license compatible with GPL-2.0-or-later (Wikimedia's standard software license).

We recommend adopting one of the following compatible licenses for your projects in Gerrit:

For extensions that have a compatible license, you can request developer access to the MediaWiki source repositories for extensions. To specify the licence in code and with "license-name" a key should be used to provide it's short name, e.g. "GPL-2.0-or-later" or "MIT" adhering to the list of identifiers at spdx.org.

Veröffentlichung

Informationen zum automatischen Kategorisieren und Standardisieren der Dokumentation Ihrer vorhandenen Erweiterung finden Sie unter 1$. So fügen Sie Ihrem Wiki Ihre neue Erweiterung hinzu:


A developer sharing their code in the MediaWiki code repository should expect:

Feedback / Criticism / Code reviews
Review and comments by other developers on things like framework use, security, efficiency and usability.
Developer tweaking
Other developers modifying your submission to improve or clean-up your code to meet new framework classes and methods, coding conventions and translations.
Improved access for wiki sysadmins
If you do decide to put your code on the wiki, another developer may decide to move it to the MediaWiki code repository for easier maintenance. You may then request commit access to continue maintaining it.
Future versions by other developers
New branches of your code being created automatically as new versions of MediaWiki are released. You should backport to these branches if you want to support older versions.
Incorporation of your code into other extensions with duplicate or similar purposes — incorporating the best features from each extension.
Credit
Credit for your work being preserved in future versions — including any merged extensions.
Similarly, you should credit the developers of any extensions whose code you borrow from — especially when performing a merger.

Any developer who is uncomfortable with any of these actions occurring should not host in the code repository. You are still encouraged to create a summary page for your extension on the wiki to let people know about the extension, and where to download it.

Bereitstellen und Registrieren

Wenn Sie beabsichtigen, Ihre Erweiterung auf Wikimedia-Websites (einschließlich möglicherweise Wikipedia) bereitzustellen, ist eine zusätzliche Prüfung in Bezug auf Leistung und Sicherheit erforderlich. Konsultieren Sie $ 1.

Wenn Ihre Erweiterung Namespaces hinzufügt, möchten Sie möglicherweise deren Standard-Namespaces registrieren. Wenn Datenbanktabellen oder -felder hinzugefügt werden, möchten Sie diese möglicherweise für 2$ registrieren.

Bitte beachten Sie, dass die Überprüfung und Bereitstellung neuer Erweiterungen auf Wikimedia-Websites sehr langsam sein kann und in einigen Fällen mehr als zwei Jahre gedauert hat. <Ref> phabricator: T148848 </ ref>

Hilfedokumentation

Sie sollten Public-Domain-Hilfedokumentation für Funktionen bereitstellen, die von Ihrer Erweiterung bereitgestellt werden. Help:CirrusSearch/de ist ein gutes Beispiel. Sie sollten Benutzern über die Funktion addHelpLink() einen Link zur Dokumentation geben.

Bereitstellung von Unterstützung/Zusammenarbeit

Erweiterungsentwickler sollten ein Konto bei Wikimedia Phabricator eröffnen und ein neues Projekt für die Erweiterung anfordern. Dies bietet einen öffentlichen Ort, an dem Benutzer Probleme und Vorschläge einreichen können, und Sie können mit Benutzern und anderen Entwicklern zusammenarbeiten, um Fehler zu ermitteln und Funktionen Ihrer Erweiterung zu planen.

Siehe auch

Einzelnachweise