Desarrollando Plugins de Discourse - Parte 3 - Añadir configuraciones personalizadas del sitio

Siguiente tutorial: Developing Discourse Plugins - Part 2 - Connect to a plugin outlet


Ajustes del Sitio

Si visitas /admin/site_settings en un Discourse donde tienes capacidades de administrador, verás una lista de ajustes de configuración. Recién instalado, proporcionamos lo que creemos que son los mejores ajustes para una instalación de Discourse, pero también entendemos que la gente quiere modificar sus instalaciones para que su foro sea exactamente como lo desean.

Es probable que, a menos que tu plugin sea muy simple, desees agregar ajustes que los usuarios de tu plugin puedan cambiar y usar para configurar la funcionalidad. ¡Afortunadamente, esto es bastante fácil de hacer!

config/settings.yml

Lo primero que necesitarás hacer es crear config/settings.yml dentro de la carpeta de tu plugin. Este archivo describirá todos los ajustes que tu plugin necesitará. Aquí hay un archivo de ejemplo:

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

El archivo debe estar en formato YAML. YAML puede ser bastante quisquilloso, así que si Discourse tiene problemas para cargar tus ajustes, te sugiero que intentes validar tu YAML con una herramienta como YAMLint.

Explicaré el archivo de ejemplo en detalle. El nivel superior es plugins y eso le dice a Discourse que queremos que estos ajustes aparezcan bajo “Plugins” en los ajustes del sitio.

Después de eso, se declaran dos ajustes, awesomeness_enabled y awesomeness_max_volume. Discourse deduce el tipo de los ajustes a partir del valor predeterminado, por lo que awesomeness_enabled es un booleano y awesomeness_max_volume es un número.

El client: true es importante de entender. Discourse se compone de dos aplicaciones principales, la API del lado del servidor escrita en Ruby on Rails, y la aplicación del lado del cliente escrita en Ember.js. Por defecto, no exponemos los ajustes a la aplicación cliente de Ember.js a menos que agregues client: true. Hacemos esto porque algunos ajustes son privados, como las claves API, y no deben enviarse a los usuarios finales. Además, si enviáramos todos los ajustes al cliente, podría ser una gran cantidad para que los usuarios finales descarguen.

En nuestro caso de ejemplo, queremos que ambos ajustes sean accesibles en el mundo de JavaScript, así como en el mundo del lado del servidor.

Un segundo paso importante

Antes de poder usar tus ajustes de sitio recién agregados, necesitas agregar traducciones para ellos. Dado que Discourse admite muchos idiomas, cualquier texto que agregues deberá ser compatible con la traducción a otros idiomas.

Creemos las traducciones para nuestros ajustes en inglés:

config/locales/server.en.yml

en:
  site_settings:
    awesomeness_enabled: "¿Es genial este plugin?"
    awesomeness_max_volume: "¿Cuál es el volumen máximo posible?"

Las etiquetas que agregamos en ese archivo se mostrarán en la sección de administración. Es una buena idea ser lo más claro posible sobre lo que logra el ajuste.

Declarar el ajuste como el ‘ajuste habilitado’

Ahora que tenemos nuestro ajuste de sitio, debemos decirle a Discourse que es el que activa y desactiva nuestras características.

Abre tu archivo plugin.rb y agrega la siguiente línea debajo de los comentarios de metadatos:

enabled_site_setting :awesomeness_enabled

Asegúrate de comenzar todos tus otros ajustes con “awesomeness_” para que el botón de ajustes en /admin/plugins funcione correctamente.

Accediendo a tus nuevos Ajustes

Primero, necesitarás reiniciar tu servidor de desarrollo para que los ajustes surtan efecto. Una vez que lo hagas, los ajustes deberían estar disponibles para tu código del lado del servidor y del lado del cliente.

Inyectamos automáticamente los ajustes del sitio en la mayoría de los objetos de JavaScript, por lo que si estás declarando un Component, Controller, Route, View o Model, deberías poder acceder al ajuste del sitio simplemente usando this.siteSettings.awesomeness_enabled. En la mayoría de las plantillas handlebars también deberías poder decir {{siteSettings.awesomeness_enabled}} y se mostrará el valor del ajuste.

Aún no hemos cubierto mucho sobre Ruby en esta serie, pero si deseas acceder a los ajustes del sitio en la aplicación Ruby, puedes hacerlo a través de: SiteSetting.awesomeness_enabled

¡Ahora ve y agrega ajustes personalizados a tus plugins!


Más en la serie

Parte 1: Conceptos básicos de Plugins
Parte 2: Salidas de Plugins
Parte 3: Este tema
Parte 4: Configuración de git
Parte 5: Interfaces de Administración
Parte 6: Pruebas de Aceptación
Parte 7: Publica tu plugin


Este documento está controlado por versiones - sugiere cambios en github.

34 Me gusta

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 Me gusta

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

4 Me gusta

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 me gusta

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 me gusta

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 Me gusta

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 me gusta

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 me gusta

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 me gusta

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 Me gusta

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

2 Me gusta

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 me gusta

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 Me gusta

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 Me gusta

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 Me gusta