Adding helpers to existing controllers from plugin



I’m working on a plugin right now and part of the requirements are that I display some information not only on the profile page of a user but the profile preview user-card, inside the profile main page the controller has access to a method called viewingSelf yet the same does not exist for the user-card.

How can I go about extending the user-card controller to support this method? Keep in mind this must remain isolated to my plugin and I cannot modify discourse itself in anyway.


No one has any idea on how to accomplish this? This seems like it should be something pretty straight forward to do from a plugin, overriding the controller within my plugin files does not work like a template does.

(cpradio) #3

What sort of information and more importantly where do you need to display it? As plugin-outlets are usually utilized for this purpose.

(Rafael dos Santos Silva) #4

Showing a custom user field inside the user card is pretty easy, I add all the employee info on my user cards:

<!-- File discourse/plugins/discourse-plugin/assets/javascripts/discourse/connectors/user-card-metadata/show-user-card.hbs -->
<div class="falco-custom-card">
    <span class="position">{{user.user_fields.[3]}}</span>
    <span class="branch-id">{{user.user_fields.[1]}}</span>
    <span class="branch-name">{{user.user_fields.[2]}}</span>


I think you are all misunderstanding the question,

Adding the buttons to the user-card is trivial but what i need is to add a method to the user-card controller.

This method specifically.

viewingSelf: function() {
return this.get(‘content.username’) === Discourse.User.currentProp(‘username’);

(cpradio) #6

Isn’t that as simple as putting a file in your plugin that does userCardController.reopen … and adding the method?

Subsequently, I highly doubt the team would be against putting that in Core. They would likely accept such a PR.


Can you provide an example logic? I’ve tried a few attempts to over ride the existing user-card methods.

I’m not following what you mean by reopen, as the user-card controller itself is defined as Ember.Controller.Extend.

(cpradio) #8

Do you have an initializer for your plugin?

If so, it would be like this

import UserCard from 'discourse/controllers/user-card';

export default {
  name: 'plugin_name',
  initialize: function() {
       viewingSelf: function() {
         return this.get('content.username') === Discourse.User.currentProp('username');


Awesome, thank you that seemed to have done the trick. Is there a documentation page somewhere outlining this that I didn’t see?

(cpradio) #10

Not that I know of, it is just one of the many advantages to Ember’s framework. You can reopen existing objects and append to them.


Yeah, I’m just used to being able to physically edit the controllers themselves when working within Ember so extending things via plugins is a little odd for me haha


Thanks again for your assistance, though I have a question regarding how to append methods directly to the application controller itself.

I’m currently doing this…

import Application from 'discourse/controllers/application'

  canInviteToForum: function() {
    return Discourse.User.currentProp('can_invite_to_forum');

but that doesn’t seem to actually be appending the method, is there something I’m not grasping that changes when accessing the application controller vs say the user-card controller? Thanks.

(Robin Ward) #13

That should work, but due to the way ember works would only be accessible in the application template which I suspect is not what you want?

Most templates should be able to check that property by just saying {{currentUser.can_invite_to_forum}} because currentUser is injected just about everywhere.


Awesome, i got it now thanks again.

My final question is since I want an action handler available in the global scope say if I’m on the discovery page then how would I make that action available? Would you suggest I append it to currentUser since that is like you said injected everywhere? Currently appending it to Discovery results in a “nothing handled action” message.

Figured this out as well, thanks again.

import DiscourseController from ‘discourse/controllers/controller’;


(Robin Ward) #15

If you need a global action handler we tend to put those in the application route.