Feedback Requested (honestly): Adding Custom BB Codes to XenForo

Status
Not open for further replies.
Joined
Oct 6, 2010
Messages
105
Joined
Oct 6, 2010
Messages
105
Updated with the rest of the second section (creating the class that is used to extend the BB Code class installed by default). One simple step in here, but will now move on to writing the simple codes, and then onto the spoiler tag.

Edit: 3rd section has been posted.
 

Nix

Just a little crazy!!
Staff member
Joined
Mar 30, 2009
Messages
6,641
Looks very comprehensive and flows well, good job so far:)
 
Joined
Oct 6, 2010
Messages
105
As requested, here is a comprehensive Step By Step guide to creating BB Codes for XenForo, or at least, until Kier and Mike create a manager in the backend.

In XenForo, BB Codes are handled via PHP classes (as in most other bulletin boards), and to add more, you must extend these classes, adding more tags to the list. Below, I will take you step by step in adding three tags: a spoiler tag (one that may or may not have options), a simple header tag (h2), and another simple float tag (with an option).

Note: This article does not cover how to utilize a template for your display, and everything is currently handled via PHP. I may revisit this in the future to add a "template based" PHP BBCode.

The Basic Setup and Classes​
In this section, I will describe the basic setup required to setup the BB Code system to utilize your newly created tags / classes.


Step 1: Place a test/development board into debug mode.

I do not suggest you place a live, functioning XenForo forum into debug mode. Always, always utilize a test / development board. To accomplish this, add the following PHP code to the beginning of your config.php file after creating a back up of the file:
PHP:
$config['debug'] = 1;

Reloading your Administrator Control Panel (ACP) should now show a 'Development' tab next to the 'Tools' tab. If it does not, please make sure you uploaded and overwrote your existing configuration file.

Step 2: Create your add on.

Since XenForo wants everything related (and rightly so), our next step is to setup a new "add on" for use on your site (you will export this at the end of this article to import to your live board). For simplicity, I shall name mine "XenBBCode". To add a new add on you want to go into the Development tab within the ACP and click on "Create Add-On." In here, you want to place your ID in the ID slot. This ID will be used later in the article in naming of classes, and should not include any spaces.

Step 3: Create your event listener class.

The next required step, is to create an event listener class to allow extension of the BB Code system. To accomplish this, create a file located in /library/XenBBCode/EventListener/ and called BbCode.php. You will need to create the XenBBCode directory and its sub-directories yourself. These are unique to your add-on. (Note: XenBBCode should be the ID of your add-on for the rest of this article.) Now, add the following contents to your new PHP file...
PHP:
<?php

class XenBBCode_EventListener_BbCode
{
    public static function listen($class, array &$extend)
    {
        if ($class == 'XenForo_BbCode_Formatter_Base')
        {
            $extend[] = 'XenBBCode_BbCode_Formatter_Base';
        }
    }
}

Within this file, as you may have noticed is a class. The title of the class should always follow your directory structure. Every time you have a slash ( / ), replace it with an underscore ( _ ), and just chop off the .php extension. So, let's look at that transformation:
XenBBCode/EventListener/BbCode.php -> XenBBCode_EventListener_BbCode

This allows XenForo's autoloading of classes to recognize and know the location of the file your new class resides in.

You may have also noticed the contents of the class is a single function, with two arguments. These arguments are gathered from XenForo, and will be explained in the next step. The code within the function is something we only want run when it attempts to load the BbCode formatting class that comes with XenForo, so, we add the condition. And lastly, the code within the condition tells XenForo which class should be used to extend the default class (and it is $extend[] so that XenForo can automatically resolve hierarchy and such for you). Within the function definition, it is also important to have the word "static" in there as XenForo calls this function statically, and never creates a new object.

Step 4: Add the Event Listener

Now that we have created our class, we want to tell XenForo to utilize the class when it attempts to load the specified class. We do this through the extremely powerful Event Listener system. This system basically opens up the entire forum to extension through just a few extremely well placed "events." So, let's add ours to the mix.

