Empaquetar un plugin de Discourse como una gema

Pavilion ha comenzado a empaquetar algunos plugins de Discourse como gemas de Ruby, comenzando con nuestro cliente de suscripción.

Nuestro cliente de suscripción sigue siendo un plugin separado que ahora carga esta gema, pero su backend ahora está completamente empaquetado como una gema y el plugin separado pronto será obsoleto por completo. Esta es una pequeña introducción sobre cómo hacer lo mismo con sus plugins que se adaptan mejor a ser gemas.

Cómo trabajar con gemas

En primer lugar, necesita comprender cómo trabajar con gemas de Ruby. Si nunca antes ha creado una gema, le recomiendo que cree su propia gema estándar de forma aislada antes de abordar el trabajo con un plugin de Discourse como gema. Recomiendo esta guía:

Cómo los plugins inyectan código en Discourse

La forma en que una gema de plugin de Discourse inyecta código en Discourse es exactamente la misma que un plugin estándar. La única diferencia es el empaquetado. Por lo tanto, para trabajar con un plugin como gema, también deberá comprender cómo un plugin estándar inyecta código en Discourse. Esencialmente, hay dos cosas que comprender aquí:

  1. Un plugin de Discourse es un motor de Rails. Probablemente ya lo sepa, pero deberá comprender realmente qué significa esto. Recomiendo revisar esta guía sobre motores de Rails. Por ejemplo, deberá comprender por qué gran parte del código en el archivo plugin.rb de un plugin de Discourse está envuelto en una devolución de llamada after_initialize.

  2. Cómo funciona el proceso de inicialización de Discourse. En realidad, solo hay un archivo para leer y comprender aquí, a saber, el archivo discourse/discourse/config/application.rb. Ahí es donde se carga la mayor parte del código de Rails, donde se carga todo el código del plugin y donde se inicializan los plugins. Revise ese archivo en profundidad y comprenda dónde y cómo se requieren los archivos del plugin y luego se inicializan.

Cómo funciona un plugin de Discourse como gema

Para unir todo, deberá comprender cómo los dos temas anteriores se sintetizan en una gema de plugin de Discourse. En particular, tenga en cuenta lo siguiente:

  1. En una gema de plugin de Discourse, el archivo engine.rb juega un papel similar al archivo plugin.rb, con algunas diferencias de configuración. Eche un vistazo al archivo discourse_subscription_client gem engine.rb y compárelo con un archivo plugin.rb estándar.

  2. En una gema de plugin de Discourse, necesita simular discourse/discourse en sus pruebas rspec para probar adecuadamente la gema. No necesita simular toda la aplicación de Discourse, solo las partes contra las que está probando. Lo hace creando una aplicación Rails esquelética con las clases y puntos finales específicos de Discourse que necesita y cargándola como un soporte rspec. Vea la aplicación de simulación de Discourse de la gema del cliente de suscripción y dónde se carga en el spec rails_helper.rb.

Cómo cargar una gema local en un plugin de Discourse

Para cargar su versión local de una gema en un plugin de Discourse al trabajar con ese plugin y gema en desarrollo, debe hacer lo siguiente.

Enlace simbólico su carpeta de gema a la carpeta de gema del plugin correspondiente. Por ejemplo, para trabajar con mi versión local de la gema discourse_subscription_client en el plugin discourse-subscription-client, hago lo siguiente:

ln -s /Users/angus/discourse/gems/discourse_subscription_client /Users/angus/discourse/discourse/plugins/discourse-subscription-client/gems/3.2.1/gems

Luego, cambie el nombre de la carpeta de gema enlazada simbólicamente en el plugin para que utilice el mismo patrón de nombre que una carpeta de gema estándar, por ejemplo:

discourse_subscription_client-0.1.0.pre11

Ahora, cuando su plugin cargue su gema de plugin de Discourse, cargará su versión local en lugar de la de rubygems.

Si tiene alguna pregunta o se atasca, publique aquí y le ayudaré.

14 Me gusta

Parece que este enfoque no es posible para cubrir ningún aspecto del tema de Discourse en un plugin. ¿Quizás un mejor título sería “Empaquetar un motor Rails específico de Discourse como una gema”?

1 me gusta

Eso es correcto, necesitas manejar las cosas del framework JS del front-end por separado.

Si bien es técnicamente exacto, no estaría de acuerdo en que ese título fuera mejor, ya que eso disuadiría a algunas de las personas adecuadas de leer el tema: la mayoría de las personas que escriben plugins podrían no identificarlos como “motores Rails específicos de Discourse”.

De hecho, ahora separo mi código de forma más habitual en plugins de back-end y componentes de temas de front-end para poder iterar las cosas del front-end muy rápidamente en los despliegues a los entornos de staging y producción.

3 Me gusta

Estoy de acuerdo con eso, aunque este documento solo sea útil para algunos desarrolladores avanzados, debería cubrir a todas las personas.

Y gracias por compartir esto.

1 me gusta

De acuerdo, es un tema avanzado.