Shortcodes

Introduction

The Events Calendar and Event Tickets plugins provide a robust Shortcode API that allows both internal and third-party developers to create and manage shortcodes within the ecosystem. This API is designed to standardize shortcode creation, argument handling, validation, and rendering while providing hooks for customization at every step.

The Shortcode API is part of the Common module in The Events Calendar, making it available to all plugins that include this common functionality. This documentation will explore how to leverage this API to create custom shortcodes that integrate seamlessly with The Events Calendar and Event Tickets.

Top ↑

Core API Architecture

The Shortcode API is built around four primary components in the Common module:

Top ↑

Interface

The Shortcode_Interface (\Tribe\Shortcode\Shortcode_Interface) defines the contract that all shortcodes must follow. This interface ensures that shortcodes implement consistent methods for:

  • Registration
  • Argument handling
  • Content parsing
  • HTML rendering

Key methods defined in the interface include:

  • get_registration_slug() – Returns the shortcode tag used for registration
  • setup() – Configures the shortcode with arguments and content
  • parse_arguments() – Processes and validates shortcode attributes
  • get_html() – Renders the shortcode’s HTML output

Top ↑

Abstract Class

The Shortcode_Abstract (\Tribe\Shortcode\Shortcode_Abstract) implements the interface and provides common functionality that all shortcodes can inherit. The abstract class handles:

  • Argument parsing and validation
  • Default argument management
  • Aliased argument support (allowing alternative attribute names)
  • Content storage
  • Filter hooks for customization

Key properties you’ll need to define when extending this class:

protected $slug = 'your_shortcode_tag';
protected $default_arguments = [
    'arg1' => 'default_value',
    'arg2' => 123,
];

The abstract class includes built-in support for argument aliasing, allowing users to provide alternative argument names in their shortcodes:

protected $aliased_arguments = [
    'alt_name' => 'canonical_name',
    'from' => 'to',
];

Top ↑

Manager

The Manager (\Tribe\Shortcode\Manager) class is responsible for:

  • Registering shortcodes with WordPress
  • Handling shortcode rendering through the appropriate classes
  • Tracking which shortcodes are currently being processed
  • Providing utility methods for checking shortcode status

The Manager implements a filter tribe_shortcodes that allows plugins to register their shortcodes:

add_filter( 'tribe_shortcodes', function( $shortcodes ) {
    $shortcodes['my_shortcode'] = 'My\Namespace\My_Shortcode';
    return $shortcodes;
} );

Top ↑

Utils

The Utils (\Tribe\Shortcode\Utils) class provides helper methods for shortcode-related operations, particularly converting widget settings to shortcode attributes:

$attributes_string = Utils::get_attributes_string( $settings, $allowed );

Top ↑

Creating Custom Shortcodes

Top ↑

Basic Implementation

To create a custom shortcode using The Events Calendar’s Shortcode API:

  1. Create a class that extends \Tribe\Shortcode\Shortcode_Abstract
  2. Set the $slug property to your shortcode tag
  3. Implement the get_html() method to render your shortcode output
  4. Register your shortcode with the manager

Here’s a minimal example:

<?php
namespace My\Plugin\Shortcodes;

use Tribe\Shortcode\Shortcode_Abstract;

class My_Custom_Shortcode extends Shortcode_Abstract {
    /**
     * {@inheritDoc}
     */
    protected $slug = 'my_custom_shortcode';

    /**
     * {@inheritDoc}
     */
    protected $default_arguments = [
        'title' => '',
        'limit' => 5,
    ];

    /**
     * {@inheritDoc}
     */
    public function get_html() {
        $title = $this->get_argument( 'title', 'Default Title' );
        $limit = $this->get_argument( 'limit', 5 );

        // Your shortcode logic here

        return '<div class="my-shortcode">' . 
               '<h3>' . esc_html( $title ) . '</h3>' .
               // Additional HTML
               '</div>';
    }
}

Top ↑

Handling Arguments

The Shortcode API provides robust argument handling:

Top ↑

Default Arguments

Set default values for your shortcode arguments:

protected $default_arguments = [
    'title' => 'Default Title',
    'limit' => 10,
    'category' => '',
];

Top ↑

Argument Aliasing

Allow users to use alternative attribute names:

protected $aliased_arguments = [
    'count' => 'limit',     // [my_shortcode count="5"] works the same as [my_shortcode limit="5"]
    'heading' => 'title',   // [my_shortcode heading="Events"] works the same as [my_shortcode title="Events"]
];

Top ↑

Argument Validation

Implement validation callbacks for your arguments:

protected $validate_arguments_map = [
    'limit' => [ $this, 'validate_limit' ],
    'category' => [ $this, 'validate_category' ],
];

protected function validate_limit( $limit ) {
    $limit = absint( $limit );
    return $limit > 0 ? $limit : 5;
}

protected function validate_category( $category ) {
    return sanitize_text_field( $category );
}

Top ↑

Retrieving Arguments

Access processed arguments in your shortcode:

public function get_html() {
    // Get a single argument with optional default
    $limit = $this->get_argument( 'limit', 10 );

    // Get all arguments
    $args = $this->get_arguments();

    // Build your shortcode output using these arguments
    // ...
}

Top ↑

