Create your own BBCode, using PHP
(Page 2 out of 2)Nesting BBCode can easily be done, and it's no problem to have [i] tags in between [b] tags. But you can't have [b] tags within [b] tags. For [b] tags this would be pretty pointless, and nobody does it. But in some cases, tags must be nest-able. Consider a [quote] tag, which can be used to display a quote. Sometimes you will have a quote within a quote. That's why the [quote] tag must be nest-able.
Regular expressions can't be used for this, because it doesn't support nesting, which means we have to write a custom PHP function for this. All we have to do is replace [quote] with the correct HTML, and replace [/quote] with the correct HTML. Then we have to make sure that all the [quote] tags have been properly closed (otherwise it could mess up our layout).
The function would look something like this:
$open = '
';
$close = '';
// How often is the open tag?
preg_match_all ('/\[quote\]/i', $str, $matches);
$opentags = count($matches['0']);
// How often is the close tag?
preg_match_all ('/\[\/quote\]/i', $str, $matches);
$closetags = count($matches['0']);
// Check how many tags have been unclosed
// And add the unclosing tag at the end of the message
$unclosed = $opentags - $closetags;
for ($i = 0; $i < $unclosed; $i++) {
$str .= '';
}
// Do replacement
$str = str_replace ('[ quote]', $open, $str);
$str = str_replace ('[ /quote]', $close, $str);
return $str;
}
(Please note that the above code has an error. The [quote] and [/quote] tags have a space after the [ character. Don't forget to remove it!)
As you can see the function first checks how often the open and close tags are used. If there is a difference, then it adds a close tag at the end of the message to prevent anything bad from happening. This function can be used for most tags that must be nest-able.
Conclusion
In this tutorial I have shown you how to create your own BBCode. If you've never had a look at bbcode before, you're probably surprised by how easy it is to create your own bbcode. I suggest you take the knowledge you've learnt from this tutorial, and extend the bbcode_format function to include more tags, and different kinds of bbcode.
Don't forget to view a live demo of everything you've learnt in this tutorial, and there is also a BBCode function in our codesnippets database.
December 16th, 2005 at 10:24 am
Thanks for this tutorial, however, wouldn’t it be better for the quote to have $str .= ‘
‘; as
$str .= $close;
December 16th, 2005 at 10:25 am
That was meant to be [/blockquote] replace [ with
January 17th, 2006 at 4:28 pm
cool, i have a similar set up on my site however i only check for [code] … [/code]
How could i get the syntax highlighting as you have on your site? I’ve tried using highlight_string(”$1″) but it’s not having any affect?!?
February 9th, 2006 at 7:27 am
I can’t seem to get this to work…on the site I’m creating, I have a form, that sends to a page that puts everything into the database. and then another page that displays the messages. I have tried to put it into both those pages, and it doesn’t work on neither on…I have tried changing $str to $post and still wont work…my site just seems to ignore the function and posts everything as you type it. Any idea’s what I could be doing wrong? Its prolly something small and stupid, but I can’t figure it out
thanks
March 21st, 2006 at 1:21 am
Good tut. I tried making it into a function but it wouldn’t return the variable.
June 16th, 2006 at 1:38 pm
If user has closed tags in wrong order it breaks web page (if using xhtml strict) like: [b]something[i]very[/b]
August 3rd, 2006 at 12:51 pm
Thanks a lot for this! Been meaning to learn regex. :D
April 2nd, 2007 at 2:43 am
Hey there,
Nice tutorial. However, I have a question. It’s been a few months since I’ve worked on my own BBCode class. However, when doing so, I was trying to get GeSHi to work with my BBCode class. The which I did this, was call a separate function from within my BBCode class, which would call the correct GeSHi settings and such.
However, I found when I called GeSHi, it was messing up the value which it retrieved, and returned it as a literal \\1 or $1. Depending on what I gave it for the preg_replace parameter. I’m trying to make GeSHi work with my BBCode class basicly, so GeSHi doesn’t return \\1 or $1 but returns the parsed GeSHi output instead.
Hope you understand what I mean, have you got any suggestions for this? I guess I should get down and dirty with GeSHi perhaps?
As I said, it’s been a couple months since I have done any work on my BBCode class, but from memory I could return the valid output I wanted from a custom function instead of \\1 and such.