Within the development tab, lets click on "Code Event Listeners" and then again on "Create New Code Event Lisener." Within this screen, we want to set a few options. Firstly, we want to choose "load_class_bb_code" as the event we want to listen in on. Once you choose this option, you will notice a a description pop up below the select. Within this description, you will see a list of arguments, that correspond to the arguments we added into our listen() function in the last step. These must be absolutely exactly the same for the system to work correctly.

Now, let's set the callback method. The first option is the class name you created (XenBBCode_EventListener_BbCode, for my example) and the second is the method. The method will be listen() as that's the way I told you to name it in the last one, but it should be the name of the function you created to extend the BbCode parsing class.

The last two options you want to set are the description and add-on. The add-on should be the one you created in the second step. The description can be anything you want, but should be used to describe why the event listener is added. For this example, I placed "Adds three custom BBCodes to XenForo."

Adding the Custom BB Code Parser Class​
Now that we have the basics of our add-on / custom BB Code system in place, we can start actually adding BB Codes to our system. To do this, we will create a class that will be used to house all three BB Codes that will be added. By creating a simple class, you ensure all are properly added and created for use on your board. I'm sure you can already figure out the class name we will be using, but in case it didn't immediately jump into your head (don't worry, there's nothing wrong with that) the class name will be: XenBBCode_BbCode_Formatter_Base.


Step 5: Create the Extending Class

Next, we want to create the class that we defined as the extension to the default BB Code formatting class. Create a new file in /library/XenBBCode/BbCode/Formatter/ and name it Base.php. Again, refer to Step 3 as to why the file is to be located in this directory and named Base.php. Add the following code to your class (Note: If this class was left as is, your forum's BBCode would be unchanged, as it is identical to the included BB Code formatter):
PHP:
class XenBBCode_BbCode_Formatter_Base extends XFCP_XenBBCode_BbCode_Formatter_Base
{
	protected $_tags;
	public function getTags()
	{
		$this->_tags = parent::getTags();
		return $this->_tags;
	}
}

You will (or should) notice that our class is extending a class that isn't defined. This will be resolved by XenForo automatically, but you always want to place an extends statement in your definition. Our classes extend a class with the same name as ours, just with the prefix of XFCP_. Make sure this line is there, or else, our add-on will not work as desired, if at all.

Within the class, we define a protected variable _tags, which will hold an array off all the tags and their information. This variable name was taken from its parent class, but isn't strictly required to be _tags, but I recommend you do this.

Now, we overwrite a function called getTags() inside of our class so that we can add tags. When the parser starts to parse BB Code, it'll call our getTags(), rather than the included one. Which means, if we just define our tags, everything as simple as [b][/b] would not be displayed as bolded text. So, the first line in our getTags() class should always be:
PHP:
$this->_tags = parent::getTags();

This statement will return an array of all default XenForo BB Codes and add them to our array, which we will build upon in later sections of this guide. And the last line should always be returning our array, so the parser can build and display posts correctly (with custom tags!).

Creating a simple, no option required BB Code (<h2></h2>)​
Next, we are going to look at how to add our BB Codes to the system. To do this (and for the rest of this article), we will be working in the class we defined in Step 5, and not moving outside of that class. So, when I ask you to add code, modify a function, etc., it should be done within this class.​
Step 6: Add the definition for an [h2][/h2] tag.​
Within the getTags() function, we want to add a new entry into our _tags[] array, so that it'll recognize [h2][/h2] as a valid tag. To do this, we want to modify our getTags() function to look like such:​
PHP:
	public function getTags()
	{
		$this->_tags = parent::getTags();
		$this->_tags['h2'] = array(
			'hasOption' => false,
			'replace' => array('<h2>', '</h2>')
		);
		return $this->_tags;
	}
What we do, is we add a new index to the array ('h2'), and define an array of options as its value. For this simple tag, we want to say that it does not have an option ('hasOption' => false) and that it should be replaced with <h2> for [h2] and </h2> for [/h2]. This is defined in the option 'replace', which itself houses an array of two things: the replacement for the opening tag (first index) and the replacement for the second tag (second index).​
 
Joined
Oct 6, 2010
Messages
105
If you save and upload this file, you should now be able to utilize [h2] within your posts. If you comment out these lines, [h2] will not be replaced when BB Code formatting occurs. Test this, just to make sure there weren't any errors (there shouldn't be, tho).​

