A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/thunderer/Shortcode below:

thunderer/Shortcode: Advanced shortcode (BBCode) parser and engine for PHP

Shortcode is a framework agnostic PHP library allowing to find, extract and process text fragments called "shortcodes" or "BBCodes". Examples of their usual syntax and usage are shown below:

[user-profile /]
[image width=600]
[link href="http://google.pl" color=red]
[quote="Thunderer"]This is a quote.[/quote]
[text color="red"]This is a text.[/text]

The library is divided into several parts, each of them containing logic responsible for different stages and ways of processing data:

Each part is described in the dedicated section in this document.

There are no required dependencies and all PHP versions from 5.3 up to latest 8.x are tested and supported. This library is available on Composer/Packagist as thunderer/shortcode, to install it execute:

composer require thunderer/shortcode=^0.7

or manually update your composer.json with:

(...)
"require": {
    "thunderer/shortcode": "^0.7"
}
(...)

and run composer install or composer update afterwards. If you're not using Composer, download sources from GitHub and load them as required. But really, please use Composer.

To ease usage of this library there is a class ShortcodeFacade configured for most common needs. It contains shortcut methods for all features described in the sections below:

Shortcodes are processed using Processor which requires a parser and handlers. The example below shows how to implement an example that greets the person with name passed as an argument:

use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Parser\RegularParser;
use Thunder\Shortcode\Processor\Processor;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;

$handlers = new HandlerContainer();
$handlers->add('hello', function(ShortcodeInterface $s) {
    return sprintf('Hello, %s!', $s->getParameter('name'));
});
$processor = new Processor(new RegularParser(), $handlers);

$text = '
    <div class="user">[hello name="Thomas"]</div>
    <p>Your shortcodes are very good, keep it up!</p>
    <div class="user">[hello name="Peter"]</div>
';
echo $processor->process($text);

Facade example:

use Thunder\Shortcode\ShortcodeFacade;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;

$facade = new ShortcodeFacade();
$facade->addHandler('hello', function(ShortcodeInterface $s) {
    return sprintf('Hello, %s!', $s->getParameter('name'));
});

$text = '
    <div class="user">[hello name="Thomas"]</div>
    <p>Your shortcodes are very good, keep it up!</p>
    <div class="user">[hello name="Peter"]</div>
';
echo $facade->process($text);

Both result in:

    <div class="user">Hello, Thomas!</div>
    <p>Your shortcodes are very good, keep it up!</p>
    <div class="user">Hello, Peter!</div>

Processor has several configuration options available as with*() methods which return the new, changed instance to keep the object immutable.

If processor was configured with events container there are several possibilities to alter the way shortcodes are processed:

There are several ready to use event handlers in the Thunder\Shortcode\EventHandler namespace:

The example below shows how to manually implement a [raw] shortcode that returns its verbatim content without calling any handler for nested shortcodes:

use Thunder\Shortcode\Event\FilterShortcodesEvent;
use Thunder\Shortcode\EventContainer\EventContainer;
use Thunder\Shortcode\Events;
use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Parser\RegularParser;
use Thunder\Shortcode\Processor\Processor;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;

$handlers = new HandlerContainer();
$handlers->add('raw', function(ShortcodeInterface $s) { return $s->getContent(); });
$handlers->add('n', function(ShortcodeInterface $s) { return $s->getName(); });
$handlers->add('c', function(ShortcodeInterface $s) { return $s->getContent(); });

$events = new EventContainer();
$events->addListener(Events::FILTER_SHORTCODES, function(FilterShortcodesEvent $event) {
    $parent = $event->getParent();
    if($parent && ($parent->getName() === 'raw' || $parent->hasAncestor('raw'))) {
        $event->setShortcodes(array());
    }
});

$processor = new Processor(new RegularParser(), $handlers);
$processor = $processor->withEventContainer($events);

assert(' [n /] [c]cnt[/c] ' === $processor->process('[raw] [n /] [c]cnt[/c] [/raw]'));
assert('n true  [n /] ' === $processor->process('[n /] [c]true[/c] [raw] [n /] [/raw]'));

Facade example:

use Thunder\Shortcode\Event\FilterShortcodesEvent;
use Thunder\Shortcode\Events;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
use Thunder\Shortcode\ShortcodeFacade;

$facade = new ShortcodeFacade();
$facade->addHandler('raw', function(ShortcodeInterface $s) { return $s->getContent(); });
$facade->addHandler('n', function(ShortcodeInterface $s) { return $s->getName(); });
$facade->addHandler('c', function(ShortcodeInterface $s) { return $s->getContent(); });

$facade->addEventHandler(Events::FILTER_SHORTCODES, function(FilterShortcodesEvent $event) {
    $parent = $event->getParent();
    if($parent && ($parent->getName() === 'raw' || $parent->hasAncestor('raw'))) {
        $event->setShortcodes(array());
    }
});

assert(' [n /] [c]cnt[/c] ' === $facade->process('[raw] [n /] [c]cnt[/c] [/raw]'));
assert('n true  [n /] ' === $facade->process('[n /] [c]true[/c] [raw] [n /] [/raw]'));

This section discusses available shortcode parsers. Regardless of the parser that you will choose, remember that:

There are three included parsers in this library:

All parsers (except WordpressParser) support configurable shortcode syntax which can be configured by passing SyntaxInterface object as the first parameter. There is a convenience class CommonSyntax that contains default syntax. Usage is shown in the examples below:

