Craft CMS 3 shortcode plugin
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

Craft CMS Shortcodes

For Craft CMS 3

The Craft 2 version is still available here.


Easily map WordPress style shortcodes to custom templates or PHP class handlers. Use the provided Twig filter, shortcodes (or sc), to parse shortcodes in field content.

This plugin is a simple wrapper for the thunderer/shortcode PHP package.


composer require samhernandez/craft-shortcodes


Add a file to the /config directory named shortcodes.php. That file should return an array that maps shortcode tags to templates that you create to handle each shortcode.

Config file: /config/shortcodes.php

return [
    'map' => [
        'video' => '_shortcodes/video.twig',
        // ...

Now, any [video] shortcodes will now load your custom handler template.

Twig Filter

Add the twig filter, shortcodes, to any field that might contain shortcodes.

<div>{{ entry.legacyContent | shortcodes }}</div>

There is a short alias, sc, if you prefer it.

<div>{{ entry.legacyContent | sc }}</div>

Template Handlers

This section is probably all you need to skim unless you’re looking to handle shortcodes with PHP rather than Twig. If so, jump to the next section.

As mentioned, this plugin is a simple wrapper for the thunderer/Shortcode PHP package. With that in mind, a Twig variable, shortcode is available in your mapped shortcode templates.

(If you’re curious, it’s an instance of ParsedShortcode, but the most useful methods are on the AbstractShortcode class.)

The matched element for the current route (e.g. entry, category, etc.) is also available in the shortcode template just in case it’s helpful.

Useful shortcode Methods


Gets the textual content between the opening and closing shortcode tags.

If the shortcode signature looks like this:

    Some text.


shortcode.getContent() | trim == 'Some text.'

Without the trim filter it would include outer line breaks and whitespace.


If the shortcode signature looks like this:

[myshortcode param="value"]


shortcode.getName() == 'myshortcode'


If the shortcode signature looks like this:

[img src="/image.jpg"]


shortcode.getParameter('src') == '/image.jpg'

A default value can be provided as the second argument:

shortcode.getParameter('width', 300) == 300

The width parameter is not on the shortcode tag, so it defaults to 300.


Retrieve an unnamed parameter by its zero-index position.

If the shortcode signature looks like this:



shortcode.getParameterAt(0) == ''


Retrieves all of the parameters as key/value pairs. Unnamed parameters will be keys rather than values.

If the shortcode signature looks like this:

[embed width=300]


shortcode.getParameters(0) == {
    "": null,
    "width": 300


Returns true if there is textual content between the opening and closing tags.


Returns true if the shortcode tag has given parameter key.


Returns true if the shortcode has any parameters at all.

Template Example

We’ll create a simple, contrived video shortcode handler; just enough to steer you in the right direction.

Assuming your config file (/config/shortcodes.php) looks like this:

return [
    'map' => [
        'video' => '_shortcodes/video.twig',
        // ...

Create a template: templates/_shortcodes/video.twig

  Shortcode signature: [video mp4="video.mp4" webm="video.webm"]

{% set mp4 = shortcode.getParameter('mp4') %}
{% set webm = shortcode.getParameter('webm') %}

<video controls>
  {% if mp4 %}<source src="{{ mp4 }}" type="video/mp4">{% endif %}
  {% if webm %}<source src="{{ webm }}" type="video/webm">{% endif %}

This Twig example is demonstrated as PHP in the next section.

PHP Class Handlers

To handle shortcodes with PHP, create a callable class and add it as a handler in the configuration file.

Callable Class Example

We’ll create a simple, contrived video shortcode handler; just enough to steer you in the right direction. We’ll enable the example module that ships with Craft and drop a shortcode handler in there.

Enable the module in /config/app.php by uncommenting the commented lines that ship with Craft.

return [
    'modules' => [
        'my-module' => \modules\Module::class,
    'bootstrap' => ['my-module'],

Add a VideoHandler class in the module folder, modules/videohandler.php


namespace modules;

use samhernandez\shortcodes\handlers\ShortcodeHandlerInterface;
use Thunder\Shortcode\Shortcode\ShortcodeInterface;

class VideoHandler implements ShortcodeHandlerInterface
     * This callable class will be used as a callback to
     * handle the `video` shortcode tag.
     * @param ShortcodeInterface $shortcode
     * @return string
     * @see
    public function __invoke(ShortcodeInterface $shortcode)
        $mp4 = $shortcode.getParameter('mp4');
        $webm = $shortcode.getParameter('webm');

        $html = '<video>';

        if ($mp4) {
            $html .= '<source src="'.$mp4.'" type="video/mp4">';

        if ($webm) {
            $html .= '<source src="'.$webm.'" type="video/webm">';

        $html .= '</video>';

        // Be sure to return html as raw Twig
        return TemplateHelper::getRaw($html);

Now add the fully qualified class name to the config file, config/shortcodes.php.


use modules\VideoHandler;

return [
    'map' => [
        'video' => VideoHandler::class

That's it!

Advanced Config

There are two more config options: parser and syntax.

use 'samhernandez/craft-shorcodes/Shortcodes'

return [
    'map' => [
        // ...
    'parser' => Shortcodes::PARSER_REGEX,
    'syntax' => ['@', '$', '!', '&', '~']

parser options:

  • Shortcodes::PARSER_REGULAR
  • Shortcodes::PARSER_REGEX
  • Shortcodes::PARSER_WORDPRESS (default)

Read the thunderer/Shortcode Parsing docs for more information about the "regular" and "regex" parsers.

If you need to use different symbols for shortcode singatures, use syntax as an array with the following:

  1. Opening tag
  2. Closing tag
  3. Closing tag marker
  4. Parameter value separator
  5. Parameter value delimiter

Alternative syntaxes are ignored by the WordPress parser. You'll need to use the "regular" or "regex" parser.

Read the thunderer/Shortcode Syntax docs for more information.


Pull requests are welcome.

I'd like to see some of the native WordPress shortcodes in Twig so they can be used with this plugin straight out of the bubble wrap.

A nicer icon would be welcome too.