Adding WordPress like shortcodes to your web applications

One of the cool features of WordPress is its shortcode feature. There may be times one wished to add this capability to your PHP web applications. Recently I found one such library which allows you to add shortcode features to your web apps. The library discussed here implements WordPress style shortcode syntax as a standalone package. Its a small package and so can be easily integrated into you existing applications. Content from editors, databases, etc. can be scanned by the Shortcode Manager and the contents replaced by a custom callback.

Installation

The library requires at least PHP version 5.4. The package is installed using composer, with the following added to you ‘composer.json’ file,or you can download the zip package from github.

"require": {
  "maiorano84/shortcodes": "~1.0"
}

The shortcode library comes with everything you need for defining your own custom shortcodes and their respective callbacks. To define a custom Shortcode programatically, you can use the SimpleShortcode class provided.

Usage

The anatomy of a shortcode is as follows. You can design any one of the following using the classes provided.

[tag] - No content, no attributes
[tag]Content[/tag] - Tag with content
[tag atribute=value] - Tag with attributes
[tag atribute=value]Content[/tag] - Tag with content and attributes

Let us start with creating a custom shortcode to add a dollar ($) sign to a amount given in a shortcode. So for example when a shortcode is encountered like below:

The price for the product is [currency]550.00[/currency].

It should be replaced by:

The price for the product is $550.00.

The complete code for the shortcode registration and usage is given below.

<?php
 
require 'vendor/autoload.php';
 
use Maiorano\Shortcodes\Manager\ShortcodeManager;
use Maiorano\Shortcodes\Library\SimpleShortcode;
 
/* Instantiate the Shortcode Manager */
$manager = new ShortcodeManager;
 
/* Shortcode name */
$shortcode_name = 'currency';
 
/* Create your shortcode */
$currencySC = new SimpleShortcode($shortcode_name,
                                  null,
                                  function($content = null)
                                  {
                    return '$'.$content;
});
 
/* Register our new shortcode */
$manager->register($currencySC);
 
/* Now use it */
$text = 'The price for the product is [currency]550.00[/currency].';
$out = $manager->doShortcode($text);
echo $out;
//The price for the product is $550.00.

The main function in the above example is ‘SimpleShortCode’, the function signature is shown below.

function SimpleShortCode($name, $atts = [], Callable $callback = null)

We can also write it another way, directly passing the shortcode generating code to the ‘ShortcodeManager’ method as a array element. Although I think this looks a little complex and will probably prone to bugs when adding more shortcodes.

<?php
 
require 'vendor/autoload.php';
 
use Maiorano\Shortcodes\Manager\ShortcodeManager;
use Maiorano\Shortcodes\Library\SimpleShortcode;
 
/* Instantiate the Shortcode Manager */
$manager = new ShortcodeManager(array(
        'currency' => new SimpleShortcode('currency',
                                      null,
                                      function($content = null)
                                      {
                        return '$'.$content;
        })
    ));
 
 
/* Now use it */
$text = 'The price for the product is [currency]550.00[/currency].';
$out = $manager->doShortcode($text);
echo $out;
//The price for the product is $550.00.

In our example the second attributes parameter was ‘null’, however we can pass various attributes along with the shortcode for further customization, as will be shown in the next example.

Adding Attributes

Say we want to add a ‘bold’ attribute to the ‘currency’ shortcode above, which makes the currency string bold. We can accomplish that with the following.

<?php
 
require 'vendor/autoload.php';
 
use Maiorano\Shortcodes\Manager\ShortcodeManager;
use Maiorano\Shortcodes\Library\SimpleShortcode;
 
/* Instantiate the Shortcode Manager */
$manager = new ShortcodeManager;
 
/* Shortcode name */
$shortcode_name = 'currency';
 
/* Create your shortcode */
$currencySC = new SimpleShortcode($shortcode_name,
                                  array('style'=>'normal'),
                                  function($content = null, array $atts=[])
                                  {
                    if($atts['style'] == 'bold') {
                        return '<b>$'.$content.'</b>'; 
                    } else {
                        return '$'.$content;
                    }
});
 
/* Register our new shortcode */
$manager->register($currencySC);
 
/* Pass a style attribute with the shortcode */
$text = 'The price for the product is [currency style=bold]550.00[/currency].';
 
/* Now use it */
$out = $manager->doShortcode($text);
echo $out;

The default style for the shortcode is ‘normal’, so when no additional attributes are passed to the shortcode the curreny string will be displayed normally. However when we add a ‘bold’ attribute to the shortcode the output string will be rendered bold.

[currency style=bold]550.00[/currency]

