Orden de precedencia de componentes de tema

Noto que los componentes del tema parecen ejecutarse en orden de instalación. Por ejemplo, si instalo A y luego B, los scripts de A se incluyen en las páginas generadas antes que los de B.

¿Es esto algo en lo que puedo confiar? ¿Existe alguna vista que muestre este orden? Al ver los componentes instalados, estos aparecen listados en orden alfabético.

Preferiría una forma de ejecutar acciones explícitamente antes de un componente en particular. En mi caso, quiero ejecutar acciones antes del componente TOC (relacionado con este tema). Según la documentación de Ember, las funciones programadas para una cola determinada se ejecutan en el orden en que fueron programadas. Esto hace que el orden de programación sea esencial en mi caso.

2 Me gusta

No es algo en lo que puedas confiar; en su lugar, las APIs adecuadas deberían controlar esto. Puedes usar inicializadores de Ember para controlarlo hasta cierto punto. @eviltrout podría tener algunas ideas específicas si puedes pegar el código de ejemplo que estás intentando programar.

7 Me gusta

Este es el código que estoy ejecutando:

<script type="text/discourse-plugin" version="0.8">
    const { run } = Ember;
    
    api.decorateCooked($elem => {
        run.scheduleOnce("actions", () => {
          // Debe ejecutarse antes de las acciones programadas por el componente TOC.
        });
    })

El componente TOC utiliza la misma interfaz para programar sus acciones.

Según la documentación de Ember, la interfaz de programación:

Añade el objetivo/método pasado y cualquier argumento opcional a la cola nombrada para que se ejecuten al final del RunLoop

Este término “añadir” sugiere un ordenamiento FIFO de las acciones programadas. Por lo tanto, el orden en que se llama a schedule es crítico aquí.

Noté que en mi intento de reordenar la ejecución de JavaScript reinstalando y desinstalando el componente TOC (esto tiene, aparentemente, el efecto secundario afortunado de ejecutar el JavaScript del TOC al final), las reglas CSS ahora se aplican en este orden :slight_smile:

Siento que el tema del orden para la ubicación del código de los componentes del tema es bastante importante. Si el orden es oficialmente “indefinido”, los componentes no tienen forma de interactuar.

Quizás la interacción entre componentes no sea un objetivo. Pero creo que con una heurística de ordenamiento (por ejemplo, declarar que un archivo de componente aparezca antes o después del archivo de otro componente con el mismo nombre; esto se definiría presumiblemente en about.json), este problema no es tan difícil de resolver.

Por mi parte, empiezo a pensar que bifurcar el componente TOC es la opción correcta, dado lo que estoy intentando hacer.

Cada vez que creas o instalas un tema o un componente, Discourse le asigna un ID. Si visitas la página de ese componente, deberías ver ese ID en la URL (el número al final).

component id in the URL

Cuando ese componente se añade a tu tema, su orden de ejecución parece basarse en su ID, a un nivel muy básico (haciendo un console.log sin ningún aplazamiento). Así, el 233 se ejecutará antes que el 234, y así sucesivamente.

Esto funciona en la mayoría de los casos porque los cambios posteriores suelen añadirse en nuevos componentes, por lo que simplemente funciona.

A largo plazo, el orden podría respetar el de la lista de componentes que has añadido al tema.

pero eso no está en ninguna hoja de ruta por ahora.

Lo que realmente necesitas es el orden de los inicializadores. No creo que puedas hacerlo a menos que muevas tu código a la nueva forma de crear JavaScript para temas. Este método te permite asignar un nombre y un orden de ejecución al inicializador. Por ejemplo, supongamos que tengo este archivo:

/javascripts/discourse/initializers/initialize-for-foo.js

y se ve así:

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "foo",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("foo")
    });
  }
}

y tengo otro inicializador que se ve así:

/javascripts/discourse/initializers/initialize-for-bar.js

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "bar",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("bar")
    });
  }
}

Si quiero asegurarme de que bar se ejecute después de foo, puedo añadir un argumento after: a él, lo que garantizará que se ejecute después del nombre del inicializador que pase allí. Así, para hacer que bar se ejecute después de foo, haría lo siguiente en:

/javascripts/discourse/initializers/initialize-for-bar.js

import { withPluginApi } from "discourse/lib/plugin-api";

export default {
  name: "bar",
+ after: "foo",
  initialize() {
    withPluginApi("0.8.7", api => {
      console.log("bar");
    });
  }
};
6 Me gusta

¡Muchas gracias por las indicaciones detalladas! Dado que tengo problemas relacionados con el componente TOC (a los que también respondiste, ¡gracias de nuevo), he bifurcado TOC y movido el código dependiente a ese componente. Esto está relacionado con los IDs de los encabezados, específicamente la necesidad de controlarlos desde la publicación para manejar duplicados y colisiones con los IDs de los elementos principales.

Creo que, dado lo que estoy haciendo con la documentación, parte de lo cual se sale un poco de lo establecido, esa es la aproximación correcta.

1 me gusta