You are not logged in (Sign In)

Textformatter API

Text Formatters are filters, applied to your Entries, Comments and Custom Fields, and like Data Sources and Events, allow you to add a greater level of customisation to Symphony. They can be found in Symphony’s Text-Formatters folder under /workspace along with the data-sources and events folders.

This article will demonstrate how you can create your own BBCode Text Formatter and use it on an entry.

How Text Formatters Work in Symphony

You can choose what Text Formatter you use from your author page. Each time you create a new entry, its text is passed through that Text Formatter before reaching the database. The database holds two version of the text: the original unaltered text entered, and the text with your formatting filter applied. (This also applies to comments.)

As an Administrator, you can specify a Text Formatter for Comments from the Comment Settings page. You also have the ability to enable formatting on Custom Fields.

The API

The basic API for Text Formatters is set by its parent interface. When creating your Text Formatter, you must adhere to this interface and implement the required functions. Below is a summary of the interface:

	Class TextFormatter extends Object
		_db
		__construct($args)
		about()
		run($string)
  • _db: Private variables which are set when the constructor is called.
  • construct: Must be explicitly called from any child classes prior to running its own constructor code. This function should be overloaded by the child. $args must be a valid parent object.
  • about(): Abstract function. Must be implemented by the child.
  • run($string): Abstract function. Must be implemented by the child.

Creating A Custom Text Formatter

The best way to learn the Text Formatter API is by example. In this tutorial we will create a simple BBCode style formatter. It will automatically add line breaks, and replace square bracket notation with valid XHTML. An example of what we might produce would be:

	This is [b]a bold string[/b]
	How wonderful [i]it is[/i]

This becomes

	<p>
	This is <strong>a bold string</strong>
	<br />
	How wonderful <em>it is</em>	
	</p>

File Setup

Since this is a PHP file, you will need to wrap then entire file contents in a PHP script tag. In your file place

    <?php 
    
    ?>

You must make sure there is no whitespace before or after the <?php ?> tags. If you do it is possible that parts of your front end will fail to render correctly. Similarly, within your class, be careful about using any print() or echo statements unless you are buffering the output.

Class Declaration and File naming

Text Formatters in Symphony are called dynamically whenever they are needed. Because of this there is a strict naming scheme to ensure that the Text Formatter classes can be called reliabily.

Your class declaration needs to have “formatter” before the actual name. i.e. “formatterMarkdown”. It also needs to extend the TextFormatter class we saw eariler. So, in this instance we will have the following for our class declaration:

    Class formatterBBCode Extends TextFormatter

You need to also save the file with the correct name. In this instance it will be formatter.bbcode.php. Placing “formatter” first allows for easy identification of Text Formatter classes.

Function and Variable declarations

Based on the API discussed earlier, this is what your class skeleton will look like:

	Class formatterBBCode Extends TextFormatter{
 
		var $_patterns;
		var $_replacements;
 
		function __construct($args=array()){
 		}
 
		function about(){
 		}
 
 		function run($string){
 		}
 
	}

As you can see, there are two private variables. $_patterns and $_replacements. These will be initialized in the constructor. They will hold the BBCode tags and their replacements.

Constructor Overloading

The constructor is where we initalize variables and do other once-off things. It is also necessary to explicitly call the parent constructor. The order that this is done is important and it is advised to call parent constructor first. This is what our constructor will look like:

	function __construct($args = array()){
		parent::__construct($args);
		
		$this->_patterns = array();
		$this->_replacements = array();
 
		$this->_patterns[] = "b";
		$this->_replacements[] = "strong";
 
		$this->_patterns[] = "i";
		$this->_replacements[] = "em";
 
		$this->_patterns[] = "u";
		$this->_replacements[] = "u";
	}

As you can see, we’ve created three patterns and their replacements. [b], [i] and [u]. Any parameters passed in to the constructor are sent on to the parent constructor.

About()

The about function needs to return an associative array of details about the event. It must contain the following fields:

  • name: The name of the Text Formatter as it will appear in the comments settings and author profile select boxes.
  • author: An array holding name, email and url.
  • version: Number denoting the version of this release. Must be in the format of Major.Minor i.e 1.5
  • description: Details about the Text Formatter. This is currently unused, but will eventually.
  • release-date: Must be correctly formatted GMT date. Year-Month-Day Hour:Min:Sec i.e 2006-01-23 14:02:33