You can add as many attributes as you may wish to the shortcode.

Building a separate class

Rather than registering a shortcode randomly in any place it is better if we create a custom class for our shortcode. An example class for our ‘currency’ shortcode is given below. Copy the file to the ‘library’ sub-directory of the shortcode package.

<?php
/* Currency.php */
namespace Maiorano\Shortcodes\Library;
use Maiorano\Shortcodes\Contracts;
 
/**
 * Generate Currency symbols
 * @package Maiorano\Shortcodes\Library
 */
class Currency implements Contracts\ShortcodeInterface, Contracts\AttributeInterface
{
    use Contracts\ShortcodeTrait, Contracts\AttributeTrait;
 
    /**
     * @var string
     */
    protected $name = 'currency';
 
    /**
     * @var array
     */
    protected $attributes = array('style'=>'normal');
 
    /**
     * @param string|null $content
     * @param array $atts
     * @return string
     */
    public function handle($content = null, array $atts=[])
    {
        if($atts['style'] == 'bold') {
            return '<b>$'.$content.'</b>'; 
        } else {
            return '$'.$content;
        }
    }
}

Now we can use the ‘currency’ shortcode defined in the class in our code anywhere as shown below.

<?php
 
require 'vendor/autoload.php';
 
use Maiorano\Shortcodes\Manager\ShortcodeManager;
use Maiorano\Shortcodes\Library;
 
/* Instantiate the Shortcode Manager */
$manager = new ShortcodeManager(array(
    'currency' => new Library\Currency)
);
 
/* Pass a style attribute with the shortcode */
$text = 'The price for the product is [currency style=bold]550.00[/currency].';
 
$out = $manager->doShortcode($text);
echo $out;

Nested shortcodes

In most cases, the SimpleShortcode class will be sufficient in covering your app’s needs. However, some cases may require quite a bit more functionality that the SimpleShortcode class just hasn’t thought of. One fairly common scenario you might run into is the need for Nested Shortcodes:

[foo][bar/][/foo]

To see a pragmatic application we will add another simple shortcode that displays just a exclamation mark (!) after the content. The code is shown below.

$foo = new SimpleShortcode('foo',
                                  null,
                                  function($content = null)
                                  {
                    return $content." !";
});

The complete code is given below.

<?php
 
require 'vendor/autoload.php';
 
use Maiorano\Shortcodes\Manager\ShortcodeManager;
use Maiorano\Shortcodes\Library\SimpleShortcode;
 
/* Instantiate the Shortcode Manager */
$manager = new ShortcodeManager;
 
/* Shortcode name */
$shortcode_name = 'currency';
 
/* Create your shortcode */
$currencySC = new SimpleShortcode($shortcode_name,
                                  array('style'=>'normal'),
                                  function($content = null, array $atts=[])
                                  {
                    if($atts['style'] == 'bold') {
                        return '<b>$'.$content.'</b>'; 
                    } else {
                        return '$'.$content;
                    }
});
 
/* Create another shortcode */
$foo = new SimpleShortcode('foo',
                                  null,
                                  function($content = null)
                                  {
                    return $content." !";
});
 
/* Register our new shortcode */
$manager->register($currencySC);
$manager->register($foo);
 
/* Pass a style attribute with the shortcode */
$text = 'The price for the product is [currency style=bold]550.00 [foo/][/currency].';
 
/* Now use it */
$out = $manager->doShortcode($text, null, true);
echo $out; // The price for the product is $550.00 !.

There is an optional third parameter that you can set within ‘doShortcode’, which will trigger the manager to run recursively over all defined tags until everything has been processed. This is essential to make sure nested shortcodes are processed.

Shortcodes allows you to add some nice functionality to your web apps. You have already seen the power and flexibility offered by WordPress shortcodes, now the same is available to you for using with other web apps.



One thought on “Adding WordPress like shortcodes to your web applications

  1. Very nice article!

    As an added note, the second parameter within doShortcode allows you to specify which tags should be rendered within a given set. This can either be an array of registered tags, or a pipe-delimited string. So if there’s a particular block of text you’re rendering, you can optionally decide if you want only a particular set of tags to be available within that instance.

    Additionally, SimpleShortcode makes use of the ContainerAware Interface. This allows the shortcode to perform manager-specific methods on itself (eg: doShortcode) by leveraging the container on which it was registered. This shouldn’t be necessary in most cases, but if a custom shortcode requires knowledge of its corresponding manager, you can use this interface alongside the ContainerAware Trait to bootstrap this capability into your own custom shortcodes.

Comments are closed.