Welcome to Our Community

Registration on our forums are now open for some days! Feel free to sign up today.

[screencast] Creating XenForo Add-on 1.0.0

Learn how to create your first XenForo add-on with this visual guide

  1. XenForo Rocks
    Creating a XenForo Add-on

    Many of the questions that we received athttp://xenfans.com were about how to display some text in the sidebar, header or footer. And how to make upgrading a lot easier. How does one create their own add-on, etc. These screencasts will walk you through the process of creating your first add-on for XenForo, so you can easily create your own templates, css, phrasing, and make upgrading a lot easier.

    Every board is unique, and every community has their own desires. So this might not be for everybody, but it should help you get started. If you are still not certain after these videos how to create an add-on for your site you can check out the third party services forum and see if there's a developer ready to help out.

    tl;dr : Create a new add-on, create your own .php file. Use a code event and one or more hooks. Tweak your custom template and phrases and perhaps include some options for choice. And you have a .zip file you can call your first add-on.

    All the videos were recorded without practice and with only a bit of preparation. They are however in a high resolution. You can watch them full screen in 1080p.

    Screencast 1 - Creating your own add-on

    To make sure that your custom phrases, custom templates, and custom options are all part of one add-on, we will first need to create a new unique addon.

    You can go to the admin.php file from XenForo by logging in as a full fledged administrator on the forums. In the top right there should be a link to the administrator control panel. The hometab will have a left sidebar from where you can click on 'list add-ons'. The page that loads will have a button in the top right that says Create new..

    The add-on ID has to be unique, short and simple. Don't use spaces. Personally I prefer to prefix all my add-ons with xenfans_ because my web site is xenfans.com. This means that my unique ID can't clash with someone else's who might have chosen the same ID as me.

    The title can be longer, more human readable.

    The version number, I tend to use x.x.x, you can start with 3.0.1 if you want, or 0.0.1, as long as the future releases are increasing from whatever you have.

    The version ID has to be incremented after every release. In the videos I just constantly go there to point this out. However, during normal development you give it an ID and work on the add-on until you release it with the public. Then increment it, and develop it again until it's released again.

    Having created your own add-on means you're done. It just doesn't do anything. So the next step is to do something with it. I've chosen to go the path of 'I want to display X on my forum at Y position, without editing any existing templates'. So I want to use a hook and my own .php code to display my custom template.

    Under the Appearance tab you can go to templates. Make sure you're in the Master style, and click on the button Create New Template.

    I like to make it easy to find and remember my templates. Using my site prefix like xenfans_and using the name of the add-on as another prefix, such as demo_. This should already be enough, but for the purpose of the video I also called it my main template. Just to imply you can have more templates (but more about that in an upcoming screencast).

    We might want to use phrasing, but for now I just put in some test data, such as: <p>test</p>and link the custom template to my own add-on by selecting it from the dropdown below the template editor. And then press the submit button to save my new custom template.

    If you'd take a look at the .xml of the add-on after exporting it, you will see there's a<templates> group with inside it a <template>tag with our custom template name and data.

    At this point your first add-on is done, just isn't really functional. But, you can export the template, uninstall it even, freshly install XenForo and import the .xml. Your add-on will re-appear and the custom template will be in the system.

    The next screencasts are about making your add-on functional, so we can use our custom template, and later on we will discuss how to customize our add-on by doing more with the templates, using the phrasing system so it's easier to translate for boards with multiple languages installed. And how we can get some control over the template, for example where we want to display it, header, footer or sidebar.

    Having me type it all out is one thing, seeing it with your own eyes might help you even more.



    Resources:

    XenForo Manual : Add-ons
    XenForo Community : Development Help

    Screencast 2 - Creating your own .php file

    We've created our own add-on within the XenForo system, and a custom template that we want to use. The next step is to create a .phpfile so we can use a Code Event Listener in our add-on to point to our class and it's method. Doing so means that we can now tell the system with php code to do something. For example that we want to use a certain hook in the system. More about that in the next screencast. Let's focus on the basics of the .php file.

    Every add-on has to be placed within theupload/library/ folder. So go to your FTP client and login to the host. From where you browse to the public html directory and the directory where XenForo is installed. There should be alibrary/ directory there. Go inside it.

    What I like to do is use my prefix again, my web site is XenFans.com so I use XenFans as my directory (prefix) name. We now havelibrary/XenFans/ This means that I can easily find my own add-ons within the file system, and can't be confused with add-ons from others.

    To avoid further confusion I also make a separate directory for each add-on that I create. For example I made a popular add-on and an extra tabs add-on. And now this demo add-on. I have:
    library/XenFans/Popular/
    library/XenFans/ExtraTabs/
    library/XenFans/Demo/
    And it's very easy to identify which files belong to what add-on, and who made the add-on.

    The above structure is also used to name our classes, and instead of a forward directory slash : /
    We have to use an underscore : _

    If your class is within the .php file Route.php for example, or in the case of this example our Listener file is called Index.php then we have:
    XenFans/Demo/Index.php

    To name your class, you remove the .php and replace the / with _
    XenFans_Demo_Index

    We can now use this class name in our .php code, and use it in the Code Event Listener as well. Linking them together.

    The .php file has to start with <?php of course, to tell the system the rest of the file is PHP programming code.
    Below it, we start our class { } and we just figured out how to call it. Our file looks like this now:

    Code:
    <?php
    class XenFans_Demo_Index
    {
    // code goes here
    }
    The next step is to have a function, so we have a method to use. You can make up the name of the method. And the Code Event Listener if you select the right option from the dropdown will give you the code to put inside the () of the function.

    Normally you can call your functions like addTemplate() or findUsers() etc. For this demo I've simply gone with XenfansDemo()

    It's a public static function and we want to use a template hook. The Code Event Listener within XenForo, underneath the Development tab hastemplate_hook as option (and that's the one indeed, that we want to use).

    When you select it the page will update and display the callback signature. Copy this over to the function in the .php file. Which should now look like:
    public static function(callbacksignaturehere) { }

    Since we picked a function name, and found the right callback signature, your .php file should now look like this:

    Code:
    <?php
    class XenFans_Demo_Index
    {
    public static function XenfansDemo($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
    {
    // code here
    } // end function
    } // end class
    This currently is not functional, well, it works, but it's not doing anything. In the next screencast we will be look into doing something with our function so we can use a hook and get that template to show on the forums.

    Now we have an add-on, we have our own .php file. But to make them work together we need a Code Event Listener. Go back to the admin control panel, and underneath the Developmenttab is the Code Events Listeners manager. From where you can create a new one. Click the button to do so, and from the dropdown we select template_hook.

    We want to execute our callback, which is the class name. Our custom class name isXenFans_Demo_Index (see the .php file where it's easy to copy paste from) and our method is the XenfansDemo function that we created (again, easy copy paste).

    You can ignore the other settings, but what's important of course is to tell the system this is part of the add-on XenFans Demo. Select it from the list and save your Code Event Listener.

    Here's the video for screencast 2



    Screencast 3 - A case for a template hook


    What we want to do with our add-on is to take our template, inject it into an existing template by using a hook in the system. To find this hook we have to go through all the templates. But if you don't know yet how to find them specifically, you can keep it simple first and make it a guessing game.

    I want to add my template above the top breadcrumbs. So going into the Appearance tab, and selecting to show all the templates. I can filter it on 'bread' which gave me a template called ads above the top breadcrumbs (ad_above_top_breadcrumb). Awesome, especially because it had a hook there. We're going to use that hook:ad_above_top_breadcrumb

    (sidenote: in the video I said template a few times when I meant hook, sigh!)

    Every template of XenForo can have one or more hooks, you can find them by searching within a template for xen:hook (they have an open and a close tag, wrapping the hook around content)

    Back in our .php file we can now make aswitch statement to execute our code only when that $hookName (for case: ad_above_top_breadcrumb) is run in to.

    So we need
    switch (variable)
    {
    case (whichone?):
    // my code
    break;
    }

    Applying this to what we now know, our php code looks like this (within our method):

    Code:
    switch ($hookName)
    {
    case (ad_above_top_breadcrumb):
    // my code
    break;
    }
    The next step is to replace my code with something that works.
    In this case we want to populate a string with our custom template. And then prepend it to the existing $contents of XenForo.
    So for example, if $contents was already "boo" and we want to prepend it with $new , new being the content of our template, which has "test" in it. We will end up with "test boo":

    Code:
    $xenfans_demo_contents = $template->create('xenfans_demo_maintemplate', $template->getParams());
    $contents = $xenfans_demo_contents . $contents;
    I just named it our own string,$xenfans_demo_contents, and used an existing XenForo object to get our custom template's content and then replaced $contents with our string plus, what $contents already was.
    Okay, our complete .php file now looks like this:

    Code:
    <?php
    class XenFans_Demo_Index
    {
    public static function XenfansDemo($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
    {
    switch ($hookName)
    {
    case (ad_above_top_breadcrumb):
    $xenfans_demo_contents = $template->create('xenfans_demo_maintemplate', $template->getParams());
    $contents = $xenfans_demo_contents . $contents;
    break;
    } // switch
    } // end function
    } // end class
    And thank you MCE for still not doing those tabs right (boo!) You can look at the .php file in the .zip attached to this page to see full syntax highlight and indentation.

    Time to show you all this with a video, please don't get discouraged at this point!


    Screencast 4 - Multiple hooks

    An add-on doesn't have to be just a single plugin for each single customization. You can make a whole framework if you want. You can make a plugin for each customization and then use it all in a single add-on. Basically. This screencasts shows you how to use the same add-on for the same custom template, to display it at various locations. And the next screencast will show you how to add your own options to the system so you can even create choice such as 'show it in the top or the bottom'. But let's show how I would approach using multiple hooks to show a template at various locations.

    The switch statement has to be rewritten a little bit. By simply adding a second case to it. It's still the same class, the same method and we're still in the switch for that $hookName code event listener. So all we have to do is add another case, for when it's another hook (could be from the same or another template).

    You'd end up with basically this:

    Code:
    switch ($hookName)
    {
    case (ad_above_top_breadcrumb):
    $xenfans_demo_contents = $template->create('xenfans_demo_maintemplate', $template->getParams());
    $contents = $xenfans_demo_contents . $contents;
    break;
    case (ad_below_bottom_breadcrumb):
    $xenfans_demo_contents = $template->create('xenfans_demo_maintemplate', $template->getParams());
    $contents = $xenfans_demo_contents . $contents;
    break;
    } // switch


    Screencast 5 - Adding options for choice

    And we're basically done, at the end of screencast four you have a working add-on showing a custom template at some point (or multiple points) within the system. But you can do more with XenForo, as you can see a lot of features have options. You can turn things on and off, you can reposition them, you can give them a title, etc.

    Let's make our own option for our add-on. So we have choice. And we will start very simple. With a checkbox to say : yeah, show our template in the top. Or no, show it elsewhere (being in the bottom).

    In the next screencast we will tweak this checkbox by replacing it with a radio selection and add yet another choice to it.

    Go to the admin control panel, and under the Home tab click on Options. Here you can create your own Options Group. Again, I like to use my site's name as a prefix. xenfans_ and the add-on name simplified, such as demo_

    You can give it a description, I usually use this to explain the add-on or include a link to the support / download area where people can find out more about the add-on in question.

    Submit the changes, as you can basically ignore the list on the page at this point.

    You will be loaded within the options group from where you can create your new option. Do so by clicking on the Add Option button and again, giving it a prefix_addonprefix_WHAT? unique id. In this case xenfans_demo_position (I went with position because we want to determine if we're loading our custom template at the top or the bottom of the page)

    The next step is to update our .php file to get the XenForo options (so we can use it in the php code) and use an if else conditional to determine whether to load a case for one or the other hook name, effectively showing our custom template at either the top or the bottom.

    In the case of a checkbox, we're working with a boolean datatype which gives us 0 or 1, where 1 is making the checkbox checked and 0 unchecked. We will default it to 1, because my preference is to show our template at the top of the page by default.

    To get access to our options you have to add this line to the public function, before the switch:
    $options = XenForo_Application::get('options');

    We can now use $options->ourstuffhere

    And we're going to do that with the if conditional.
    if our options for the position is set to 1, do this, otherwise it's probably 0, but in any case, we want to do that instead.
    We're using the checkbox's unique id of course, xenfans_demo_position with either 1 or 0.
    if ($options->xenfans_demo_position == '1')
    {
    // it's set to checked, which means show it in the top
    }
    else
    {
    // it isn't set to checked, so we want to show it elsewhere, the bottom hook
    }

    We are going to try and be smart, and make a custom string like $xenfans_demo_case, which we will set to either 1 hook name, or the other. This way we can also extend our if else in the future if we want to add more hook names (locations).

    if (comparison)
    {
    $xenfans_demo_case = 'ad_above_top_breadcrumb'; //top
    } else {
    $xenfans_demo_case = 'ad_below_bottom_breadcrumb'; //bottom
    }

    And now we can remove the second case from the switch statement, and instead of using multiple cases we just need one. And we can use our string.

    I could do this all a bit differently, for example I could define an array, call all possible locations and map them to hook names. Or I could just be very global by not assuming I know the hook name up front. But I have chosen to show it this way, because it allows you to figure out how to do multiple cases if you have multiple templates. And you could have one especially for the sidebar, and a different one for the footer.

    Anyway, our previous php code has been transformed to this (within the method):
    [​IMG]

    Let's take a look at the screencast video hopefully to simplify this what sounds confusing process. Trust me, after a bit of practice the lightbulbs will come on.



    Screencast 6 - Changing our Options

    In the previous screencast I talked about how to create your own options, and that we'd be using a simpler on/off statement to compare against. And that we will be changing that to a more complex radio selection to include more choice. So let's go do that.

    Going back to the options' group for this add-on you can see a little tool icon on the right of the xenfans_demo_position checkbox. Clicking it allows you to edit this option within the group.

    Change it from on/off to a radio selection. And change boolean to a string.

    Instead of checked is top and unchecked is bottom, we will now determine exactly where we want something. Instead of showing say 25 individual and complex situations I will just extend it with a hook name to display our template in the sidebar as well.

    We will be using the top, bottom, and sidebar options, and set a phrase to them, so it's more user friendly to read.

    In the next screencast I will go into phrasing. Showing how to create phrases, where to find them, and how they look in the .xml file.

    For now we will be using xen: phrase phraseNameHere and focus only on our radio selection option and our php code.

    You can see in the screencast video how I create the top={xen: phrase xenfans_demo_top}.

    Once you've created one for each position find their hook names, and go to the php file to change the code.

    Our if conditional has to be changed from 1 to top, as the default. And the else has to become an else if first, for the bottom. And you can extend this for any other location you want to include. And then an else at the bottom for the last option. Such as the sidebar.

    [​IMG]

    Let's watch the video to see how I've exactly done all of this.



    Screencast 7 - Creating phrases for translation

    Sidenote: there is NO space between the : and p in {xen: phrase} but if I remove the space XenForo parses it to a smilie. (boo)

    Just to show how flexible and dynamic XenForo is (perhaps compared to some other solutions) you can tell by using custom templates, hooks and phrases. That you can create a unique board without having to touch the core files, the core templates, or the core phrases. And by using phrases you can even support multiple language boards. This screencast shows you how to use the xen: phrase feature in your add-on and templates.

    A little step back first. XenForo is quite dynamic, but it's also smart. In a normal text editor if you would type say {this:that
    And leave it at that, save it, .. nothing goes wrong.
    The internal template editor of XenForo (and at various locations where this is used) can check for the missing }. I've demonstrated this as well.

    Another step back. To execute something like xen: phrase or xen:link or some of the others, you can put curly brackets { } around it. Well, you have to, actually. xen: phrase becomes {xen: phrase} I hope that explains why it shows why I am using that, and why it goes wrong when you don't complete it.

    I wish plain text editors could error check what I wrote, beyond spell checker hehe.

    A phrase has to be unique. And again, I use my site's prefix xenfans_ and the add-on name demo_ to easily organize and identify them.

    Our options have titles and descriptions, XenForo already makes phrases for those. You can look at the .xml file after exporting the add-on to find out their names, they tend to start with options_ as a prefix.

    All the phrases are part of the Appearance. Click on that tab and click on Phrases in the left menu. You can search for and add new phrases here. We're going to focus on our add-on phrases.

    The radio selection has one for top, bottom and sidebar.
    And our custom template has the word 'test' in it.

    Edit the template first if you want, changing "test" within it to {xen: phrase xenfans_demo_test}

    Ok, back to the phrase manager. Create a new phrase, give it a unique title, such as xenfans_demo_top (etc) and type in Top, etc. Save your new phrases.

    The screencast video shows you how I've done it.



    Screencast 8 - Doing more with templates

    We can do a lot with the templates that we create. We can re-use existing templates (where logical and realistic) and we can include our other custom templates if we had any. And we can require templates such as css and js, etc.

    In XenForo you can just create a new template. Call it .css or .js at the end, and put your pure css or javascript code in there. And then require or include it in your custom template.

    This screencast video shows you how I've done that. By extending our custom template with a .css one, with a custom class. Then I require this .css template in our main template. And use the class in our paragraph to give it a border, width, align the text, etc. As a simple demo to show you what you can start doing with your templates.

    Imagine extending your add-on with custom templates you only load when it's hooking in at a certain location. But having a parent template where you can check against add-on options. And they're all using your custom .css and for example the sidebar has custom .js. It's possible to be very dynamic.



    Screencast 9 - From add-on to .zip file

    We are done! Plain and simple.

    We've created an add-on, made a .php file to use for it. And linked it all together with our code event listener so it is functional. We've created one or more custom templates, and options to include choice.

    Imagine what you can do with this simple first add-on:
    - Create a special notice during a contest in the top, with a custom design.
    - Display affiliate links in the footer.
    - Link to small banners or tutorials in the sidebar.
    - Or display basically any custom html5/css3 at any location where there's a hook available.

    At XenFans.com I've used this method to create various add-ons. From very simple to more complex ones. Such as quickly adding additional tabs to the navigation bar. A sidebar block to show promoted users. To a separate page showing popular content.

    And many others like Ragtek, AleXD, Jake Bunce, Brogan, Fuhrmann, Tikibay and Jaxel have more small to very large add-ons both free and paid. But they all start with the same principle. And these screencasts hopefully helped you turn on a few lightbulbs to get you started with customizing your board to your preferences. Without having to risk issues during upgrade, customizing existing templates and delaying updates when there were changes etc.

    It's time to export the .xml file, get the .php file, and put it in a directory. Then to .zip it up for your archive, or simply to share with others.



    Thank you for taking the time to read my explanations and instructions, feel free to comment. And thank you for watching the screencasts. I hope they were clear enough.

    Please leave a like if you thought this was helpful.



    BUT WAIT ! There is more.