Given that guideline, our About function will look like this:

	return array(
		name => "BBCode",
		"author" => array("name" => "Alistair Kearney",
						  "website" => "http://www.pointybeard.com",
						  "email" => "alistair@pointybeard.com"),
		description => "Makes available BBCode style text formatting",
		version => "1.0",
		release-date => "2006-10-04 14:31:00"
	);

Run()

This function is where all the work is done. The string we want formatted is passed into this function, and returned formatted. Our implementation will strip all XHTML tags using PHP‘s strip_tags() function, iterate over the $_patterns array, replace any matches with the appropriate replacement string using str_replace(). It will then run the whole string through the nl2br() function.

The first part of the run() function will look like this:

    $string = strip_tags($string);
    for($ii = 0; $ii < count($this->_patterns); $ii++){
	
        ##Open Element Replacements
        $before = '[' . $this->_patterns[$ii] . ']';
        $after =  '<' . $this->_replacements[$ii] . '>';
        $string = str_replace($before, $after, $string);
 
        ##Close Element Replacements
        $before = '[/' . $this->_patterns[$ii] . ']';
        $after =  '</' . $this->_replacements[$ii] . '>';
        $string = str_replace($before, $after, $string);
    }


Each item in the $_patterns is iterated over, and open and close element tags are set up ($before and $after). These are then used by the str_replace() function to alter the input string.

Once this is done we need to then add the line breaks, add the wrapping <p></p> element and then return the result to the caller.

    $string = nl2br($string);
    $string = "<p>" . $string . "</p>";
    return $string;


Final Code

	<?php
 
	Class formatterBBCode Extends TextFormatter{
 
		var $_patterns;
		var $_replacements;
 
		function __construct($args = array()){
			parent::__construct($args);
		
			$this->_patterns = array();
			$this->_replacements = array();
	
			$this->_patterns[] = "b";
			$this->_replacements[] = "strong";
 
			$this->_patterns[] = "i";
			$this->_replacements[] = "em";
 
			$this->_patterns[] = "u";
			$this->_replacements[] = "u";
 		}
 
		function about(){
 
			return array(
				name => "BBCode",
				"author" => array("name" => "Alistair Kearney",
						          "website" => "http://www.pointybeard.com",
						          "email" => "alistair@pointybeard.com"),
				description => "Makes available BBCode style text formatting",
				version => "1.0",
				release-date => "2006-10-04 14:31:00"
			);
 		}
 
 		function run($string){
 
			$string = strip_tags($string);
 
			for($ii = 0; $ii < count($this->_patterns); $ii++){
		
				##Open Element Replacements
				$before = "[" . $this->_patterns[$ii] . "]";
				$after =  "<" . $this->_replacements[$ii] . ">";
				$string = str_replace($before, $after, $string);
 
				##Close Element Replacements
				$before = "[/" . $this->_patterns[$ii] . "]";
				$after =  "</" . $this->_replacements[$ii] . ">";
				$string = str_replace($before, $after, $string);
			}
 
 			$string = nl2br($string);
			$string = "<p>" . $string . "</p>";
			return $string;		
		}
 
	}
 
	?>

Testing

To begin with we will check the syntax of the class. If the syntax is incorrect, than the author profile and comment settings page will fail to display.

To test the file, place it into your /workspace/text-formatters folder. Then browse to the file (i.e. http://yoursite.com/workspace/text-formatters/formatter.bbcode.php). If there are problems with the file you will see error messages and you need to correct the errors on the line they are associated with. Note: The following error is OK, and means you have no Syntax errors:

    Fatal error: Class 'TextFormatter' not found in /workspace/text-formatters/formatter.bbcode.php on line 3

Once you get an error message similar to the one above, meaning there are no syntax errors, you can proceed to your author profile page and set the text formatter you are using to BBCode. Create a new entry and use some of the BBCode tags. Than check it looks ok on your front end.

Improvements

To keep this article simple and avoid too much confusion, several things were left out of our final solution which would make it much more complete. Instead of using nl2br() to add line breaks, try correctly identifying paragraphs and wrapping them in <p></p> elements. You should make use of preg_replace().

 
You are not logged in
developer-resources/text-formatters.txt · Last modified: 2007/03/22 21:05 by alistair