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>
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.
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
<?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]).
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 ¯\(ツ)/¯