Manual:Desenvolvendo extensões
Se você planeja ter sua extensão implementada nos sites da Wikimedia, leia Escrevendo uma extensão para implantação (em inglês). |
A cada extensão consta de três partes:
Uma mera extensão consiste de três arquivos, um para cada parte:
- MyExtension/extension.json
- Armazena as instruções de configuração. O nome do arquivo deve ser “extension.json” (Nas versões anteriores ao MediaWiki 1.25, as instruções de configuração ficavam num arquivo
MyExtension/MyExtension.php
, nomeado de acordo com a extensão. Várias extensões ainda são compatíveis com aquelas versões neste arquivo PHP). - MyExtension/includes/ (or MyExtension/src/)
- Armazena o código para a execução da extensão.
- MyExtension/resources/ (or MyExtension/modules/)
- Stores the client-side resources such as JavaScript, CSS and LESS for the extension.
- MyExtension/i18n/*.json
- Armazena as informações de localização da extensão.
Ao desenvolver uma extensão, substitua MyExtension (como encontrado acima) pelo nome da sua extensão. Use nomes em UpperCamelCase no diretório e no(s) arquivo(s) PHP; essa é a convenção geral para nomes de arquivos[1] (A BoilerPlate extension é um bom ponto de partida para a sua extensão.)
$wgMainCacheType = CACHE_NONE
e $wgCacheDirectory = false
, ou você poderá não obter mensagens do sistema ou outras mudanças.
Configuração
Seu objetivo ao escrever a parte da instalação é tornar a instalação da extensão o mais fácil possível, para que os usuários só precisem adicionar essa linha ao LocalSettings.php:
wfLoadExtension( 'MyExtension' );
Se você deseja fazer com que sua extensão seja configurável pelo usuário, defina e documente alguns parâmetros de configuração. A configuração deve estar desta maneira:
wfLoadExtension( 'MyExtension' );
$wgMyExtensionConfigThis = 1;
$wgMyExtensionConfigThat = false;
Para alcançar essa simplicidade, seu arquivo de configuração deve efetuar várias tarefas (descritas detalhadamente nas seguintes seções):
- registrar qualquer manipulador de mídia, função ao analisador sintático, página especial, marcação personalizada de XML e/ou viariável que sua extensão usar;
- definir e/ou validar quaisquer variáveis de configuração definidos por você para a sua extensão;
- preparar as classes usadas pela sua extensão para carregamento automático;
- determinar quais partes da sua configuração devem ser feitas imediatamente e quais precisam estar em modo de espera até o núcleo do MediaWiki ter sido inicializado e configurado;
- definir hooks adicionais necessários pela sua extensão;
- criar ou verificar tabelas de banco de dados requeridas pela sua extensão; e
- configurar a localização para a sua extensão.
.md
. For example, see the README.md
file for Parsoid on Phabricator Diffusion.
Registrando recursos com o MediaWiki
O MediaWiki lista todas as extensões instaladas na página Special:Version
.
Por exemplo, é possível ver todas as extensões instaladas nesta wiki na página Special:Version.
Versão MediaWiki: | ≥ 1.25 |
To do this, add the extension details to extension.json . The entry will look something like this:
{
"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
}
Muitos deles são opcionais, mas preenchê-los por completo é uma boa prática.
manifest_version
refere-se à versão do esquema usado pelo arquivo extension.json .
A partir de agora (janeiro de 2018) as versões disponíveis são 1 e 2. Ver aqui para a documentação sobre este recurso.
Unless you need to support an older version of MediaWiki, pick the latest version.
Além do registro acima, você também deve fazer um “hook” do seu recurso com o MediaWiki. O texto acima apenas configura a página Special:Version. A maneira com a qual você fará isso depende do tipo da sua extensão. Para mais detalhes, veja a documentação para cada tipo de extensão:
Tornando a extensão configurável pelos usuários
Caso queira que os usuários possam configurar sua extensão, será necessário fornecer uma ou mais variáveis de configuração. É uma boa ideia dar um nome único para cada variável. Também devem ser seguidas as convenções para nomes do MediaWiki (ex.: variáveis globais devem começar com $wg).
Por exemplo, se sua extensão se chamar “Extensãozinha que não faz nada de mais”, tente nomear todas as suas variáveis de configuração para começarem com $Eqnfndm ou $EQNFNDM. As suas escolhas não importam desde que nenhuma extensão do núcleo do MediaWiki comece as variáveis dessa maneira e que você tenha feito um bom trabalho em verificar se nenhuma das extensões publicadas começam as variáveis dessa maneira. Os usuários não ficarão tão felizes em ter de escolher entre a sua e outras extensões pelo fato de você ter usado os mesmos nomes que as outras.
Uma outra boa ideia é incluir uma documentação completa de quaisquer variáveis de configuração nas suas notas de instalação.
Aqui há um exemplo da extensão BoilerPlate que pode ser usado como ponto de partida:
{
"name": "BoilerPlate",
"version": "0.0.0",
"author": [
"Your Name"
],
"url": "https://www.mediawiki.org/wiki/Extension:BoilerPlate",
"descriptionmsg": "boilerplate-desc",
"license-name": "GPL-2.0-or-later",
"type": "other",
"AutoloadClasses": {
"BoilerPlateHooks": "includes/BoilerPlateHooks.php",
"SpecialHelloWorld": "includes/SpecialHelloWorld.php"
},
"config": {
"BoilerPlateEnableFoo": {
"value": true,
"description": "Enables the foo functionality"
}
},
"callback": "BoilerPlateHooks::onExtensionLoad",
"ExtensionMessagesFiles": {
"BoilerPlateAlias": "BoilerPlate.i18n.alias.php"
},
"Hooks": {
"NameOfHook": "BoilerPlateHooks::onNameOfHook"
},
"MessagesDirs": {
"BoilerPlate": [
"i18n"
]
},
"ResourceModules": {
"ext.boilerPlate.foo": {
"scripts": [
"resources/ext.boilerPlate.js",
"resources/ext.boilerPlate.foo.js"
],
"styles": [
"resources/ext.boilerPlate.foo.css"
]
}
},
"ResourceFileModulePaths": {
"localBasePath": "",
"remoteExtPath": "BoilerPlate"
},
"SpecialPages": {
"HelloWorld": "SpecialHelloWorld"
},
"manifest_version": 2
}
Note that after calling wfLoadExtension( 'BoilerPlate' );
the global variable $wgBoilerPlateEnableFoo
does not exist.
If you set the variable, e.g. in LocalSettings.php
then the default value given in extension.json will not be used.
For more details on how to use global variable inside custom extensions, please refer to Manual:Configuration for developers .
Preparando classes para carregamento automático
Caso escolha ter de usar classes para implementar sua extensão, o MediaWiki fornece um mecanismo simplificado para auxiliar o PHP em encontrar o arquivo-fonte onde sua classe está localizada.
Na maioria dos casos, isso deverá eliminar a necessidade de escrever seu próprio método __autoload($classname)
.
Para usar o mecanismo de carregamento automático do MediaWiki, adicione algo ao campo AutoloadClasses . A chave para cada adição é o nome da classe; o valor é o arquivo armazenador da definição da classe. Para uma extensão de uma só classe, a classe tem geralmente o mesmo nome que a extensão. Dessa maneira, sua seção de carregamento automático deve parecer assim (nesse exemplo, a extensão se chama MyExtension):
{
"AutoloadClasses": {
"MyExtension": "includes/MyExtension.php"
}
}
O nome do arquivo é relativo ao diretório onde se encontra o arquivo extension.json.
For more complex extensions, namespaces should be considered. See Manual:Extension.json/Schema#AutoloadNamespaces for details.
Definindo hooks adicionais
Veja Manual:Ganchos (em inglês).
Adicionando tabelas de bancos de dados
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.
Se sua extensão precisar adicionar suas próprias tabelas de bancos de dados, use o hook LoadExtensionSchemaUpdates . Veja a página do manual para mais informações de uso.
Configurando a localização
Veja:
Adicionando registros
No MediaWiki, todas as ações dos usuários numa wiki são rastreadas para transparência e colaboração. Veja Manual:Registrando para Special:Log (em inglês) para adicionar registros.
Handling dependencies
Assume that an extension requires the presence of another extension, for example because functionalities or database tables are to be used and error messages are to be avoided in case of non-existence.
For example the extension CountingMarker requires the presence of the extension HitCounters for certain functions.
One way to specify this would be by using the requires
key in extension.json.
Another option is using ExtensionRegistry (available since MW 1.25):
if ( ExtensionRegistry::getInstance()->isLoaded( 'HitCounters', '>=1.1' ) {
/* do some extra stuff, if extension HitCounters is present in version 1.1 and above */
}
Currently (as of February 2024, MediaWiki 1.41.0) the name of the extension-to-be-checked needs to exactly match the name in their extension.json.[2][3]
Example: if you want to check the load status of extension "OpenIDConnect", you have to use it with a space
if ( ExtensionRegistry::getInstance()->isLoaded( 'OpenID Connect' ) {
...
}
Localização
|
$wgMainCacheType = CACHE_NONE
e $wgCacheDirectory = false
, caso contrário suas mudanças nas mensagens do sistema poderão não ser exibidas.Se você deseja que sua extensão seja usada em wikis com leitores multilíngues, será necessário adicionar compatibilidade a localizações na sua extensão.
Armazenando mensagens em <chave-idioma>.json
Armazene as definições de mensagens em arquivos de localização JSON, um para cada chave de idioma em que sua extensão será traduzida. As mensagens serão salvas com uma chave de mensagem e a mensagem, usando o formato padrão JSON. Todo id de mensagem deve estar em letras minúsculas e sem espaços. Each key should begin with the lowercased extension name. Um exemplo pode ser encontrado na extensão MobileFrontend. Aqui está um exemplo de um arquivo JSON mínimo (neste caso, en.json):
en.json
{
"myextension-desc": "Adds the MyExtension great functionality.",
"myextension-action-message": "This is a test message"
}
Armazenando a documentação das mensagens em qqq.json
A documentação das chaves das mensagens pode ser armazenada num arquivo JSON com o código qqq. Uma documentação do exemplo acima pode ser:
qqq.json:
{
"myextension-desc": "The description of MyExtension used in Extension credits.",
"myextension-action-message": "Adds 'message' after 'action' triggered by user."
}
Carregando o arquivo de localização
Na sua rotina de configuração, defina a localização dos seus arquivos de mensagem; ex. no diretório i18n/:
{
"MessagesDirs": {
"MyExtension": [
"i18n"
]
}
}
Usando wfMessage no PHP
No seu código de configuração e implementação, substitua todo uso da mensagem com uma chamada para wfMessage( $msgID, $param1, $param2, ... )
.
Em classes que implementam a IContextSource (assim como algumas subclasses das páginas especiais, por exemplo), pode-se usar $this->msg( $msgID, $param1, $param2, ... )
.
Exemplo:
wfMessage( 'myextension-addition', '1', '2', '3' )->parse()
Usando mw.message no JavaScript
Também é possível usar funções de i18n no JavaScript. Veja Manual:Messages API (em inglês) para mais detalhes.
Tipos de extensões
Extensões podem ser categorizadas baseando-se nas técnicas de programação usadas para torná-las efetivas. A maioria das extensões mais complexas usam mais de uma das seguintes técnicas:
- Subclassing: O MediaWiki aceita que certos tipos de extensões sejam implementados como subclasses de uma classe-base fornecida pelo MediaWiki:
- Páginas especiais – Subclasses da classe SpecialPage são usadas para construir páginas cujo conteúdo é dinamicamente gerado usando uma combinação do estado atual do sistema, parâmetros inseridos pelos usuários e consultas às bases de dados. Relatórios e formulários de inserção de dados podem ser gerados. São usadas tanto para propósitos administrativos quanto de relato.
- Temas – Temas modificam a aparência e a experiência do MediaWiki alterando o código de exibição de páginas ao “subclassear” a classe SkinTemplate do MediaWiki.
- Ganchos – Uma técnica de injeção de código em PHP personalizado nos pontos principais do processador do MediaWiki. Eles são amplamente usados pelo analisador sintático, motor de localização e sistema de gerenciamento de extensões e páginas do MediaWiki.
- Associações de funções em tags – Tags do estilo são associadas com uma função do PHP que retorna códigos em HTML. Não é necessário limitar-se na formatação do texto dentro das tags nem exibi-lo. Várias extensões do tipo tag usam o texto como parâmetros que guiam a geração de que incorpora objetos do Google, formulários de entrada de dados, feeds RSS e excertos de artigos wiki selecionados.
- Palavras mágicas – Uma técnica para mapear uma variedade de strings de wikitexto num só id, associado a uma função. Variáveis e funções do analisador sintático usam dessa técnica. Todo o texto mapeado ao id será substituído com o valor retornado da função. O mapeamento entre as strings de texto e o id é armazenado no array $magicWords. A interpretação do id envolve um processo um tanto quanto complicado – veja Manual:Palavras mágicas para mais informações.
- Variable – O termo variável é um equívoco. Elas são porções de wikitexto que se parecem com predefinições, porém não têm parâmetros e têm valores de código complexo atribuídos a elas. Marcações wiki padrão, como
{{PAGENAME}}
e{{SITENAME}}
são exemplos de variáveis. Elas receberam esse nome da fonte do seu valor: uma variável PHP ou algo que pudesse ser atribuído a uma variável; ex.: uma string, um número, uma expressão ou um valor de retorno de uma função. - Funções do analisador sintático –
{{functionname: argument 1 | argument 2 | argument 3...}}
. Semelhantes às extensões do tipo tag, funções do analisador sintático processam argumentos e retornam valores. Ao contrário de extensões do tipo tag, o resultado dessas funções é em wikitexto.
- Variable – O termo variável é um equívoco. Elas são porções de wikitexto que se parecem com predefinições, porém não têm parâmetros e têm valores de código complexo atribuídos a elas. Marcações wiki padrão, como
- Módulos da API – É possível adicionar módulos personalizados à API action, que pode ser invocada por JavaScript, robôs ou clientes terceiros.
- Page content models – If you need to store data in formats other than wikitext, JSON, etc. then you can create a new ContentHandler .
Compatibilidade a outras versões do núcleo
Existem duas convenções comuns para suportar versões antigas do núcleo do MediaWiki:
- Mestre: o ramo mestre da extensão é compatível com tantas versões antigas do núcleo quanto possível. Isso resulta em um fardo de manutenção (os hacks de compatibilidade com versões anteriores precisam ser mantidos por muito tempo e as mudanças na extensão precisam ser testadas com várias versões do MediaWiki), mas os sites que usam versões antigas do MediaWiki se beneficiam das funcionalidades recentemente adicionadas ao extensão.
- Ramos de liberação: os ramos de liberação da extensão são compatíveis com ramos de núcleo correspondentes, p. Ex. Os sites que usam o 1.42 precisam usar o ramo REL1_42 da extensão. (Para extensões hospedadas em gerrit, esses ramos são criados automaticamente quando as novas versões do MediaWiki são lançadas.) Isso resulta em um código mais limpo e um desenvolvimento mais rápido, mas os usuários em versões do núcleo antigo não se beneficiam das correções de erros e dos novos recursos, a menos que sejam recados manualmente.
Os mantenedores de extensão devem declarar com a compatibility policy
parâmetro da predefinição {{Extensão }} que convenção eles seguem.
Licença (em inglês)
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:
- GNU General Public License, version 2 or later (GPL-2.0-or-later)
- MIT License (MIT)
- BSD License (BSD-3-Clause)
- Apache License 2.0 (Apache-2.0)
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.
Publicando
Para categorizar e padronizar a documentação da sua extensão, veja Predefinição:Extensão . Para adicionar sua extensão nesta wiki:
O(A) desenvolvedor(a) que compartilhar seu código no MediaWiki ou no repositório de códigos do MediaWiki deve estar preparado para:
- Comentários / Críticas / Revisões
- Revisões e comentários de outros desenvolvedores acerca de, por exemplo, uso do framework, segurança, eficiência e usabilidade.
- Ajuste do desenvolvedor
-
- Outros desenvolvedores modificando suas submissões para melhorar ou simplificar seu código seguindo novas classes e métodos do framework, convenções de código e traduções.
- Melhorias no acesso de administradores de wikis
- Se você decidir expor seu código numa wiki, outro desenvolvedor poderá movê-lo para o repositório de códigos do MediaWiki para facilitar sua manutenção. Você pode então criar um Acesso de desenvolvedor para continuar a mantê-lo.
- Versões futuras por outros desenvolvedores
- Novas ramificações do seu código sendo criadas por outros desenvolvedores no momento em que novas versões do MediaWiki forem lançadas. Você deve backport para essas ramificações se quiser oferecer suporte a versões anteriores.
- Mesclar seu código em outras extensões com propósitos idênticos ou semelhantes — incorporando os melhores recursos de cada extensão.
- Crédito
- Crédito pelo seu trabalho será preservado em versões futuras — incluindo em extensões mescladas.
- Da mesma forma, você deve creditar os desenvolvedores de extensões cujo código foi tomado por você — especialmente ao realizar uma mescla.
Desenvolvedores que não estiverem de acordo com as ações acimas não devem implantar seus códigos diretamente no MediaWiki ou em seu repositório de códigos. Ainda te motivamos a criar uma página de sumário para a sua extensão na wiki para informar as pessoas sobre sua extensão, e onde baixá-la.
Implementando e registrando
Se você pretende que sua extensão seja implantada em sites Wikimedia (incluindo, possivelmente, a Wikipédia), um escrutínio adicional é garantido em termos de desempenho e segurança. Consulte Escrevendo uma extensão para implantação (em inglês).
Se sua extensão adicionar espaços nominais, você pode tentar registrar seus espaços nominais padrões; da mesma forma, se ela adicionar tabelas ou campos aos bancos de dados, experimente registrá-los em database field prefixes .
Please be aware that review and deployment of new extensions on Wikimedia sites can be extremely slow, and in some cases has taken more than two years.[4]
Documentação de ajuda
Forneça uma documentação de ajuda de domínio público para os recursos providos por sua extensão.
The convention is for extensions to have their user-focused help pages under a pseudo-namespace of Help:Extension:<ExtensionName>
, with whatever subpages are required (the top level page will be automatically linked from the extension infobox if it exists).
Ajuda:CirrusSearch é um bom exemplo disso.
Forneça aos usuários uma ligação à documentação pela função addHelpLink() .
Releasing updates
There are a number of common approaches to releasing updates to extensions.
These are generally defined according to the compatibility policy of the extension (master
, rel
, or ltsrel
):
master
- Releases may be tagged with version numbers on the master branch, and documentation provided on the extension's homepage describing which extension versions are compatible with which core versions. Release branches will still be created automatically, and you may wish to delete these if they are not intended to be used.rel
andltsrel
- Release by backporting changes to theREL1_*
branches (either all changes, or only critical ones). Version numbers are generally not needed unless the extension is a dependency of another (the version number can then be provided in the other extension's configuration to ensure that incompatible combinations aren't installed). Many extensions will stay at the same version number for years.
Fornecendo suporte ou colaboração
Desenvolvedores de extensões devem abrir uma conta no Phabricator da Wikimedia e solicitar um novo projeto para a extensão. Isso fornece um canal público, onde os usuários podem relatar problemas e enviar extensões. Colabore também com os usuários e outros desenvolvedores para fazer triagem de bugs e para planejar mais recursos à sua extensão.
Ver também
- Manual:Registro de extensão - provides further developer documentation on how to register extensions and skins.
- API:Extensions – explica como sua extensão pode fornecer uma API para os clientes.
- Manual:Extending wiki markup
- Manual:Convenções de codificação
- Melhores práticas para extensões
- Resource Loader
Learn by example
- Extension:Examples – implementa alguns recursos de exemplo com extensas documentações.
- Extension:BoilerPlate – uma extensão clichê funcionando, útil como um ponto de partida para a sua extensão. (repositório Git)
- Leia a extensão Example, baseie seu código na extensão BoilerPlate.
- cookiecutter-mediawiki-extension – uma predefinição para a ferramenta em Python Cookiecutter, que gera uma extensão BoilerPlate (com variáveis, etc.).
- Permite que você avance rapidamente com a sua extensão.
- Pode também gerar a extensão BoilerPlate.
- List of simple extensions - copie alguns códigos delas.