How to access current post tags using Ember and JavaScript?


(Jay Crossler) #1

Hi, first time poster. Loving Discourse so far!

I’m writing a plugin that will do some auto-tagging suggesting based on the content of the title and post. I’m trying to access a few things at the JavaScript level - trying to get access to the client-side view of the current post that’s being typed in. My goal is to make a new route and action (similar to draft.json that gets sent every few letters typed), and have that respond with suggested tags if the server algorithm triggers a response. This of course needs tagging turned on in the admin menu.

I’m trying to access the Tag Chooser - I can do so in JQuery via: $('input.tag-chooser')

But, if I try to add an existing tag programmatically, using:
$('input.tag-chooser').select2('data',{id:'tags', text:'tags'});
It then shows up on the UI, but not once I save it (guessing it didn’t save to the model) because I didn’t run this.set('tags', tags); – because I don’t have access to the this object. When I modify tag-chooser to get access, setting also doesn’t seem to work as expected.

But, I’m trying to get access to the main JS object that is built in tag-chooser.js (in _initValue) so that I can add a tag to it… or maybe to access the Ember object to add a tag that way. I see that it looks like the main Global variables are in the JS Discourse object… but I’m not sure how to do something like Discourse.get(‘Tags’) or Discourse.set(‘Tags’) or what.

Any suggestions on where to start? I’m going through Ember tutorials now, but it’s a bit slow going.


(Robin Ward) #2

What you probably want to do is extend the Composer controller and add an Ember observer on the model’s reply field. When it changes, you can perform your ajax request, then set the tags using this.set('model.tags', 'new value')

For a plugin to do this, you’ll need to create an initializer that looks up the composer controller and runs extend on it.


(Jay Crossler) #3

Thanks so much for the reply.

I tried creating a file in my plugin: plugins/myplugin/assets/javascripts/discourse/controllers/composer.js.es6

With export default Ember.Controller.extend({...}) but this doesn’t seem to get loaded into the asset pipeline. All my other plugin code is loading fine.

Is this the best way to extend the controller? Or is there another way to lookup the post controller so I have a pointer to it?

Thanks again.


(Robin Ward) #4

No you’ll need to do what I said above:

create an initializer that looks up the composer controller and runs extend on it.

If you need an example the Poll plugin does this.


(Jay Crossler) #5

That was very helpful (after I read through 5 Ember tutorials and 1 on es6). Here’s what I came up with for others if they need it (in /plugins/myplugin/assets/javascripts/discourse/initializers/listener.js.es6):

import { withPluginApi } from 'discourse/lib/plugin-api';
import { observes } from "ember-addons/ember-computed-decorators";

function initializeIntelligentTagger(api) {
  const ComposerController = api.container.lookupFactory("controller:composer");
  ComposerController.reopen({
    editPostItem: function () {
      console.log(this.get('model.title'));
      console.log(this.get('model.reply'));
    }.observes('model.reply')
  });
}

export default {
  name: "add-intelligent-tagger",
  initialize() {
    withPluginApi('0.0.1', initializeIntelligentTagger);
  }
};

Critiques would be appreciated. Next, I’ll work on the ajax call to guess at tags. I’m thinking of first removing the top 10k most common words, then have a lookup table for v1, then feed it to a deep-learning algorithm to train for v2) - hints welcome.