Tutorial anterior: Developing Discourse Plugins - Part 4 - Setup git
Às vezes, as configurações do site não são suficientes como uma interface de administração para que seu plugin funcione da maneira que você deseja. Por exemplo, se você instalar o plugin discourse-akismet, pode ter notado que ele adiciona um item de navegação na seção de plugins de administração do seu Discourse:
Neste tutorial, mostraremos como adicionar uma interface de administração para seu plugin. Vou chamar meu plugin de purple-tentacle, em homenagem a um dos meus jogos favoritos. Sério, eu realmente amo esse jogo!
Configurando a Rota de Administração
Vamos começar adicionando um plugin.rb, como fizemos nas partes anteriores do tutorial.
plugin.rb
# name: purple-tentacle
# about: A sample plugin showing how to add a plugin route
# version: 0.1
# authors: Robin Ward
# url: https://github.com/discourse/purple-tentacle
add_admin_route 'purple_tentacle.title', 'purple-tentacle'
Discourse::Application.routes.append do
get '/admin/plugins/purple-tentacle' => 'admin/plugins#index', constraints: StaffConstraint.new
end
A linha add_admin_route informa ao Discourse que este plugin precisará de um link na página /admin/plugins. Seu título será purple_tentacle.title, vindo do nosso arquivo de traduções i18n, e ele linkará para a rota purple-tentacle.
As linhas abaixo configuram o mapeamento do lado do servidor das rotas para nosso plugin. O Discourse assume que quase toda rota no front-end possui uma rota correspondente no servidor que fornece dados. Para este plugin de exemplo, na verdade não precisamos de nenhum dado do back-end, mas precisamos informar ao Discourse para servir algo caso o usuário acesse /admin/plugins/purple-tentacle diretamente. Esta linha apenas diz: “ei, se o usuário acessar essa URL diretamente no lado do servidor, sirva o conteúdo padrão dos plugins!”
(Se isso estiver confuso, não se preocupe muito; voltaremos a isso em um futuro tutorial quando lidarmos com ações do lado do servidor.)
Em seguida, adicionaremos um modelo que será exibido quando o usuário acessar o caminho /admin/plugins/purple-tentacle. Será apenas um botão que mostra um GIF animado de um tentáculo roxo quando o usuário clicar no botão:
assets/javascripts/discourse/templates/admin/plugins-purple-tentacle.gjs
import DButton from "discourse/components/d-button";
<template>
{{#if @controller.tentacleVisible}}
<div class="tentacle">
<img src="https://eviltrout.com/images/tentacle.gif" />
</div>
{{/if}}
<div class="buttons">
<DButton
@label="purple_tentacle.show"
@action={{@controller.showTentacle}}
@icon="eye"
@id="show-tentacle"
/>
</div>
</template>
Se você aprendeu o básico do Handlebars, o modelo deve ser bastante simples de entender. O <DButton /> é um componente no Discourse que usamos para exibir um botão com um rótulo e um ícone.
Para conectar nosso novo modelo, precisamos criar um mapa de rotas:
assets/javascripts/discourse/purple-tentacle-route-map.js
export default {
resource: "admin.adminPlugins",
path: "/plugins",
map() {
this.route("purple-tentacle");
},
};
Um mapa de rotas é algo que adicionamos ao Discourse para permitir que plugins adicionem rotas à aplicação Ember. A sintaxe dentro de map() é muito semelhante ao roteador do Ember. Neste caso, nosso mapa de rotas é muito simples; ele apenas declara uma rota chamada purple-tentacle sob /admin/plugins.
Finalmente, vamos adicionar nossas strings de tradução:
config/locales/client.en.yml
en:
js:
purple_tentacle:
title: "Purple Tentacle"
show: "Show Purple Tentacle"
Se você reiniciar seu servidor de desenvolvimento, deverá ser capaz de visitar /admin/plugins e verá nosso link! Se clicar nele, verá o botão para mostrar nosso tentáculo roxo:
Infelizmente, ao clicar no botão, nada acontece ![]()
Se você olhar no console de desenvolvedor, verá um erro que fornece uma pista do motivo:
Uncaught Error: Nothing handled the action 'showTentacle'
Ah, sim, o motivo é que, em nosso modelo, estamos dependendo de algumas coisas:
- Que, quando o usuário clicar no botão,
showTentacleserá chamado no controlador. showTentacledeve definir a propriedadetentacleVisiblecomotruepara que a imagem apareça.
Se você ainda não leu os Guias do Ember sobre Controladores, agora é um bom momento para fazê-lo, pois implementaremos um controlador para nosso modelo purple-tentacle que lidará com essa lógica.
Crie o seguinte arquivo:
assets/javascripts/discourse/controllers/admin-plugins-purple-tentacle.js
import Controller from "@ember/controller";
import { action } from "@ember/object";
import { tracked } from "@glimmer/tracking";
export default class AdminPluginsPurpleTentacleController extends Controller {
@tracked tentacleVisible = false;
@action
showTentacle() {
this.tentacleVisible = true;
}
}
E agora, ao atualizar nossa página, clicar no botão mostra nosso personagem animado!

Deixo como um exercício extra para o leitor adicionar um botão que esconde o tentáculo quando clicado ![]()
Se você estiver tendo dificuldade para fazer sua versão deste plugin funcionar, eu a enviei para o GitHub.
Mais na série
Parte 1: Fundamentos dos Plugins
Parte 2: Saídas de Plugin
Parte 3: Configurações do Site
Parte 4: Configuração do git
Parte 5: Este tópico
Parte 6: Testes de Aceitação
Parte 7: Publique seu plugin
Este documento está sob controle de versão — sugira alterações no GitHub.





