Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Shortcode Laravel Package

thunderer/shortcode

Framework-agnostic PHP library for parsing and processing shortcodes/BBCodes. Extract shortcodes from text, handle replacements, and apply them via processors and events. Includes serializers for Text/XML/JSON/YAML. Supports PHP 5.3–8.x.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require thunderer/shortcode
    

    Add to composer.json if not using Composer directly.

  2. Basic Usage:

    use Thunder\Shortcode\ShortcodeFacade;
    
    $facade = new ShortcodeFacade();
    $facade->addHandler('greet', fn($s) => "Hello, {$s->getParameter('name')}!");
    echo $facade->process('[greet name="John"]');
    // Output: Hello, John!
    
  3. First Use Case: Replace dynamic content in a Laravel Blade template:

    // In a service provider or controller
    $facade = new ShortcodeFacade();
    $facade->addHandler('user', fn($s) => auth()->user()->{$s->getParameter('field')});
    
    // In Blade: {{ $facade->process('[user field="name"]') }}
    

Implementation Patterns

Core Workflows

  1. Handler Registration:

    // Single handler
    $facade->addHandler('alert', fn($s) =>
        "<div class='alert'>" . $s->getContent() . "</div>"
    );
    
    // Multiple handlers (e.g., in a service provider)
    $handlers = [
        'alert' => fn($s) => "<div class='alert'>" . $s->getContent() . "</div>",
        'button' => fn($s) => "<button>{$s->getContent()}</button>",
    ];
    foreach ($handlers as $name => $callback) {
        $facade->addHandler($name, $callback);
    }
    
  2. Nested Shortcodes:

    $facade->addHandler('container', fn($s) =>
        "<div>" . $facade->process($s->getContent()) . "</div>"
    );
    echo $facade->process('[container][alert]Error![/alert][/container]');
    
  3. Dynamic Handlers (Laravel Example):

    // Register handlers based on database config
    $shortcodeConfigs = ShortcodeConfig::all();
    foreach ($shortcodeConfigs as $config) {
        $facade->addHandler($config->name, function($s) use ($config) {
            return app($config->handler_class)->render($s);
        });
    }
    
  4. Blade Integration:

    // Create a Blade directive
    Blade::directive('shortcode', function ($expression) {
        return "<?php echo app('shortcode')->process({$expression}); ?>";
    });
    
    // Usage in Blade: @shortcode('[user field="email"]')
    

Advanced Patterns

  1. Event-Driven Processing:

    $facade->addEventHandler(\Thunder\Shortcode\Events::FILTER_SHORTCODES, function($event) {
        if ($event->getParent()->getName() === 'raw') {
            $event->setShortcodes([]); // Skip nested shortcodes
        }
    });
    
  2. Custom Parsers:

    $customSyntax = (new \Thunder\Shortcode\Syntax\SyntaxBuilder())
        ->setOpeningTag('{')
        ->setClosingTag('}')
        ->getSyntax();
    
    $facade->setParser(new \Thunder\Shortcode\Parser\RegularParser($customSyntax));
    
  3. Serialization:

    $shortcode = $facade->parse('[alert]Warning![/alert]');
    $json = $facade->serialize($shortcode, 'json');
    $restored = $facade->unserialize($json, 'json');
    
  4. Configuration Management:

    // In config/shortcodes.php
    return [
        'recursion_depth' => 3,
        'max_iterations' => 2,
    ];
    
    // Apply in service provider
    $facade->setProcessor(
        $facade->getProcessor()
            ->withRecursionDepth(config('shortcodes.recursion_depth'))
    );
    

Gotchas and Tips

Pitfalls

  1. Recursion Depth:

    • Default null allows unlimited nesting, which can cause stack overflows.
    • Set withRecursionDepth(3) for most use cases to prevent infinite loops.
  2. Auto-Processing Content:

    • withAutoProcessContent(true) (default) processes nested shortcodes automatically.
    • Disable with false if you need manual control over nested processing.
  3. Parser Quirks:

    • RegexParser fails with overlapping shortcodes (e.g., [a][a/]).
    • Use RegularParser for complex nested structures.
  4. Parameter Handling:

    • Unquoted parameters (e.g., [tag param=value]) may break if values contain spaces.
    • Always quote parameters: [tag param="value with spaces"].
  5. Case Sensitivity:

    • Shortcode names are case-sensitive by default.
    • Normalize names (e.g., strtolower()) if case-insensitive behavior is needed.

Debugging Tips

  1. Inspect Parsed Shortcodes:

    $shortcodes = $facade->parse('[alert]Warning![/alert]');
    dd($shortcodes); // Debug parsed structure
    
  2. Log Handlers:

    $facade->addHandler('debug', function($s) {
        \Log::debug('Shortcode:', [
            'name' => $s->getName(),
            'params' => $s->getParameters(),
            'content' => $s->getContent(),
        ]);
        return $s->getContent();
    });
    
  3. Test Edge Cases:

    // Test unclosed shortcodes
    $facade->process('[alert]Warning!'); // Should output raw
    
    // Test invalid syntax
    $facade->process('[alert param=value]'); // Ensure proper escaping
    

Extension Points

  1. Custom Handlers:

    // Dynamic handler resolution (e.g., from a database)
    $facade->addHandler('dynamic', function($s) {
        $handler = app("ShortcodeHandler:{$s->getParameter('type')}");
        return $handler->render($s);
    });
    
  2. Plugin System:

    // Register shortcodes via plugins
    event('shortcode.register', function($facade) {
        $facade->addHandler('plugin-tag', fn($s) => "Plugin: {$s->getContent()}");
    });
    
  3. Caching Handlers:

    // Cache handler results (e.g., for expensive operations)
    $facade->addHandler('expensive', function($s) {
        return cache()->remember("shortcode:{$s->getName()}", now()->addHours(1), function() {
            return app('ExpensiveService')->process($s);
        });
    });
    
  4. Laravel Service Provider:

    // Bind facade to Laravel container
    $this->app->singleton('shortcode', function($app) {
        $facade = new ShortcodeFacade();
        // Register default handlers here
        return $facade;
    });
    
  5. Middleware for Shortcodes:

    // Process shortcodes in HTTP responses
    $response->setContent(
        $facade->process($response->getContent())
    );
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky