Extensible BBCode
8.x-3.x-dev
|
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.
Aside from creating custom template-based tags, you can also provide tags from a module. There are two ways to do so:
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
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.