Updating Discourse Plugins, taking the first step

I have to fully read the new plugin api format but my first problem actually has to do with this error:

The discourse/components/post-menu object has been removed from Discourse and your plugin needs to be updated.

PostMenu is a pretty important one and as far as I can tell does exist upon searching the Discourse repo on github. This is what is in the plugin:

import PostMenu from 'discourse/components/post-menu';
import StringBuffer from 'discourse/mixins/string-buffer';
import { iconHTML } from 'discourse/helpers/fa-icon';
import ComposerController from 'discourse/controllers/composer';

…some code inbetween…

  PostMenu.reopen({
    buttonForLike() {
      const likeAction = this.get('post.likeAction');
      if (!likeAction) { return; }
      var className = likeAction.get('acted') ? 'has-like fade-out' : 'like';
      var uId = Discourse.User.current().id;

      if (uId%2 == 0) className+= " custom-like"

      const opts = {className: className};

      if (likeAction.get('canToggle')) {
        const descKey = likeAction.get('acted') ? 'post.controls.undo_like' : 'post.controls.like';
        return new Button('like', descKey, 'heart', opts);
      } else if (likeAction.get('acted')) {
        opts.disabled = true;
        return new Button('like', 'post.controls.has_liked', 'heart', opts);
      }
    }
  });

Is there no more PostMenu component?

Can you explain what this plugin is doing? There might be a better (easier) way of doing it now :wink:

It does a couple of different things. For every other user, the like button style is different. The more important function of the plugin which isn’t shown in what I copied over, is that for logged out users, taking the action of liking or replying will redirect to a specific URL.

   //if NOT current user
          PostMenu.reopen({

            buttonForLike() {
              const opts = {className: 'like'};
              return new Button('like', 'post.controls.like', 'heart', opts);
            },

            // Reply button
            buttonForReply() {
              const options = {className: 'create fade-out'};

              if(!Discourse.Mobile.mobileView) {
                options.textLabel = 'topic.reply.title';
              }

              return new Button('reply', 'post.controls.reply', 'reply', options);
            },

            clickLike(post) {
              location.href = this.redirectUrl();
            },

            clickReply(post) {
              location.href = this.redirectUrl();
            },

            redirectUrl() {
              return 'http://website/join/?try=comment'
            }
          });
        }
      }
    }
1 Like

Hmm, so you need to override the current behaviour of existing PostMenu buttons.

Is that still possible @eviltrout?

1 Like

You are going to update to use the new client side Discourse Plugin API. In particular you will want to use addPostMenuButton.

For a larger example complete with backwards compatibility, you can check out the solved button plugin code.

1 Like

I believe he doesn’t want to add a new button but rather change the behavior of an existing one. I guess you could hide the original like button and add a custom one…

so clickLike is not a thing anymore?

I don’t believe so. It moved from a component to a widget.

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/widgets/post-menu.js.es6#L32

1 Like

Ah, thanks for the clarification. You can actually use api.attachWidgetAction to overwrite a widget’s action too:

api.attachWidgetAction('post-menu', 'like', () => {
  console.log('new like code goes here');
});
6 Likes
  api.addPostMenuButton('coffee', () => {
              return {
                action: 'drinkCoffee',
                icon: 'coffee',
                className: 'coffee',
                title: 'coffee.title',
                position: 'first'  // can be `first`, `last` or `second-last-hidden`
              };

I have a question about the position argument for addPostMenuButton. How would one go about positioning the new button as second or third. Seems like if you can choose first or last, you might as well give ful control and be able to choose middle, etc as well.

Those positions are based on existing plugin behaviours I needed to duplicate. It turned out that they only needed those three options!

It is more complicated than it seems at first because there is a hidden chunk of icons in the middle. So if you said “middle” does that mean in the hidden section?

As for second, I’d happily accept a PR that adds that :slight_smile:

1 Like

I’d be happy to try :slight_smile:

Would you mind pointing me in the direction of where the position: first logic currently lives in the Discourse repo? :grin:

Edit: found it

Made the PR :smile:

https://github.com/discourse/discourse/pull/4108

2 Likes