Desenvolvendo Plugins do Discourse - Parte 3 - Adicionar configurações personalizadas do site

\nTutorial anterior: Developing Discourse Plugins - Part 2 - Connect to a plugin outlet


Configurações do Site

Se você visitar /admin/site_settings em um Discourse no qual você tem capacidades de administrador, verá uma lista de configurações de configuração. Logo de início, fornecemos o que consideramos serem as melhores configurações para uma instalação do Discourse, mas também entendemos que as pessoas querem ajustar suas instalações para deixar seu fórum exatamente como desejam.

É provável que, a menos que seu plugin seja muito simples, você queira adicionar configurações que os usuários do seu plugin possam alterar e usar para configurar a funcionalidade. Felizmente, isso é bem fácil de fazer!

config/settings.yml

A primeira coisa que você precisará fazer é criar config/settings.yml dentro da pasta do seu plugin. Este arquivo descreverá todas as configurações que seu plugin precisará. Aqui está um arquivo de exemplo:

plugins:
  awesomeness_enabled:
    default: true
    client: true
  awesomeness_max_volume:
    default: 10
    client: true

O arquivo precisa estar no formato YAML. O YAML pode ser bem exigente, então, se o Discourse estiver com problemas para carregar suas configurações, sugiro que você tente validar seu YAML com uma ferramenta como o YAMLint.

Vou explicar o arquivo de exemplo em detalhes. O nível superior é plugins e isso diz ao Discourse que queremos que essas configurações apareçam em “Plugins” nas configurações do site.

Depois disso, duas configurações são declaradas, awesomeness_enabled e awesomeness_max_volume. O Discourse infere o tipo das configurações a partir do padrão, então awesomeness_enabled é um booleano e awesomeness_max_volume é um número.

O client: true é importante de entender. O Discourse é composto por duas aplicações principais, a API do lado do servidor escrita em Ruby on Rails, e a aplicação do lado do cliente escrita em Ember.js. Por padrão, não expomos configurações para o cliente Ember.js a menos que você adicione client: true. Fazemos isso porque algumas configurações são privadas, como chaves de API, e não devem ser enviadas aos usuários finais. Além disso, se enviássemos todas as configurações para o cliente, isso poderia ser muito para os usuários finais baixarem!

No nosso caso de exemplo, queremos que ambas as configurações sejam acessíveis no mundo JavaScript, bem como no mundo do lado do servidor.

Um segundo passo importante

Antes de poder usar suas configurações de site recém-adicionadas, você precisa adicionar traduções para elas. Como o Discourse suporta vários idiomas, qualquer texto que você adicionar terá que suportar a tradução para outros idiomas.

Vamos criar as traduções para nossas configurações em inglês:

config/locales/server.en.yml

en:
  site_settings:
    awesomeness_enabled: "Is this plugin awesome?"
    awesomeness_max_volume: "What is the maximum volume possible?"

Os rótulos que adicionamos nesse arquivo serão exibidos na seção de administração. É uma boa ideia ser o mais claro possível sobre o que a configuração realiza.

Declarando a configuração como a ‘configuração habilitada’

Agora que temos nossa configuração de site, devemos dizer ao Discourse que ela é a que ativa e desativa nossos recursos.

Abra seu arquivo plugin.rb e adicione a seguinte linha abaixo dos comentários de metadados:

enabled_site_setting :awesomeness_enabled

Certifique-se de começar todas as suas outras configurações com “awesomeness_” para que o botão de configurações em /admin/plugins funcione corretamente.

Acessando suas novas configurações

Primeiro, você precisará reiniciar seu servidor de desenvolvimento para que as configurações entrem em vigor. Depois de fazer isso, as configurações devem estar disponíveis para seu código do lado do servidor e do lado do cliente.

Nós injetamos automaticamente as configurações do site na maioria dos objetos JavaScript, então, se você estiver declarando um Component, Controller, Route, View ou Model, você deve ser capaz de acessar a configuração do site simplesmente usando this.siteSettings.awesomeness_enabled. Na maioria dos templates handlebars, você também deve ser capaz de dizer {{siteSettings.awesomeness_enabled}} e o valor da configuração será exibido.

Ainda não cobrimos muita coisa sobre Ruby nesta série, mas se você quiser acessar as configurações do site na aplicação Ruby, você pode fazer isso através de: SiteSetting.awesomeness_enabled

