PHPackages                             violet88/silverstripe-shortcodable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. violet88/silverstripe-shortcodable

ActiveSilverstripe-vendormodule[Utility &amp; Helpers](/categories/utility)

violet88/silverstripe-shortcodable
==================================

Provides a popup for inserting and editing shortcodes in the SilverStripe CMS.

01901[1 issues](https://github.com/Violet88github/silverstripe-shortcodable/issues)JavaScript

Since Apr 3Pushed 2y agoCompare

[ Source](https://github.com/Violet88github/silverstripe-shortcodable)[ Packagist](https://packagist.org/packages/violet88/silverstripe-shortcodable)[ RSS](/packages/violet88-silverstripe-shortcodable/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependenciesVersions (1)Used By (0)

SilverStripe Shortcodable
=========================

[](#silverstripe-shortcodable)

[![Screenshot](docs/img/edit.png)](docs/img/edit.png)

Provides a popup for inserting and editing shortcodes in the SilverStripe CMS. Shortcodes are small pieces of code inside square brackets that trigger a larger function. This module allows you to define your own `DataObjects` and `ViewableData` as shortcodes, and insert them into the HTMLEditorField in the CMS.

Requirements
------------

[](#requirements)

- SilverStripe ^5
- PHP ^8.1

> **Note:** This module may work with SilverStripe 4 and PHP 7.4, but it is not officially supported. Please use [sheadawson/silverstripe-shortcodable](https://github.com/sheadawson/silverstripe-shortcodable) for SilverStripe 4 and below.

Installation
------------

[](#installation)

Install the module using composer.

```
composer require violet88/silverstripe-shortcodable
```

Configuration
-------------

[](#configuration)

### Defining Shortcodes

[](#defining-shortcodes)

Define your shortcodes in a yml config file. You can define shortcodes for `DataObjects` and `ViewableData` classes.

```
Violet88\Shortcodable\Shortcodable:
    shortcodable_classes:
        - MyDataObject
        - MyViewableData
```

Shortcodable classes may be namespaced, but at the moment using duplicate class names in different namespaces is not supported and may lead to unexpected results. This is a known issue and will be addressed in a future release.

### Parsing Shortcodes

[](#parsing-shortcodes)

In order to be able to parse the shortcodes, the `parse_shortcode` method must be available in the class. This method should return the HTML that will replace the shortcode in the frontend.

```
use SilverStripe\ORM\DataObject;
use SilverStripe\View\ArrayData;

class MyDataObject extends DataObject
{
    private static array $db = [
        'Title' => 'Varchar',
        'Content' => 'HTMLText',
    ];

    public static function parse_shortcode($arguments, $content, $parser, $tagName)
    {
        $object = self::get()->byID($arguments['id']);

        return ArrayData::create([
            'Title' => $object->Title,
            'Content' => $object->Content,
        ])->renderWith('MyDataObject');
    }
}
```

> **Note:** The `parse_shortcode` method doesn't need to use template rendering. It can return any string.

> **Note:** The `parse_shortcode` method must be a static one. All shortcodes contain an 'id' argument with which the object can be fetched.

### Additional Shortcode Attributes

[](#additional-shortcode-attributes)

You can define additional attributes for your shortcodes using the `shortcode_fields` config array. These attributes will be available in the shortcode popup when inserting or editing a shortcode.

In this array you can also define how the attribute should be rendered in the popup. All standard HTML input types are supported, as well as a `select` and `radiogroup` type.

The schema for the `shortcode_fields` array is as follows:

```
{
    "attribute_name": {
        "type": "text",
        "label": "Attribute label", // Optional
        "placeholder": "Attribute placeholder", // Optional
        "options": {
            // Only for select and radiogroup types
            "option1": "Option 1",
            "option2": "Option 2"
        }
    }
}
```

This schema can translate to the following `shortcode_fields` array in PHP:

```
use SilverStripe\ORM\DataObject;
use SilverStripe\View\ArrayData;

class MyDataObject extends DataObject
{
    private static array $db = [
        'Title' => 'Varchar',
        'Content' => 'HTMLText',
    ];

	private static $shortcode_fields = [
		'Title' => [
			'type' => 'text',
            'label' => 'Title for video',
			'placeholder' => 'Enter a title'
		],
        'Content' => [
            'type' => 'textarea',
            'placeholder' => 'Description for video'
        ],
        'Type' => [
            'type' => 'select',
            'options' => [
                'youtube' => 'YouTube',
                'vimeo' => 'Vimeo'
            ]
        ]
	];

    public static function parse_shortcode($arguments, $content, $parser, $tagName)
    {
        $object = self::get()->byID($arguments['id']);

        return ArrayData::create([
            'Title' => $object->Title,
            'Content' => $object->Content,
        ])->renderWith('MyDataObject');
    }
}
```

> **Note:** Since the `shortcode_fields` attribute is static and cannot be changed, we've added the ability to define the options for a `select` or `radiogroup` type using a method. This method should return an array of options.
>
> ```
> private static $shortcode_fields = [
>     'Type' => [
>         'type' => 'select',
>         'options' => 'getTypes'
>     ]
> ];
>
> public function getTypes()
> {
>     return [
>        'youtube' => 'YouTube',
>        'vimeo' => 'Vimeo'
>     ];
> }
> ```

If you're looking for something easier to set up, an array of field names can be used instead of the full schema. This will default to a `text` input type with the field name as the placeholder.

```
use SilverStripe\ORM\DataObject;
use SilverStripe\View\ArrayData;

class MyDataObject extends DataObject
{
    private static array $db = [
        'Title' => 'Varchar',
        'Content' => 'HTMLText',
    ];

    private static $shortcode_fields = [
        'Title',
        'Content',
        'Type'
    ];

    public static function parse_shortcode($arguments, $content, $parser, $tagName)
    {
        $object = self::get()->byID($arguments['id']);

        return ArrayData::create([
            'Title' => $object->Title,
            'Content' => $object->Content,
        ])->renderWith('MyDataObject');
    }
}
```

CMS Usage
---------

[](#cms-usage)

Once installed a new icon will appear in the CMS editor toolbar. It looks like this: [![icon](docs/img/button.png)](docs/img/button.png)

This button shows a popup that can be used to create a new shortcode:

[![popup](docs/img/new.png)](docs/img/new.png)

Shortcodes can also be edited by clicking on them in the editor, or removed by pressing the backspace key when the cursor is at the beginning of the shortcode:

[![edit](docs/img/edit.png)](docs/img/edit.png)

### Validity

[](#validity)

Shortcodes are only valid if they are in the format `[shortcode]` or `[shortcode attribute="value"]`. If the shortcode is not valid, it will be highlighted in red and removed when the editor is saved:

Valid ShortcodeInvalid Shortcode[![Valid Shortcode](docs/img/valid.png)](docs/img/valid.png)[![Invalid Shortcode](docs/img/invalid.png)](docs/img/invalid.png)Upgrading from [sheadawson/silverstripe-shortcodable](https://github.com/sheadawson/silverstripe-shortcodable)
--------------------------------------------------------------------------------------------------------------

[](#upgrading-from-sheadawsonsilverstripe-shortcodable)

If you are upgrading from [sheadawson/silverstripe-shortcodable](https://github.com/sheadawson/silverstripe-shortcodable) the following steps can be used to get you back on track:

1. Remove the old module using composer:

    ```
    composer remove sheadawson/silverstripe-shortcodable
    ```
2. Install the new module using composer:

    ```
    composer require violet88/silverstripe-shortcodable
    ```
3. Update your config namespaces from `Silverstripe\Shortcodable` to `Violet88\Shortcodable`:

    ```
    - Silverstripe\Shortcodable:
    + Violet88\Shortcodable\Shortcodable:
      shortcodable_classes:
        - MyDataObject
        - MyViewableData
    ```
4. Update your class namespaces from `Shortcodable` to `Shortcodable`:

    ```
    - use SilverStripe\Shortcodable;
    + use Violet88\Shortcodable\Shortcodable;

    - use SilverStripe\Shortcodable\Controller\ShortcodableController;
    + use Violet88\Shortcodable\Controllers\ShortcodableController;
    ```
5. Remove references to the `ShortcodableHtmlEditorField` and `ShortcodableShortcodeParserExtension` extensions. These no longer exist in the new module.
6. Update your `getShortcodeFields` method to use the new `shortcode_fields` config array. This array can be used to define additional attributes for your shortcodes.

    ```
    - public function getShortcodeFields() {
    -     return FieldList::create([
    -         TextField::create('Title', 'Title for video'),
    -         TextareaField::create('Content', 'Description for video'),
    -         DropdownField::create('Type', 'Type', [
    -             'youtube' => 'YouTube',
    -             'vimeo' => 'Vimeo'
    -         ])
    -     ]);
    - }
    + private static $shortcode_fields = [
    +     'Title' => [
    +         'type' => 'text',
    +         'placeholder' => 'Title for video'
    +     ],
    +     'Content' => [
    +         'type' => 'textarea',
    +         'placeholder' => 'Description for video'
    +     ],
    +     'Type' => [
    +         'type' => 'select',
    +         'options' => [
    +             'youtube' => 'YouTube',
    +             'vimeo' => 'Vimeo'
    +         ]
    +     ]
    + ]
    ```

###  Health Score

17

—

LowBetter than 6% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community17

Small or concentrated contributor base

Maturity19

Early-stage or recently created project

 Bus Factor1

Top contributor holds 55% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/e81407c3850e235ac246bc79116c74cac965fb3c8c146404b40ea660c88333eb?d=identicon)[PixNyb](/maintainers/PixNyb)

---

Top Contributors

[![sheadawson](https://avatars.githubusercontent.com/u/1166136?v=4)](https://github.com/sheadawson "sheadawson (60 commits)")[![PixNyb](https://avatars.githubusercontent.com/u/40770831?v=4)](https://github.com/PixNyb "PixNyb (18 commits)")[![micschk](https://avatars.githubusercontent.com/u/1005986?v=4)](https://github.com/micschk "micschk (8 commits)")[![oilee80](https://avatars.githubusercontent.com/u/1453382?v=4)](https://github.com/oilee80 "oilee80 (5 commits)")[![jonom](https://avatars.githubusercontent.com/u/1079425?v=4)](https://github.com/jonom "jonom (4 commits)")[![JanSneeuw](https://avatars.githubusercontent.com/u/48092471?v=4)](https://github.com/JanSneeuw "JanSneeuw (3 commits)")[![satrun77](https://avatars.githubusercontent.com/u/166450?v=4)](https://github.com/satrun77 "satrun77 (2 commits)")[![spekulatius](https://avatars.githubusercontent.com/u/8433587?v=4)](https://github.com/spekulatius "spekulatius (2 commits)")[![wernerkrauss](https://avatars.githubusercontent.com/u/1043925?v=4)](https://github.com/wernerkrauss "wernerkrauss (1 commits)")[![djmattski](https://avatars.githubusercontent.com/u/3836638?v=4)](https://github.com/djmattski "djmattski (1 commits)")[![ec8or](https://avatars.githubusercontent.com/u/1678184?v=4)](https://github.com/ec8or "ec8or (1 commits)")[![lozcalver](https://avatars.githubusercontent.com/u/1655548?v=4)](https://github.com/lozcalver "lozcalver (1 commits)")[![Neumes](https://avatars.githubusercontent.com/u/8358226?v=4)](https://github.com/Neumes "Neumes (1 commits)")[![patjnr](https://avatars.githubusercontent.com/u/435055?v=4)](https://github.com/patjnr "patjnr (1 commits)")[![adrexia](https://avatars.githubusercontent.com/u/984753?v=4)](https://github.com/adrexia "adrexia (1 commits)")

### Embed Badge

![Health badge](/badges/violet88-silverstripe-shortcodable/health.svg)

```
[![Health](https://phpackages.com/badges/violet88-silverstripe-shortcodable/health.svg)](https://phpackages.com/packages/violet88-silverstripe-shortcodable)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
