Second smiley-plugin gets blocked by default emoji plugin?

(Joe Seyfried) #1

Hi there,

I just started to hack away with a new smiliey plugin (based on the original emoji plugin) to make transition from my old forums easier for my user base. However, I ran into an interesting problem: although the original emoji plugin was disabled in the site settings and the editor window displayed my own smiley list all right, the smilies did not get replaced in the posts (or the preview area). Only when I moved the original emoji plugin out of the way, things started working. Chances are that I’m doing something completely wrong, so I’d be glad for any pointers into the right direction. I’m currently wondering if you cannot call Discourse.Dialect.registerInline twice (the emoji plugin does that before it checks if it’s disabled or not, so my smiley plugin wouldn’t stand a chance to do the same if called second).

I refactored everything to avoid naming collisions, there’s no mention of “emoji” in my whole plugin directory but for the and the plugins.rb comment line (d’uh, I know).

To illustrate the problem, here we go:

(Sam Saffron) #2

This is an interesting problem we need to add a clean mechanism for hard disabling plugins

(Jens Maier) #3

You can call registerInline at most once per unique start string. The backend implementation stores inline replacer functions in a hash keyed by that string, so the last call of registerInline for a non-unique start replaces all previous handlers for the same start tag.

If you want to be hackish, you could hook deep into the Markdown parser:

  • BetterMarkdown.Markdown.buildInlinePatterns gets called exactly once after all plugins are loaded.
  • The default emoji handler is stored in BetterMarkdown.Markdown.dialects.Discourse.inline[":"].
  • Putting these together, replace buildInlinePatterns with a function that replaces the default emoji handler with your own; just do not forget to call the original buildInlinePatterns afterwards.

Naturally, this is tightly coupled to the current implementation of the Markdown parser and the Discourse dialect, so you’re on really thin ice, and I personally wouldn’t try to distribute this as a plugin. But it should work well enough to placate your users for the time being. :slight_smile:

(Joe Seyfried) #4

Thanks Sam and Jens for your insights. So basically, I’m left with two options: move the emoji plugin out of the path and repeat this process for each update (I suppose that the updater will put it back in place since it’s in the Discourse main package?), or start hacking into the handlers of Discourse, ending with a broken mechanism later into the game… :wink:

Couldn’t we change the registration of the “:”-handler for the time being from

Discourse.Dialect.registerInline(':', function(text, match, prev) {
    if (!Discourse.SiteSettings.enable_emoji) { return; }


  if (Discourse.SiteSettings.enable_emoji) { 
    Discourse.Dialect.registerInline(':', function(text, match, prev) {
      if (!Discourse.SiteSettings.enable_emoji) { return; } // we could drop this line

:question: …this would stop the plugin from interfering with anything else until we have a hard-disable mechanism for plugins as Sam suggested.