Agora vá em frente e adicione configurações personalizadas aos seus plugins!


Mais na série

Parte 1: Noções Básicas de Plugin
Parte 2: Plugin Outlets
Parte 3: Este tópico
Parte 4: Configuração do git
Parte 5: Interfaces de Administrador
Parte 6: Testes de Aceitação
Parte 7: Publique seu plugin


Este documento é controlado por versão - sugira alterações no github.

34 curtidas

For those more familiar with YAML, this was probably obvious, and thanks to YAMLint that you referenced I was able to figure this out pretty quick, but I thought it was worth mentioning that the format for the config/locales/server.en.yml needs to specifically be:

en:
  site_settings:
    awesomeness_enabled: "Is this plugin awesome?"
    max_volume: "What is the maximum volume possible?"

Correct?

Another quick question, it’s great that I can get to the settings by clicking on the Change Settings button, but how do I get the plugin specific Settings button directly to the right of the plugin like the poll plugin?

https://s3.amazonaws.com/f.cl.ly/items/162n220f0M0P3e0j2U3M/Image%202015-07-29%20at%207.29.28%20PM.png

Or is that a little too much for a Beginner’s Guide?

4 curtidas

I updated the guide to fix both of those :smile:

4 curtidas

How do you get the settings button to pre-populate the search field like Discourse Tagging does? I feel like I’m missing something obvious.

Edit: Nevermind, I figured it out. You had to use *_enabled to get it to filter. I originally didn’t have an enabled setting because the URL was simply the factor for determining if it is enabled.

1 curtida

For some reason, {{siteSettings}} in the poster-name-right outlet returns undefined. I tested with other outlets and the return the expected value. I’m not sure why :sadpanda:

Had to work around it by using {{Discourse.SiteSettings}}

1 curtida

This isn’t working because the Post view code path is some of the oldest code we have and it doesn’t do all the automatic stuff newer code can do :frowning:

I’ve come up with a fix that I think will solve your problem:

In the future I’ll be able to remove this hack and it’ll just work.

3 curtidas

Hey @eviltrout how can I add a user setting? I mean a setting for a plugin that every user can change on his profile? Can I set a default too?

I guess is the same as an Custom User Field, so can I create a new User Field from a plugin?

Unfortunately there’s no easy way to do this right now. There is probably a good argument to be made for such an API for plugin authors.

Until then the way to do it is to add the fields via plugin outlets to the user preferences, tap into serializers and saving logic to store the setting the PluginStore.

1 curtida

I ran into this a while back too. We have to expose the field in the site settings too. I’ll see if I can add a PR to make this easier.

1 curtida

For anyone following this tutorial and trying to get SiteSettings.awesomeness_enabled to return anything in a rails console, be aware that the tutorial is wrong. It should be SiteSetting.awesomeness_enabled (Setting without the s at the end!)

1 curtida

Hmmm, this works for me in the hbs files

{{#if siteSettings.plugin_outlet_locations_enabled}}

Different syntax depending on where it’s being called from?

EDIT
Ah, the singular - plural Rails “magic” thing.

Nope, your first guess was correct >.>

JS has Discourse.SiteSettings but Rails has SiteSetting.

3 curtidas

Oops! Thanks for letting me know. I’ve updated the tutorial.

2 curtidas

Well, I believe some infrastructure are not complete yet. But I am refurnishing old login plugins while it’s worthwhile to asking the future change to plugin infra. Shall I move settings from login to plugin prefix?

I would recommend to do that, yes.

1 curtida

Just to clarify, this is only the case if you say client: true, right?

Yes, that is correct. Javascript gets access to the “client side” site settings.

2 curtidas

I do not completely understand this statement. I set it to client: false but it was still visible in admin settings. What exactly happens if you set client to false.

Thank you.

We ship up a big JSON object of all the site settings that have client: true to all users, so those are considered public and viewable.

If they don’t have client: true then they are meant to be available from the server side. The admin section is an exception - we need to return all site settings to admin users so they can be changed! It uses a different API to get them all.

9 curtidas

Work for me! 2018-4-28

Code

config/settings.yml

config/locales/server.en.yml

plugin.rb

Result

http://localhost:3000/admin/site_settings/category/plugins


(oh, I saw the translation missing hint)

Thanks!

3 curtidas