I’ve got a glimmer component. It’s working. But I need it to go after the first post in a topic. There’s no plugin outlet there.
I did figure out how to insert some text in the innerHTML of the <article> tag, and that puts that text where I want, but there doesn’t seem to be a way to do that with a component.
Am I missing something?
I looked at how the adplugin inserts ads between posts, but I couldn’t quite make sense of it.
(there are legacy ways to accomplish what you’re doing, but the’ll break when we modernise the topic view. If we add a plugin outlet, it’ll be much more future-proof)
The post is passed as one of the outlet arguments, so you can check post.post_number == 1
Haha! Always happy to help with these kinds of questions. Much better for everyone if we can get themes and plugins using standard APIs like this rather than widget workarounds (which will be deprecated in the not-too-distant future).
Yeah that’s fair. Adding them inside widgets is a headache on the core side. But from the theme/plugin side it should be super clean
I’ll try and figure out those test failures and get the PR merged tomorrow. (Looks like the extra html element is messing with some fragile selectors in the qunit tests)
I’m afraid I may have been a bit over-optimistic here @pfaffman, sorry! The PR I made would introduce a new wrapper <div> between every single post, even if the outlet was not being used. That’s not really something we want to do.
There may be ways to avoid the wrapper… but nothing simple which we can do immediately.
So I think the best immediate solution for you is going to be copying the adplugin implementation which you referenced in the OP.
Essentially:
Create a component (Glimmer or classic, doesn’t matter) which renders whatever you want
Use registerWidgetShim to make that component available as a widget. The adplugin example is creating a widget called “after-post-ad”, which renders the PostBottomAd component. It is passing all of the widget attributes (@data) into the @model argument of the component.
Use api.decorateWidget to render your new widget shim in the post:after position. In your case, since you only want it on the first post, you could do something like
When we eventually glimmer-ify the topic page, you’ll need to remove the widget shim/decoration, and replace it with a plugin outlet. That should be pretty easy, since all your display logic in the component will be reusable in the plugin outlet.
Let us know how you get on! Happy to help with any follow-up questions - I know there are a lot of moving parts here.
In this case, I don’t think you’ll need to import the Service class. That would only be needed if you were creating your own Service. You just need the service injection decorator.
And in the latest version of Discourse/Ember, it can be simplified even further to avoid needing the ‘inject as’ alias. Ember now make the injection decorator available directly as service.
import { service } from "@ember/service";
(but the old { inject as service } still works, and I’m not aware of any plans to deprecate it in Ember)
EDIT: But maybe I can use decorateWidget instead of a plugin outlet. . .