Forcing Discourse to replace BBcodes with HTML?


(NomNuggetNom ) #1

Skip to post 4 for my new question :slight_smile:


I have no knowledge of Ruby and very little of HTML/CSS, so bear with me. All I want is to add a custom BBcode and have an HTML tag applied to it. For example:

[u]Hello![/u]

Would become:
<u>Hello!</u>

Or similar. If I can just get the basic hang of it, I’m sure I can make it more advanced. But for now, I need the baby steps. Thanks :D.


(Robin Ward) #2

We already support the <u> tag, but if you want to look at how the code initializes it, it’s in here:

https://github.com/discourse/discourse/blob/master/app/assets/javascripts/discourse/dialects/bbcode_dialect.js#L74


(NomNuggetNom ) #3

Yup, just an example. Thanks for linking that code, I’ll play around with it. Is there a similar organization to the Markdown detection, and if so, can you link it? (sorry if this is a silly question).

EDIT: found it.


(NomNuggetNom ) #4

Okay, so I’ve got it to the point where it is handling text just fine. However, problems occur when it encounters a non-HTML element. First of all, this is the goal:

[detail][summary]Summary of Spoiler[/summary]Actual Spoiler Content[/detail]
becomes…
<details><summary>Summary of Spoiler</summary>Actual Spoiler Content</details>
which is rendered as…

Summary of SpoilerActual Spoiler Content

Again, this works fine. But, if I try this:
[detail][summary]Summary of Spoiler[/summary][img]//discourse-meta.s3-us-west-1.amazonaws.com/original/3X/9/d/9d654c5fbae12c89ee98f1c59acf3e92560116a8.png[/img][/detail]
it becomes…
<details><summary>Summary of Spoiler</summary>[img]//discourse-meta.s3-us-west-1.amazonaws.com/original/3X/9/d/9d654c5fbae12c89ee98f1c59acf3e92560116a8.png[/img]</details>
which is rendered as…

Summary of Spoiler[img]//discourse-meta.s3-us-west-1.amazonaws.com/original/3X/9/d/9d654c5fbae12c89ee98f1c59acf3e92560116a8.png[/img]

And, finally, if I do this:
[detail][summary]Summary goes here![/summary] <img src='//discourse-meta.s3-us-west-1.amazonaws.com/original/3X/9/d/9d654c5fbae12c89ee98f1c59acf3e92560116a8.png'> [/detail]
it becomes…
<details><summary>Summary of Spoiler</summary><img src='//discourse-meta.s3-us-west-1.amazonaws.com/original/3X/9/d/9d654c5fbae12c89ee98f1c59acf3e92560116a8.png'</img></details>
which is rendered as…

Summary of Spoiler<img src='//discourse-meta.s3-us-west-1.amazonaws.com/original/3X/9/d/9d654c5fbae12c89ee98f1c59acf3e92560116a8.png'

This is actually a problem outside of the plugin, obviously. There must be some way to fix this - Discourse tags the BBcodes and converts them to HTML anyway, it’s just a matter of making it do that first, right? Could I pass the text to replaceBBCode?

Here is my code. Also tagging @zogstrip because I followed his awesome plugin tutorial :slight_smile:


(Kane York) #5

Yeah, I think if replaceBBCode recursed into the internal text this might be fixed…


(NomNuggetNom ) #6

Is this something I can do myself?


This seems like something that could be so simple to fix :’(.


(Kane York) #7

I misspoke. After reading the code, I’ve got a fix for you…

replaceBBCodeParams("expand", function(param, contents) {
  return ['details', ['summary', this.processInline(param)]].concat(contents);
}, false);

With my slightly modified bbcode_dialect.js file.

(Note: I think this might be a good thing to just put in core, if we can get the JS working for Firefox and IE.)
(Also, I can’t test this yet as Nokogiri is not building or something…)


(NomNuggetNom ) #8

I’ll give it a go, thanks. Should I just put that anywhere into the .js file? (here is my code)

EDIT: Okay, so I can’t just throw it in there. Where does it go? (sorry I’m a noob :()


(NomNuggetNom ) #9

I noticed a similar problem. If a plugin inserts BBcode, it isn’t rendered.

This might be worth tagging @eviltrout. Could be a big problem imo.


(Jeff Atwood) #10

You generally should not insert BBCode unless you have to, Markdown is native, everything else is converted.

Granted, there are some cases like [quote] where we have additional metadata that’s only possible through the BBCode.

But for the two you cite, image and URL, those should absolutely not be inserted as BBCode. Sorry.


(NomNuggetNom ) #11

Understood. OH GOSH YOU BROKE QUOTE AAAAAHH.


(NomNuggetNom ) #12

I’ve changed it to use HTML. But I still really need help fixing my other problem :(.


(Jeff Atwood) #13

You also should not use HTML, unless you need some unique bit of HTML that cannot be replicated in Markdown. The preferred and native format is Markdown.

Here is how you make an image in Markdown:

![This is an image](http://example.com/image.png)

Here is how you make a link in Markdown:

[This is a link](http://example.com)


(NomNuggetNom ) #14

Oh right, good point. I’ll change it to that, thanks.

About my other problem, is there a function that returns processed text?

EDIT: @codinghorror Now I am just beyond confused :stuck_out_tongue:


(Mittineague) #15

Speaking of Markdown, we wanted to link to a “cheat sheet”.
Is this the “flavor” Discourse uses?
http://daringfireball.net/projects/markdown/syntax


Markdown syntax -- how to adding title to image
(NomNuggetNom ) #16

@riking Could you please tell me how I use that code? Doesn’t that try to match [expand]?

Also, I have changed the syntax to be:
[details "Title"]Content[/details]


(Kane York) #17

It doesn’t work, actually. Haven’t figured it out yet…


(NomNuggetNom ) #18

I also tried, but no luck:

Discourse.Dialect.inlineBetween({
    start: "[details]",
    stop: "[/details]",
    rawContents: false,
    emitter: function (contents) {
        return "<details><summary>Test</summary>" + contents + "</details>";
    }
});

I’m thinking maybe something replicating the code block detection would work…

Discourse.Dialect.replaceBlock({
  start: /(\[code\])([\s\S]*)/igm,
  stop: '[/code]',
  rawContents: true,

  emitter: function(blockContents) {
    return ['p', ['pre'].concat(blockContents.join("\n"))];
  }
});

But I can’t figure it out.