A tour of how the Widget (Virtual DOM) code in Discourse works

#21

I can see the plugin-outlets in the header are gone. Any tips on how to add stuff to the header now?

0 Likes

(Robin Ward) #22

The header uses the same apis as the new post stream, so you can just use decorateWidget to add code before or after any widget in the header for your needs.

0 Likes

(Angus McLeod) #23

It seems that this.queueRerender() is now this.scheduleRerender() ?

2 Likes

(Robin Ward) #24

Sorry, my mistake. Within a widget you call queueRerender() which triggers a scheduleRerender() on the ember component that embedded it.

So yes, you should be using queueRerender


edit: No, this post was wrong and I was right before. scheduleRerender is what you call within a widget to rerender. It calls queueRerender on the component.

4 Likes

(Steven Slade) #25

I want to createWidget that has the attrs of an exisitng widget (specfically the topic-map widget’s attrs). When creating a widget, how do you pass it the attrs of another widget to use?

0 Likes

(Robin Ward) #26

You can pass anything as attrs to a widget when you attach it using this.attach('widget-name', attrs).

It looks like topic-map is attached with the attrs from the post it’s inside.

2 Likes

(Steven Slade) #27

Right, that’s what I thought.

attrs.topicViews is inside the widget topic-map, which is inside the post widget (attached through a few other widgets of course). However, in the post widget, attrs.topicViews comes up undefined.

0 Likes

(Steven Slade) #28

I just realized that a topic with one post will not show the topic views in the attrs. I am able to see it now on a topic with multiple posts.

0 Likes

(Robin Ward) #29

Yes the topic map is only shown if certain criteria is met:

Otherwise we don’t bother to include that information because it’s not displayed.

2 Likes

(Steven Slade) #30

Is is possible to render a component inside a created widget?

0 Likes

(Angus McLeod) #31

:confused: hm, maybe it’s my own confusion, but I’ve found the opposite is true.

Within the message-list widget I’ve created for Quick Messages, if I replace this.scheduleRerender() with this.queueRerender() it doesn’t work. It tells me this.queueRerender() is not a function:

Likewise, if I use this.scheduleRerender() in the site-header component I get an error.

Using this.scheduleRerender() in widgets and this.queueRerender() in components works fine however.

2 Likes

(Robin Ward) #32

Yes but it’s slow so you should avoid doing it whenever possible. Create a decorator, then use connect on it.

Oops, not sure if I wrote that before :coffee: but I did get it backwards. I’ll edit that post. It’s scheduleRerender within a widget. It calls queueRerender on the component that embedded it.

2 Likes

(Alan Tan) #33

@eviltrout I’m adding a link in the hamburger menu but I’m not sure if this is the right way. Also, do you think we can expose this in the pluginAPI?

api.decorateWidget("hamburger-menu:generalLinks", _ => {
   return { route: 'birthdays', label: 'birthdays.title' };
 });
0 Likes

(Robin Ward) #34

That is the correct way. What do you mean in the plugin api? It looks like you are already calling api.decorateWidget. Unless you mean a shortcut for adding links like api.addHamburgerGeneral or something perhaps better named?

1 Like

(Alan Tan) #35

Yea I was thinking of addGeneralLink like addPosterIcon since adding a link to the hamburger menu should be pretty common for plugin developers.

2 Likes

(Steven Slade) #36

I’m getting this error:

Uncaught Error: Assertion Failed: You specified the templateName discourse/components/topic-notifications-button for <Ember.View:ember1314>, but it did not exist.

I tested with admin/templates/modal/admin_delete_flag and it did indeed work.

0 Likes

(Robin Ward) #37

Sure, go ahead and add it!

2 Likes

(Joe Buhlig) #38

Here’s another one for you, Robin. Mounting a widget in raw.hbs.

I’m attempting to use mount-widget in through a plugin-outlet (until the topic-list is ported over to the widget structure) here:

It fails and I’m unable to find an error anywhere. It’s as if it never tries to mount it.

0 Likes

(Robin Ward) #39

You can’t embed a widget in a raw template. But don’t worry, we aren’t going to convert the topic list over. The gains over raw rendering for that part are negligible.

6 Likes

Mounting widget in raw template?
Mounting widget in raw template?
(Joe Buhlig) #40

That’s a relief. I’ve been working on a few things that this would impact and I was worried I’d end up repeating everything.

So if I can’t mount a widget (and I assume I can’t assign actions or helpers as well), is best practice to go this route:

import TopicListItemView from `discourse/views/topic-list-item`;

TopicListItemView.reopen(click: function(e){
   // my stuff
   this._super(e);
});
0 Likes