Building a simple, option required BB Code (float)​
Now that you've seen how to add a simple, no option required BB Code for your forum via PHP and Event listeners, let's now add one that adds a small bit of complexity, but is still relatively simple. We want to create a [float][/float] tag that tags the direction (left, right) as the option. in theory, if a user knows his way around this system and CSS, you can style you're float any way you want (as it's just a <div style="float: {option};">) in different posts. So, let's dive right in.​
Step 7: Add the definition for a [float][/float] tag.​
Now, we want to add another entry into our index, so let's do that by modifying getTags() once more to give us the following PHP code:​
PHP:
	public function getTags()
	{
		$this->_tags = parent::getTags();
		$this->_tags['h2'] = array(
			'hasOption' => false,
			'replace' => array('<h2>', '</h2>')
		);
		$this->_tags['float'] = array(
			'hasOption' => true,
			'replace' => array('<div style="float: %s;">', '</div>')
		);
		return $this->_tags;
	}
Now, you will notice that the form is very similar between float and h2, but the key difference is that 'hasOption' => is now set to true. Meaning, when XenForo starts to parse the thread, if you put [float][/float], it will leave it as such, as you haven't specified an option. You can get around this via a more complicated method that'll be explained with the addition of a spoiler BB Code in the next section.​
Now, you must provide XenForo with data on where you want the option to be displayed and you'll want to do this by placing "%s" where you want the option to display. Note: You may only use this method once, meaning you cannot put the option in more than one place. If you'd like to do this, please look at adding the spoiler BBCode, else, it won't work correctly and will spit out PHP errors and warnings.​
Now, save you're class, and over write the existing class. Adding [float="right"]Hi![/float] should create a new div that floats to the right. Something such as [float="right; right-margin: 5px"]margin![/float], should still work just fine.​
 

Floris

I'm just me :) Hi.
Staff member
Joined
Jan 1, 2001
Messages
60,098
Wow, quite a bit to read, Thanks for posting to our premium members. Looks great. I have to sit down later on and properly read through it. A lot of thinking required, and bit of learning. Very good stuff, thumbs up.
 
Joined
Oct 6, 2010
Messages
105
Thanks, and so far, that's just a single BBCode! I still have 2 more before I finish this thing... and 1 or two wrap up things. :)
 

Floris

I'm just me :) Hi.
Staff member
Joined
Jan 1, 2001
Messages
60,098
It's almost like you've got nothing to do today :D

You've deserved a proper thumbs up

thumbsup
 
Joined
Oct 6, 2010
Messages
105
It's almost like you've got nothing to do today :D

You've deserved a proper thumbs up

thumbsup

Oh, no, I have a shit load to do today, but I promised that I would get this article up by today or tomorrow for someone at XenForo.com, so I'm keeping the promise. :)
 

Floris

I'm just me :) Hi.
Staff member
Joined
Jan 1, 2001
Messages
60,098
It's nice to have it on xenfans as well, really appreciate it :D
 

Floris

I'm just me :) Hi.
Staff member
Joined
Jan 1, 2001
Messages
60,098
doesn't the float require a <div style="clear:both"></div> behind it ?
 
Joined
Oct 6, 2010
Messages
105
Um. Does it? I wasn't necessarily going for 'looks.' Just simple examples. Does it need it? I can easily add it. I know there is a problem with rendering of children tags, and will have that fix in here too.
 

Floris

I'm just me :) Hi.
Staff member
Joined
Jan 1, 2001
Messages
60,098
If you add a float, but the content you're in already uses a float (like the avatar on teh left) it's quite possible that the content looks "broken" because the float isn't cleared.
 
Status
Not open for further replies.
Top