Extending the shortcode builder

Potentially being superseded by focus on Block editor experiences, started in version 1.7.0

Registering a shortcode

In order to register a new shortcode for the shortcode builder, you need to provide a function callback to the cptui_register_shortcode() function. This will be the function that should be called at the time of display in the shortcode builder. You should register the shortcode on the cptuiext_loaded action hook so that everything is ready at the appropriate time.

function my_custom_cptui_shortcode() {
    cptui_register_shortcode( 'my_custom_shortcode' );
}
add_action( 'cptuiext_loaded', 'my_custom_cptui_shortcode' );

Creating the shortcode callback function

Once you have added a function callback to the cptui_register_shortcode() function, you need to also define that function. It will not have any parameters passed in, and it does need to return an array of parameters to use for the custom shortcode fields.

Shortcode callback parameters

  • (string) id: ID for the shortcode for CMB2
  • (string) name: The name of the shortcode. Appears in select drpdown.
  • (string) template: The name of the template file to use for the shortcode output.
  • (string) template_location: Where to find the specified template file.
  • (string) style: handle for a registered wp_register_style() call.
  • (string) script: handle for a registered wp_register_script() call.
  • (string) post_type: Which post types to allow the shortcode to be used for.
  • (string) description: Appears above the shortcode fields.
  • (array) fields: array of arrays holding CMB2-style field declarations. See CMB2 Wiki
// Very basic shortcode with no fields.
function my_custom_shortcode() {
	$shortcode = array(
		'id' => 'my_custom_shortcode',
		'name' => 'My Custom',
		'template' => 'posts',
		'template_location' => 'plugin-dir/my-templates',
		'style' => 'my_shortcode_css',
		'script' => 'my_shortcode_js',
		'post_type' => 'post',
		'description' => ' ',
		'fields' => array()
	);
	return $shortcode;
}

In order to start displaying some fields, we need to add them to the fields array at the end.

'fields' => array(
	array(
		'name' => 'Title',
		'id'   => 'title',
		'description' => 'Title to display above CPTs',
		'type' => 'text',
	),
	array(
		'name' => 'Amount',
		'id'   => 'amount',
		'description' => 'How many posts to show?',
		'type' => 'text',
	),
	array(
		'name' => 'Featured Image',
		'description' => 'Would you like a featured image',
		'id'   => 'featured_image',
		'type' => 'checkbox',
	),
)

Here we add two basic text fields to store some information in and then a checkbox. These fields will show when the user selects your custom shortcode to use and fill in values for, to be inserted into where they want the shortcode used.

Scripts and styles

If you are wanting or needing to add custom javascript or css file for your shortcode, you can do so with the ‘script’ and ‘style’ parameters. These parameters should only have the handle provided from a wp_register_script or wp_register_style function call. Custom Post Type UI Extended will handle the enqueuing of the files.

function my_custom_shortcode_enqueue() {
	wp_register_style( 'my_shortcode_css', 'plugin-dir/css/style.css' );
	wp_register_script( 'my_shortcode_js', 'plugin-dir/js/shortcode.js' );
}
add_action( 'wp_enqueue_scripts', 'my_custom_shortcode_enqueue' );

Custom template loading

This applies for version 1.4.0+

In order for the template loader, added in version 1.4.0, to find your template, you need to add its location to the stack. This value will be the same value specified above for ‘template_location’.

function my_custom_shortcode_template_stack( $paths ) {
	$paths[15] = 'plugin-dir/my-templates';

	return $paths;
}
add_filter( 'cptui_extended_template_paths', 'my_custom_shortcode_template_stack' );

With this filter callback, we are passed an array of already set paths to check. Each will have a numeral index that indicate priority for the location. For example, the template loader by default checks the child theme folder with a priority of 1. It then checks the parent folder, with a priority of 10, followed by the default location that we provide, with a priority of 100.

If you are familiar with how action/filter priorities work, this works in the exact same way.

Template file

The template file that you create is pretty much up to you. If you have set up themes that use get_template_part() that retrieve files that contain only WordPress loops, then these will be along the same lines. The key difference is that we need to invoke our own WP_Query object using the attributes provided by the shortcode.

Template file function calls

For compatibility sake, it’s best to include a call to cptui_shortcode_atts() that passes in the $attributes variable that will be made available to you inside the template. Doing this allows for the arguments to be filtered right before usage. The following snippet will provide a solid example.

$attributes = (array) cptui_shortcode_atts( $attributes );

The “(array)” casting in front of the function call is optional. The Template loading in 1.4.0 passes a PHP object into the template file. You can use either version.

Next would be grabbing the appropriate values from the “$attributes” variable to pass into a new WP_Query instance to fetch the posts. Finally, you would want to iterate over the results and output the markup however which way you want based on parameters provided by the shortcode.

Updated Dec 12, 2022 8:43 PM