The correct way to add shortcode

I was wondering what is the correct way to do shortcodes with Sage, as I’m not exactly familiar with shortcodes in wordpress in general. I’ve seen people use them in sage in both filters.php & setup.php, is there a preferable place?

For example, I am making a simple countdown timer where the user can pass a start date and end date and it will pass the data to a template partial for the markup.

How exactly would that work?

My idea of the process is as shown below ( (Loosely based off this thread). Let me know if it’s incorrect or a better way to do it in Sage.

// setup.php | Add the shortcodes

add_action( 'init', function() {
  add_shortcode('countdown', function() {
    
     // Extract the shortcode attributes
     $atts = shortcode_atts( array(
         'start' => '',
         'end' => '',
     ), $atts );

    // Start object caching or output
    ob_start();

    // Set the template we're going to use for the Shortcode
    $template = 'partials/shortcodes/countdown';

    // template data setup
    // This is where I'm lost, how do I get the the data set in WP admin to pass to the template?
    $data = collect(get_body_class())->reduce(function ($data, $class) use ($template) {
        return apply_filters("sage/template/{$class}/data", $data, $template);
    }, []);

    // Echo the shortcode blade template
    echo Template($template, $data);

    // Return cached object
		return ob_get_clean();
  });
});

// views/partials/shortcodes/countdown.blade.php
<div>
    <span class="countdown">
        $data['countdown']
    </span> 
    Days Left
</div>

If it works it’s not incorrect. Does it work?

This seems generally fine to me. I’ll sometimes split functionality like this into a separate include, like shortcodes.php or whatever to make them easier to find later, but there’s no wrong place to put something like this.

It looks good.

I’m not familiar with how shortcodes work generally in Wordpress. I intend to register this shortcode with WP Bakery to allow the client to set the countdown dates.

How are the attributes being grabbed and sent to the template file? I didn’t see how $attrs was being sent to the template in your example that I borrowed from.

Edit: Ah, I see in the answer of that thread you were setting a key on the $data array. That answers that question. I guess I wasn’t sure whether it made more sense as a filter or action. Thanks

Here’s an example of how I handle them:

<?php

namespace App;

use App\Controllers\App;

/**
 * Return if Shortcodes already exists.
 */
if (class_exists('Shortcodes')) {
    return;
}

/**
 * Shortcodes
 */
class Shortcodes
{
    /**
     * Constructor
     */
    public function __construct()
    {
        $shortcodes = [
            'box',
            'date',
            'month',
            'day',
            'year'
        ];

        return collect($shortcodes)
            ->map(function ($shortcode) {
                return add_shortcode($shortcode, [$this, strtr($shortcode, ['-' => '_'])]);
            });
    }

    /**
     * Box
     * Wraps content in a box.
     *
     * @param  array  $atts
     * @param  string $content
     * @return string
     */
    public function box($atts, $content = null)
    {
        return '<div class="box">' . do_shortcode($content) . '</div>';
    }

    /**
     * Date
     * Returns the current date.
     *
     * @param  array  $atts
     * @param  string $content
     * @return string
     */
    public function date($atts, $content = null)
    {
        return date('F d, Y');
    }

    /**
     * Month
     * Returns the current month.
     *
     * @param  array  $atts
     * @param  string $content
     * @return string
     */
    public function month($atts, $content = null)
    {
        return date('F');
    }

    /**
    * Day
    * Returns the current day.
    *
    * @param  array  $atts
    * @param  string $content
    * @return string
    */
    public function day($atts, $content = null)
    {
        return date('d');
    }

    /**
     * Year
     * Returns the current year.
     *
     * @param  array  $atts
     * @param  string $content
     * @return string
     */
    public function year($atts, $content = null)
    {
        return date('Y');
    }
}

new Shortcodes();

This lives within’ app/shortcodes.php after adding 'shortcodes' to the required files array_map() in functions.php.

Simply create a function with the name of your shortcode (using an underscore in place of a hyphen if applicable) and return a value. Afterwards, add it to the array in the construct and it will get initiated and if an underscore is present, will be changed to a hyphen (e.g. my_shortcode would become [my-shortcode]).

9 Likes

Prolly wanna make an mu-plugin or plugin for shortcodes you dev and then add styles in your theme. Shortcodes are not really a theme problem.

1 Like

Meh, depends on what the shortcode does… specific theme/styling functionality might make sense to put in a shortcode (a CTA or a button, for example), but at that point I’d wonder if it shouldn’t just go into a custom Gutenberg block ¯\(ツ)

1 Like

I use template and data like this :

$html .= \App\template( 'components.social_item', ['data' => $data] );

Especially if I’m calling a template that’s included in my theme that I just want to be able to place arbitrarily on a page.

Sounds highly coupled with low cohesion, bro

This topic was automatically closed after 42 days. New replies are no longer allowed.