1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Custom BB Code

Discussion in 'XenForo Development Discussions' started by v8td, Apr 1, 2016.

  1. v8td

    v8td Member

    Hi!

    Where i can define the new class and function for PHP Callback?

    Please explain me this help line:
    "This callback will receive these parameters: array $tag, array $rendererStates, XenForo_BbCode_Formatter_Base $formatter."

    - $tag = is the tag of the custom bb code? ... So i can define a generic "handler" class, and function where i use if..else if like: ... if($tag == "myPhoto"){//php code}... else if($tag == "myTable"){//php code}) ?

    I must echo the $result, or just use return $result from function?

    - what is $redererStates and $formatter?

    - how to pass parameters? As json?
    - can i define as many params as i need?

    Some example for a more complicated custom bb code?

    I hope i posted this question in right place.
     
  2. Chris D

    Chris D XenForo Developer Staff Member

    Directing you is difficult without knowing exactly what you wish to achieve.

    I'll start from the beginning - you first need to create a file. The class name convention matches the directory structure in XF, so for example, this class:
    XenForo_ControllerPublic_Forum

    Can be located here:
    library/XenForo/ControllerPublic/Forum.php

    With that in mind, you can add your files anywhere within the library directory, let's assume you want your BB Code class to be located in:
    library/MyAddOn/BbCode/MyPhoto.php

    The class name would be:
    MyAddOn_BbCode_MyPhoto

    The function can be named whatever you like so something like this:
    PHP:
    <?php

    class MyAddOn_BbCode_MyPhoto
    {
        public static function 
    whatever(array $tag, array $rendererStatesXenForo_BbCode_Formatter_Base $formatter)
        {

        }
    }
    For this, you'd enter the PHP Callback as:
    MyAddOn_BbCode_MyPhoto :: whatever

    $tag is an array of details about the tag which has been used, so for example if someone uses:
    [MYBBCODE=red]Some text[/MYBBCODE]

    The $tag array will contain something like this (as an array):
    Code:
    array(4) {
      ["tag"] => string(7) "mybbcode"
      ["option"] => string(10) "red"
      ["original"] => array(2) {
        [0] => string(20) "[MYBBCODE=red]"
        [1] => string(10) "[/MYBBCODE]"
      }
      ["children"] => array(1) {
        [0] => string(54) "Some text"
      }
    }
    The ultimate objective is for the function to return the HTML to be rendered inside the post.

    So if I did this:
    PHP:
    <?php

    class MyAddOn_BbCode_MyPhoto
    {
        public static function 
    whatever(array $tag, array $rendererStatesXenForo_BbCode_Formatter_Base $formatter)
        {
            return 
    '<span style="color: ' $option ';">' $children[0] . '</span>';
        }
    }
    Then the HTML returned would be:
    HTML:
    <span style="color: red;">Some text</span>
    Which would look something like:
    Some text

    There's a lot more you can do here.

    The third argument is the $formatter object. This ultimately gives you access to things like the View so you can render templates:

    PHP:
    $view $formatter->getView();
    if (
    $view)
    {
       
    $template $view->createTemplateObject('whatever_template_name', array('whateverParam' => 'whateverValue'));
       return 
    $template->render();
    }
    That would output a template named "whatever_template_name" and there would be a variable named {$whateverParam} in there with a value of 'whateverValue'.

    Hopefully that gives you a general idea of how it works. If you need any more advice, post what you're trying to achieve exactly and I'm sure someone can help.
     
    v8td likes this.
  3. v8td

    v8td Member

    Thank you!! I get it!
    That's all i needed... At least for now :)
    I will try a sample...

    Oh... wait,
    I need a CSS library in header. I'm sure i can use some object to add a CSS file request in header.

    So the class constructor has to declare a global variable, or something, to specify the css file in header...

    Finally i can start with my custom bb code (y)
     
  4. Chris D

    Chris D XenForo Developer Staff Member

    If you return a template object, that can use xen:require (like most default templates) to call and place CSS in the header.
     
    Last edited: Apr 1, 2016
    v8td likes this.
  5. v8td

    v8td Member

    I don't know the 'events' order when xenforo (or zend framework itself) is rendering the page. This bb codes are parsed when the thread body is rendered, for each thread post. The time this 'hook' is 'firing', the header template was loaded, variable replaced and i don't see how i can insert CSS in header, unless i 'hook' to header render 'event'.
    Sorry for this 'forced' comparison. I did some prestashop modules, and using phpBB... Before rewriting code i used in phpBB i switch to xenforo... and will with other forum i have...

    If you can explain or give link to existent thread, your help will be much appreciated :)

    LE: Unles the whole page is rendered only at the end of all templates parse.
    For template parsing i used phpBB model and smarty in prestashop.
    I guess xenforo has it's on sintax as i saw in files.

    Where is the template files in folders? I found them in admin interface but a quick search in folder doesn't revelead any htmls... Are stored in DB?
     
    Last edited: Apr 1, 2016
  6. Chris D

    Chris D XenForo Developer Staff Member

    Yes, they're all stored in the database and editable via the Admin CP.

    Ultimately the best thing to do is what I suggested here:
    In this example you would create a template in the Admin CP named whatever_template_name, and the array is an array of variables you want to be available to use in the template.

    The template is able to specify the location of any CSS that should be included, and it is automatically included in the header on page load (it's also smart enough to only include the CSS once even if you call it 20 times).

    CSS is also part of the template system (CSS templates are suffixed with .css).

    You would create a CSS template (in the same way as the whatever_template_name template was created) and add all your CSS in there.

    Then your template would look something like this:
    HTML:
    <xen:require css="whatever_template_name.css" />
    
    My variable is {$whateverParam}
     
    v8td likes this.
  7. v8td

    v8td Member

    ["children"] is an array. How can i separate parameters, and i receive ["children"][0], ["children"][1] ...
    If it's not possible, i will parse myself by a simple explode by ","... but i want to know :)
     
  8. Chris D

    Chris D XenForo Developer Staff Member

    "children" is generally going to be what is inside the BB code tags, e.g. the content the user has generated.

    If you're referring to the BB code option, e.g. the "option" text inside the opening tag
    [MYBBCODE=option]

    Then that is in the "option" key of the $tag array. That will always be a string. If you need to split it you would need to do that with explode as you have suggested.
     
    v8td likes this.
  9. v8td

    v8td Member

    In this example, ["children"] is a "child" as array, and indeed i get "param1,param2" as a string for first element of ["children"], more precisely the string beween tags.
    I don't use option like [tag=OPTION][/tag]....

    I use in this form: [tag]param1,param2[/tag], and i thought that i can directly separate params, as the "child" is an array... array in array. And maybe i can use directly ["children"][0], ["children"][1]

    "param1,param2" is the string stored in ["children"][0]...

    I hope i make myself clear, cause my english is "as it is"...
     
  10. Chris D

    Chris D XenForo Developer Staff Member

    Subsequent children is a bit of a special use case used for things like nested tags.

    For your use case you would need to split that manually.
     
    v8td likes this.
  11. v8td

    v8td Member

    I see now that these custom bb codes does not appear in reply editor. First, i thought "how can i hide special bbcodes" even from registered users. I want some custom bb codes to be available only for administrators / moderators... Is there a dropdown combo with these? I can't find any option in basic or advanced options for a bb code that says "show this in editor"...
     
  12. cclaerhout

    cclaerhout Well-Known Member

  13. Chris D

    Chris D XenForo Developer Staff Member

    There is an option to display custom bb codes in the editor but if you need more advanced features then the above add on may be required.
     
    v8td likes this.
  14. v8td

    v8td Member

    My custom bb code with php callback works perfectly (including parameters). The returned HTML is just as i want... Now, for a quick test, can i edit the header template (overall) to check if the inclusion of CSS and JS library will make my photo gallery works as expected?

    All i have in header is:
    Code:
    <xen:edithint template="header.css" />
    
    <xen:hook name="header">
    <div id="header">
        <xen:include template="logo_block" />
        <xen:include template="navigation" />
        <xen:if is="{$canSearch}"><xen:include template="search_bar" /></xen:if>
    </div>
    </xen:hook>
    Maybe i have to edit another template...

    LE: i see this file included:
    Code:
    <script src="js/jquery/jquery-1.11.0.min.js"></script>
    That's perfect, cause is one of dependecies for what i want. Now, a small JS and CSS...


    LE: Maybe this is similar question: https://xenforo.com/community/threads/add-new-css-template.16052/

    Yes... PAGE CONTAINER :)
     
    Last edited: Apr 1, 2016
  15. v8td

    v8td Member

    It's working! Done!
    Thanks for support!
     
  16. v8td

    v8td Member

    Questions about all this "task"....
    - It is possible to encapsulate all changes i made into an addon? The only problem i see... is that maybe i can't programmatically add the new bb code and set class and function. The way bb codes with callback function work in xenforo eliminated my own post parsing function...
    - PAGE_CONTAINER is marked with red color. There is a very usefull button "Revert template", but my question is about updateing xenforo core files, on a new version. Will my changes be overwritten?
     
  17. Chris D

    Chris D XenForo Developer Staff Member

    It is possible to assign custom BB codes to an add-on. You need to enable debug mode to do this:
    https://xenforo.com/community/threads/frequently-asked-questions.5183/#post-248490

    Be careful if you enable debug mode. It will enable access to the master style and language. Changes to the master style and language cannot easily be reversed and those changes will be overwritten during upgrade.

    However, as long as you only edit the "Default Style" (or another child of the Master Style) as you have seen, those changes can be reverted, but also those changes will not be affected by upgrades. If there is a conflict between a template we've changed during an upgrade and a template you have changed, then the template is marked as "Outdated". When this happens, you can use the comparison and merge tool to merge your changes back into the updated template.

    In terms of making template changes, it's best to use the Template Modifications system to do this. This is effectively a find and replace style system for template changes that can be assigned to add-ons.
     
  18. v8td

    v8td Member

    Chris,
    can i reffer in my class function to the user object? I need to know user type... Registered or visitor...

    I want to define another custom bbcode thath will display "You must be registered to see this photo gallery".

    Thanks!
     
  19. Chris D

    Chris D XenForo Developer Staff Member

    XenForo_Visitor::getInstance()
     
  20. v8td

    v8td Member

    It's ok to put another files in library/<class_folder>/... ? like js and css... but even common.php wich is my functions collection....?
    I think it's not against "best practices", right?

    LE: "You don't have permission to access /library/..."
     
    Last edited: Apr 2, 2016

Share This Page