use Thunder\Shortcode\HandlerContainer\HandlerContainer;
use Thunder\Shortcode\Parser\RegexParser;
use Thunder\Shortcode\Parser\RegularParser;
use Thunder\Shortcode\Processor\Processor;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;
use Thunder\Shortcode\Syntax\CommonSyntax;
use Thunder\Shortcode\Syntax\Syntax;
use Thunder\Shortcode\Syntax\SyntaxBuilder;

$builder = new SyntaxBuilder();

Default syntax (called "common" in this library):

$defaultSyntax = new Syntax(); // without any arguments it defaults to common syntax
$defaultSyntax = new CommonSyntax(); // convenience class
$defaultSyntax = new Syntax('[', ']', '/', '=', '"'); // created explicitly
$defaultSyntax = $builder->getSyntax(); // builder defaults to common syntax

Syntax with doubled tokens:

$doubleSyntax = new Syntax('[[', ']]', '//', '==', '""');
$doubleSyntax = $builder // actually using builder
    ->setOpeningTag('[[')
    ->setClosingTag(']]')
    ->setClosingTagMarker('//')
    ->setParameterValueSeparator('==')
    ->setParameterValueDelimiter('""')
    ->getSyntax();

Something entirely different just to show the possibilities:

$differentSyntax = new Syntax('@', '#', '!', '&', '~');

Verify that each syntax works properly:

$handlers = new HandlerContainer();
$handlers->add('up', function(ShortcodeInterface $s) {
    return strtoupper($s->getContent());
});

$defaultRegex = new Processor(new RegexParser($defaultSyntax), $handlers);
$doubleRegex = new Processor(new RegexParser($doubleSyntax), $handlers);
$differentRegular = new Processor(new RegularParser($differentSyntax), $handlers);

assert('a STRING z' === $defaultRegex->process('a [up]string[/up] z'));
assert('a STRING z' === $doubleRegex->process('a [[up]]string[[//up]] z'));
assert('a STRING z' === $differentRegular->process('a @up#string@!up# z'));

This library supports several (un)serialization formats - XML, YAML, JSON and Text. Examples below shows how to both serialize and unserialize the same shortcode in each format:

use Thunder\Shortcode\Serializer\JsonSerializer;
use Thunder\Shortcode\Serializer\TextSerializer;
use Thunder\Shortcode\Serializer\XmlSerializer;
use Thunder\Shortcode\Serializer\YamlSerializer;
use Thunder\Shortcode\Shortcode\Shortcode;

$shortcode = new Shortcode('quote', array('name' => 'Thomas'), 'This is a quote!');

Text:

$text = '[quote name=Thomas]This is a quote![/quote]';
$textSerializer = new TextSerializer();

$serializedText = $textSerializer->serialize($shortcode);
assert($text === $serializedText);
$unserializedFromText = $textSerializer->unserialize($serializedText);
assert($unserializedFromText->getName() === $shortcode->getName());

JSON:

$json = '{"name":"quote","parameters":{"name":"Thomas"},"content":"This is a quote!","bbCode":null}';
$jsonSerializer = new JsonSerializer();
$serializedJson = $jsonSerializer->serialize($shortcode);
assert($json === $serializedJson);
$unserializedFromJson = $jsonSerializer->unserialize($serializedJson);
assert($unserializedFromJson->getName() === $shortcode->getName());

YAML:

$yaml = "name: quote
parameters:
    name: Thomas
content: 'This is a quote!'
bbCode: null
";
$yamlSerializer = new YamlSerializer();
$serializedYaml = $yamlSerializer->serialize($shortcode);
assert($yaml === $serializedYaml);
$unserializedFromYaml = $yamlSerializer->unserialize($serializedYaml);
assert($unserializedFromYaml->getName() === $shortcode->getName());

XML:

$xml = '<?xml version="1.0" encoding="UTF-8"?>
<shortcode name="quote">
  <bbCode/>
  <parameters>
    <parameter name="name"><![CDATA[Thomas]]></parameter>
  </parameters>
  <content><![CDATA[This is a quote!]]></content>
</shortcode>
';
$xmlSerializer = new XmlSerializer();
$serializedXml = $xmlSerializer->serialize($shortcode);
assert($xml === $serializedXml);
$unserializedFromXml = $xmlSerializer->unserialize($serializedXml);
assert($unserializedFromXml->getName() === $shortcode->getName());

Facade also supports serialization in all available formats:

use Thunder\Shortcode\Shortcode\Shortcode;
use Thunder\Shortcode\ShortcodeFacade;

$facade = new ShortcodeFacade();

$shortcode = new Shortcode('name', array('arg' => 'val'), 'content', 'bbCode');

$text = $facade->serialize($shortcode, 'text');
$textShortcode = $facade->unserialize($text, 'text');
assert($shortcode->getName() === $textShortcode->getName());

$json = $facade->serialize($shortcode, 'json');
$jsonShortcode = $facade->unserialize($json, 'json');
assert($shortcode->getName() === $jsonShortcode->getName());

$yaml = $facade->serialize($shortcode, 'yaml');
$yamlShortcode = $facade->unserialize($yaml, 'yaml');
assert($shortcode->getName() === $yamlShortcode->getName());

$xml = $facade->serialize($shortcode, 'xml');
$xmlShortcode = $facade->unserialize($xml, 'xml');
assert($shortcode->getName() === $xmlShortcode->getName());

There are several builtin shortcode handlers available in Thunder\Shortcode\Handler namespace. Description below assumes that given handler was registered with xyz name:

Want to contribute? Perfect! Submit an issue or Pull Request and explain what would you like to see in this library.

See LICENSE file in the main directory of this library.


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4