Rendering HTML

The get_html() method is where you generate the shortcode output:

public function get_html() {
    // Check if we're in an admin context and not doing AJAX
    if ( is_admin() && ! tribe_context()->doing_ajax() ) {
        return '';
    }

    // Get your template engine
    $template = tribe( 'your.template.engine' );

    // Prepare data for the template
    $data = [
        'title' => $this->get_argument( 'title' ),
        'items' => $this->get_items(),
    ];

    // Add the data to template context
    $template->add_template_globals( $data );

    // Enqueue any necessary assets
    tribe_asset_enqueue_group( 'your-asset-group' );

    // Render and return the template
    return $template->template( 'path/to/template', $data, false );
}

Top ↑

Registration Process

To register your shortcode with The Events Calendar’s Shortcode API:

  1. Create a function or class method that hooks into the tribe_shortcodes filter
  2. Add your shortcode to the array with the shortcode slug as the key and the class name as the value
  3. Ensure your class autoloading is set up correctly

Example in a plugin:

<?php
/**
 * Plugin Name: My TEC Extension
 * Description: Adds custom shortcodes to The Events Calendar
 */

// Register shortcodes with TEC
add_filter( 'tribe_shortcodes', function( $shortcodes ) {
    $shortcodes['my_custom_shortcode'] = 'My\Plugin\Shortcodes\My_Custom_Shortcode';
    return $shortcodes;
} );

// Include your shortcode class
require_once plugin_dir_path( __FILE__ ) . 'classes/Shortcodes/My_Custom_Shortcode.php';

Top ↑

Available Hooks

The Shortcode API provides numerous filter hooks for customization:

Top ↑

Global Shortcode Filters

  • tribe_shortcodes – Register shortcode classes
  • tribe_shortcode_validate_arguments_map – Modify argument validation callbacks
  • tribe_shortcode_arguments – Filter processed shortcode arguments
  • tribe_shortcode_argument – Filter an individual argument value
  • tribe_shortcode_default_arguments – Modify default arguments

Top ↑

Shortcode-Specific Filters

  • tribe_shortcode_{$slug}_validate_arguments_map – Modify validation callbacks for a specific shortcode
  • tribe_shortcode_{$slug}_arguments – Filter arguments for a specific shortcode
  • tribe_shortcode_{$slug}_argument – Filter an individual argument for a specific shortcode
  • tribe_shortcode_{$slug}_default_arguments – Modify default arguments for a specific shortcode
  • tec_shortcode_{$slug}_aliased_arguments – Modify aliased arguments for a specific shortcode

Top ↑

Best Practices

When developing shortcodes with The Events Calendar’s API:

  1. Always extend the Shortcode_Abstract class – This ensures your shortcode follows the same standards and behaves consistently with other TEC shortcodes.
  2. Validate user input – Use the validate_arguments_map to ensure all user-provided attributes are properly sanitized.
  3. Support aliased arguments – Improve user experience by allowing alternative attribute names that may be more intuitive.
  4. Separate logic from presentation – Use templates for rendering HTML rather than building it directly in the get_html() method.
  5. Enqueue required assets – Make sure to enqueue any CSS/JS your shortcode needs.
  6. Check context before rendering – Avoid rendering in admin contexts where it might not make sense.
  7. Use filter hooks – Implement filter hooks to allow other developers to customize your shortcode’s behavior.
  8. Document your shortcode – Provide clear documentation on what attributes are available and how they modify the output.
  9. Handle errors gracefully – Return informative messages when something goes wrong, rather than breaking the page.
  10. Keep performance in mind – Optimize database queries and cache results when possible.

Top ↑

Troubleshooting

Common issues when working with the Shortcode API:

Top ↑

Shortcode Not Registered

If your shortcode isn’t working:

  • Verify your hook into tribe_shortcodes is running
  • Check that the class name in the registry matches your actual class name and namespace
  • Ensure your class is properly autoloaded or included

Top ↑

Arguments Not Processing Correctly

If shortcode attributes aren’t working as expected:

  • Check if you’re properly defining $default_arguments
  • Verify your validation callbacks are returning the expected values
  • Use var_dump( $this->get_arguments() ) in your get_html() method to debug

Top ↑

HTML Output Issues

If your shortcode isn’t rendering correctly:

  • Check for any PHP errors in your logs
  • Ensure templates exist at the specified paths
  • Verify that assets are being properly enqueued
  • Test your shortcode in a simple environment without other plugins

Top ↑

Advanced Customization

You can hook into the various filters provided by the API:

// Modify arguments for a specific shortcode
add_filter( 'tribe_shortcode_my_shortcode_arguments', function( $args, $instance ) {
    // Custom logic to modify args
    return $args;
}, 10, 2 );

// Add aliased arguments to all shortcodes
add_filter( 'tec_shortcode_aliased_arguments', function( $aliases, $instance ) {
    $aliases['count'] = 'limit';
    return $aliases;
}, 10, 2 );

This documentation provides a comprehensive overview of The Events Calendar’s Shortcode API. By following these guidelines, internal and third-party developers can create custom shortcodes that seamlessly integrate with The Events Calendar and Event Tickets, providing users with additional functionality while maintaining a consistent experience throughout the plugins ecosystem.