III. Using NBBC

[ Previous: E. Adding Enhanced Tags | Next: G. Supporting Wiki-Links ]

F. Adding Callback Tags

There are circumstances where enhanced tags will not be capable enough to handle your needs, and for those, NBBC supports callback tags --- tags that call a function you provide to perform their validation and formatting.

So let's look at how to add a simple callback tag: Even though we can do [border] as an enhanced tag, let's look now at how to implement it as a callback tag instead.

First, you'll need to alter the rule definition. Start with the same basic definition we've used before, but use BBCODE_MODE_CALLBACK and add a 'method' parameter:

Code:
$bbcode->AddRule('border', Array( 'mode' => BBCODE_MODE_CALLBACK, 'method' => 'MyBorderFunction', 'class' => 'block', 'allow_in' => Array('listitem', 'block', 'columns'), ));

Somewhere else in your code, you'll need to provide the callback function itself, which, in this case, is named "MyBorderFunction":

Code:
function MyBorderFunction($bbcode, $action, $name, $default, $params, $content) { .... }
*
Tech Tip

NBBC uses PHP's call_user_func() function to call your function, so it doesn't need to be just a function name: If you want NBBC to call a method of an object of a particular class, you can supply an array instead of a string, like this (where $obj contains an object with a member function named "MyMethod"):

'method' => Array($obj, 'MyMethod'),

Let's look at how the callback function works. First, these are its parameters:

  • $bbcode - The BBCode object that is currently doing the parsing.
  • $action - Always one of BBCODE_CHECK or BBCODE_OUTPUT, provided to indicate why this function was called and what it should return.
  • $name - The tag name: In the [border] example, this would contain the string "border".
  • $default - The default value of the tag. If the user were to type [border=1 color=red], the default value would be "1".
  • $params - The parameters of the tag, some given by the user, some generated by NBBC, stored in an array of key => value pairs. In the example of [border=1 color=red]Hello[/border], this array might contain:
    • '_name' => 'border'
    • '_default' => '1'
    • 'color' => 'red'
    A full list of the values NBBC adds to the tag parameters is included in the Appendix.
  • $content - Only valid when $action is BBCODE_OUTPUT, this is the content (body) of the tag, already converted to valid HTML. In the example of [border=1 color=red]Hello[/border], $content would contain the string "Hello".

The callback function is called in two stages. First, after the start tag has been read by the parser, the callback function is called immediately with $action set to BBCODE_CHECK. This gives the tag the opportunity to decide whether the parameters the user provides make any sense; and this is when we would reject bad sizes and colors in our [border] example:

Code:
function MyBorderFunction($bbcode, $action, $name, $default, $params, $content) { if ($action == BBCODE_CHECK) { if (isset($params['color']) && !preg_match('/^#[0-9a-fA-F]+|[a-zA-Z]+$/', $params['color'])) return false; if (isset($params['size']) && !preg_match('/^[1-9][0-9]*$/', $params['size'])) return false; return true; } }

A call with $action == BBCODE_CHECK must return either true or false: If it returns true, NBBC will assume the tag is acceptable; if it returns false, NBBC will assume that the tag is unacceptable and will not treat it as a tag or evaluate it further.

The second time the function is called is with $action set to BBCODE_OUTPUT. If $action is BBCODE_OUTPUT, NBBC is asking the function to generate HTML from its inputs. The return value must be a string, and must contain HTML or plain text: No BBCode tags. A typical implementation for our [border] example might look like this:

Code:
function MyBorderFunction($bbcode, $action, $name, $default, $params, $content) { if ($action == BBCODE_CHECK) { if (isset($params['color']) && !preg_match('/^#[0-9a-fA-F]+|[a-zA-Z]+$/', $params['color'])) return false; if (isset($params['size']) && !preg_match('/^[1-9][0-9]*$/', $params['size'])) return false; return true; } $color = isset($params['color']) ? $params['color'] : "blue"; $size = isset($params['size']) ? $params['size'] : 1; return "<div style=\"border: {$size}px solid $color\">$content</div>"; }
*
Tech Tip

When you implement a callback function, take special care to note which parameters are validated and which parameters are not:

  • $default contains exactly what the user typed, and has not been passed through htmlspecialchars() or htmlentities() or any other cleanup function. If you output this value, you should clean it up before outputting it.
  • $params all contain exactly what the user typed, and none of them have been passed through htmlspecialchars() or htmlentities() or any other cleanup function. If you output this value, you should clean it up before outputting it.
  • $content is always pure, clean output HTML, or pure, clean output plaintext, depending on whether it's outputting in HTML or plaintext mode.
  • Your callback function's return value must always be pure, clean output HTML, or pure, clean output plaintext, depending on whether it's outputting in HTML or plaintext mode.
  • None of the input parameters to this function will contain any BBCode tags.

[ Previous: E. Adding Enhanced Tags | Next: G. Supporting Wiki-Links ]


Copyright © 2010, the Phantom Inker. All rights reserved.