… uses array_merge?

To see the core reference click here.To hide the core reference click here.

/**
 * Merge user defined arguments into defaults array.
 *
 * This function is used throughout WordPress to allow for both string or array
 * to be merged into another array.
 *
 * @since 2.2.0
 *
 * @param string|array $args     Value to merge with $defaults
 * @param array        $defaults Optional. Array that serves as the defaults. Default empty.
 * @return array Merged user defined values with defaults.
 */
function wp_parse_args( $args, $defaults = '' ) {
	if ( is_object( $args ) )
		$r = get_object_vars( $args );
	elseif ( is_array( $args ) )
		$r =& $args;
	else
		wp_parse_str( $args, $r );

	if ( is_array( $defaults ) )
		return array_merge( $defaults, $r );
	return $r;
}

Great, but why is this relevant? Consider you are creating a short code wrapper for a function where some of the arguments that are passed to the function must be specific values and the others are meant to be exposed to the user.

As an example, let’s look at a shortcode using wp_list_pages() to display only the child-pages of the parent-page.

The shortcode is meant to expose all of the wp_list_pages() default arguments but, since it is a shortcode, you do not want the echo argument to be exposed or set to true. We also want to automatically set the child_of parameter value.

Here are the default arguments of wp_list_pages() as shown in the WordPress codex:

<?php $args = array(
	'authors'      => '',
	'child_of'     => 0,
	'date_format'  => get_option('date_format'),
	'depth'        => 0,
	'echo'         => 1,
	'exclude'      => '',
	'include'      => '',
	'link_after'   => '',
	'link_before'  => '',
	'post_type'    => 'page',
	'post_status'  => 'publish',
	'show_date'    => '',
	'sort_column'  => 'menu_order, post_title',
        'sort_order'   => '',
	'title_li'     => __('Pages'), 
	'walker'       => ''
); ?>

Noting the highlighted lines above, let’s move those into their own array and set their values:

<?php $required_arguments = array(
	'echo'     => 0,
	'child_of' => $post->ID, /** This requires the global $post, so make sure it is available */
); ?>

This leaves the balance of the arguments which will be the shortcode “defaults”. Using some code like this:

<?php $defaults = shortcode_atts( array(
	'authors'      => '',
	'date_format'  => get_option('date_format'),
	'depth'        => 0,
	'exclude'      => '',
	'include'      => '',
	'link_after'   => '',
	'link_before'  => '',
	'post_type'    => 'page',
	'post_status'  => 'publish',
	'show_date'    => '',
	'sort_column'  => 'menu_order, post_title',
        'sort_order'   => '',
	'title_li'     => __('Pages'), 
	'walker'       => ''
), $atts, 'child_pages' ); ?>

We now merge these two arrays together and pass all of the arguments to wp_list_pages():

<?php $output_arguments = wp_parse_args( $required_arguments, $defaults ); 
wp_list_pages( $output_arguments ); ?>

The parent-page was set, the echo was turned off … and all of the other parameters used by wp_list_pages were available to be modified as standard shortcode parameter value pairs.

This idea was put to use and released in the BNS Helpers plugin. To see a simplified version of the shortcode callback function and add_action() call to create the shortcode have a look at the code below.

To see the BNS Helper child-pages shortcode (simplified) code click here.To hide the BNS Helper child-pages shortcode (simplified) code click here.

<?php    
	/**
	 * Child Pages Shortcode
	 *
	 * Leverage `wp_list_pages` to output a list of linked child-pages of the
	 * current page.
	 *
	 * @package BNS_Helpers
	 * @since   0.1
	 *
	 * @link    https://developer.wordpress.org/reference/functions/wp_list_pages/
	 *
	 * @uses    (GLOBAL) $post
	 * @uses    __
	 * @uses    apply_filters
	 * @uses    get_option
	 * @uses    wp_list_pages
	 * @uses    wp_parse_args
	 *
	 * @param $atts
	 *
	 * @return null|string
	 */
	function child_pages_shortcode( $atts ) {

		/** We'll need some details from the `$post` global */
		global $post;

		/** @var array $required_arguments - these should not be changed */
		$required_arguments = array(
			'echo'     => 0,
			'child_of' => $post->ID,
		);

		/** @var array $defaults - optional arguments as shortcode parameters */
		$defaults = shortcode_atts( array(
			'authors'     => '',
			'date_format' => get_option( 'date_format' ),
			'depth'       => 0,
			'exclude'     => '',
			'include'     => '',
			'link_after'  => '',
			'link_before' => '',
			'post_type'   => 'page',
			'post_status' => 'publish',
			'show_date'   => '',
			'sort_column' => 'menu_order, post_title',
			'sort_order'  => '',
			'title_li'    => sprintf( __( 'Child Pages of "%1$s"', 'bns-helpers' ), $post->post_title ),
			'walker'      => ''
		), $atts, 'child_pages' );

		/** @var array $output_arguments - uses `wp_parse_args` to merge */
		$output_arguments = wp_parse_args( $required_arguments, $defaults );

		/** @var string $output - wrap `wp_list_pages` in its own `div` */
		$output = '<div class="bns-helpers-child-pages-output">';
		$output .= '<ul>' . wp_list_pages( $output_arguments ) . '</ul>';
		$output .= '</div><!-- .bns-helpers-child-pages-output -->';

		/** We're all set ... send the (filtered) results back */

		return apply_filters( 'bns_helpers_child_pages_shortcode', $output );

	}
	/** End function - child pages shortcode */

	/** Add Child Pages Shortcode */
	add_shortcode( 'child_pages', 'child_pages_shortcode' ); ?>