I have j/s in my theme (am I infamous yet? ;) which is modifying the DOM by adding elements via api.decorateCooked(…. It inserts a variety HTML head elements.
I also have the DiscoTOC Theme component installed.
However, adding the usual <div data-theme-toc="true"> </div> that DiscoTOC notices and expands, doesn’t generate a table-of-contents including my dynamically inserted elements.
I’m figuring this might be as simple as execution order… if DiscoTOC looks before my j/s adds more elements . . .
What determines the ordering of execution if multiple bits of theme j/s code are calling api.cooked(?
I’m inserting within the post, yes. That’s why I suspect execution order.
Some bit of code determines the execution order… that’s the leverage point for me to get my component before TOC. eg, if it’s alpha by component name (ie, as displayed in the Component list in Admin area) then I can try namin my component accordingly, etc
That said, you can set initializer order for advanced use cases. I can put DiscoTOC in a named initializer so you can run your code before DiscoTOC, but I need to know what you’re trying to do first to give you a clear answer.
Your modifications here are based on an HTTP/AJAX request, correct?
Yes AJAX, but using a synchronous call. (I’ve always loved the oxymoron of synchronous AJAX :^)
I’m feeling like my next step is create a proper component—atm, it’s just some j/s pasted into my Theme’s Header. Then I can try fiddling with a judiciously chosen ID. “_foo” or “0-foo” might be all I need.
iirc, Theme Components are evaluated after plugins.
And could be wrong, but they are loaded in order of name, so putting an x- in front of the name has in the past helped me ensure a specific Theme Component is evaluated last.
Replies by others above suggest the name of the component does not affect the execution order. I’ve just renamed them to be aa-mycomponent and x-last-DiscoTOC and it doesn’t work. [DiscoTOC doesn’t include headings added to the DOM dynamically—yes, within the post body]
hmmmmmmm… maybe what’s wrong is more than ordering. I just hit inspect… and the things in the DOM which I thought where HTML headings… are in fact DIV tags with class="d-toc-ignore"
Time for me to dig further. Where’d my headings go?
Well, I think you could prove that out either way by trying a very basic example.
Create two simple components, overriding or connecting the same thing, perhaps a simple template with a slight difference, call one by a name starting later in the alphabet, note which one ends up overriding the theme.
It’s very clearly ordered by name in the code here in the model:
The Name doesn’t affect execution order. @merefield the line you linked affects how they’re displayed in the admin UI, but isn’t used for the actual execution.
This is the relevant line for execution order:
So they are executed in ascending order of ‘id’ in the database.
The only guarantee that’s portable across Discourse instances is that theme code is always executed before theme component code.
As @Johani mentioned above, if you have need to run code after some other component has loaded, the best bet is probably to use an Ember initializer, which supports ordering. Unfortunately that won’t be possible straight away in this case, since it doesn’t look like DiscoTOC is using Ember initializers. Updating DiscoTOC to use multi-file javascript (and therefore ember initializers) would certainly be pr-welcome