Extensible BBCode  8.x-3.x-dev
 All Classes Namespaces Files Functions Variables
Extensible BBCode Documentation

This is a BBCode parser for Drupal that can be extended with custom tag macros. If you install it on your Drupal site, it will create a text format named "BBCode" that generates HTML out of text markup such as this:

This is [b]bold[/b] and [url=http://drupal.org/]this is a link[/url].

Custom tags use the Twig template engine included in Drupal's core.

Developing

Aside from creating custom template-based tags, you can also provide tags from a module. There are two ways to do so:

  1. Define a template tag using a configuration file.
  2. Implement a full-featured tag plugin class.

Template

For most use cases, a template is sufficient. Twig templates support simple control structures that mean the tag output can be dynamic without needing PHP.

A template tag is defined in a file named config/install/xbbcode.tag.{id}.yml that must contain the following:

id: {id}
label: "An administrative label for your tag."
description: "Describes the tag's function for users (used for filter tips)."

# A default name for the tag (as in [name]...[/name]).
name: {name}

# A sample use case for the tag (for the filter tips).
sample: "[{{ name }}]...[/{{ name }}]"

It must also contain exactly one of the following:

# An inline Twig template, equivalent to a tag created through the site:
template_code: "<span>{{ tag.content }}</span>"

OR

# A template file that must be placed in "templates/xbbcode-tag-{id}.html.twig"
template_file: xbbcode-tag-{id}.html.twig

In the latter case, the template must also be registered with the theme registry by implementing hook_theme(). Since the template is only used directly, only the theme hook is required:

function {module}_theme() {
  return [
    'xbbcode_tag_{id}' => [],
  ];
}

If your tag is self-closing or "empty" (in that it consists only of an opening tag like [hr]), it must contain the following:

selfclosing: true

Optionally, you may declare attachments (such as CSS/JS libraries defined in *.libraries.yml) that will be added whenever the tag is rendered:

attached:
  # see 
  library:
    - module/library

Plugin class

A plugin class can use PHP while processing a tag, and is therefore more powerful.

BBCode tags are Annotations-based plugins. To provide one, your module needs to contain a class like this (in the appropriate PSR-4 path src/Plugin/XBBCode/).

namespace Drupalmodule}\Plugin\XBBCode;

use Drupal\xbbcode\Plugin\TagPlugin;
use Drupal\xbbcode\ElementInterface;

/**
 * @XBBCodeTag(
 *   id = "xbbcode.url",
 *   title = @Translation("Link"),
 *   description = @Translation("This creates a hyperlink."),
 *   name = "url",
 *   sample = @Translation("[{{ name }}=http://www.drupal.org/]Drupal[/{{ name }}]")
 *   attached = {
 *     "libraries" = {
 *       "module/library"
 *     }
 *   }
 * )

class YourTagPlugin extends TagPlugin {
  /**
   * {@inheritdoc}

  public function process(ElementInterface $tag) {
    return '<em>' . $tag->content() . '</em>';
  }
}

The {{ name }} placeholder is required as the tag name is configurable.

The required function TagPluginInterface::process(ElementInterface $tag) receives a tag occurrence as encountered in text, and must return HTML code.

The ElementInterface object provides the following methods:

  • content() returns the rendered content of the tag.
  • option() returns the string following "=" in the opening tag, such as [url=URL]...[/url]
  • attr($name) returns the value of a named attribute in the opening tag, such as [quote author=AUTHOR date=DATE]...[/quote]
  • source() returns the unrendered content of the tag. This can be used when your tag's content should not be rendered, such as [code]...[/code].
  • outerSource() returns the full source, including opening and closing tags. This can be returned if you want to leave the tag unrendered.