wp/wp-includes/shortcodes.php
changeset 5 5e2f62d02dcd
parent 0 d970ebf37754
child 7 cf61fcea0001
equal deleted inserted replaced
4:346c88efed21 5:5e2f62d02dcd
    19  * and in the future may not be accurate. Please update the note when it is no
    19  * and in the future may not be accurate. Please update the note when it is no
    20  * longer the case.}}
    20  * longer the case.}}
    21  *
    21  *
    22  * To apply shortcode tags to content:
    22  * To apply shortcode tags to content:
    23  *
    23  *
    24  * <code>
    24  *     $out = do_shortcode( $content );
    25  * $out = do_shortcode($content);
    25  *
    26  * </code>
    26  * @link https://codex.wordpress.org/Shortcode_API
    27  *
       
    28  * @link http://codex.wordpress.org/Shortcode_API
       
    29  *
    27  *
    30  * @package WordPress
    28  * @package WordPress
    31  * @subpackage Shortcodes
    29  * @subpackage Shortcodes
    32  * @since 2.5
    30  * @since 2.5.0
    33  */
    31  */
    34 
    32 
    35 /**
    33 /**
    36  * Container for storing shortcode tags and their hook to call for the shortcode
    34  * Container for storing shortcode tags and their hook to call for the shortcode
    37  *
    35  *
    38  * @since 2.5
    36  * @since 2.5.0
       
    37  *
    39  * @name $shortcode_tags
    38  * @name $shortcode_tags
    40  * @var array
    39  * @var array
    41  * @global array $shortcode_tags
    40  * @global array $shortcode_tags
    42  */
    41  */
    43 $shortcode_tags = array();
    42 $shortcode_tags = array();
    49  * plugin has a similar shortcode, it will override yours or yours will override
    48  * plugin has a similar shortcode, it will override yours or yours will override
    50  * theirs depending on which order the plugins are included and/or ran.
    49  * theirs depending on which order the plugins are included and/or ran.
    51  *
    50  *
    52  * Simplest example of a shortcode tag using the API:
    51  * Simplest example of a shortcode tag using the API:
    53  *
    52  *
    54  * <code>
    53  *     // [footag foo="bar"]
    55  * // [footag foo="bar"]
    54  *     function footag_func( $atts ) {
    56  * function footag_func($atts) {
    55  *         return "foo = {
    57  * 	return "foo = {$atts[foo]}";
    56  *             $atts[foo]
    58  * }
    57  *         }";
    59  * add_shortcode('footag', 'footag_func');
    58  *     }
    60  * </code>
    59  *     add_shortcode( 'footag', 'footag_func' );
    61  *
    60  *
    62  * Example with nice attribute defaults:
    61  * Example with nice attribute defaults:
    63  *
    62  *
    64  * <code>
    63  *     // [bartag foo="bar"]
    65  * // [bartag foo="bar"]
    64  *     function bartag_func( $atts ) {
    66  * function bartag_func($atts) {
    65  *         $args = shortcode_atts( array(
    67  * 	extract(shortcode_atts(array(
    66  *             'foo' => 'no foo',
    68  * 		'foo' => 'no foo',
    67  *             'baz' => 'default baz',
    69  * 		'baz' => 'default baz',
    68  *         ), $atts );
    70  * 	), $atts));
    69  *
    71  *
    70  *         return "foo = {$args['foo']}";
    72  * 	return "foo = {$foo}";
    71  *     }
    73  * }
    72  *     add_shortcode( 'bartag', 'bartag_func' );
    74  * add_shortcode('bartag', 'bartag_func');
       
    75  * </code>
       
    76  *
    73  *
    77  * Example with enclosed content:
    74  * Example with enclosed content:
    78  *
    75  *
    79  * <code>
    76  *     // [baztag]content[/baztag]
    80  * // [baztag]content[/baztag]
    77  *     function baztag_func( $atts, $content = '' ) {
    81  * function baztag_func($atts, $content='') {
    78  *         return "content = $content";
    82  * 	return "content = $content";
    79  *     }
    83  * }
    80  *     add_shortcode( 'baztag', 'baztag_func' );
    84  * add_shortcode('baztag', 'baztag_func');
    81  *
    85  * </code>
    82  * @since 2.5.0
    86  *
    83  *
    87  * @since 2.5
       
    88  * @uses $shortcode_tags
    84  * @uses $shortcode_tags
    89  *
    85  *
    90  * @param string $tag Shortcode tag to be searched in post content.
    86  * @param string $tag Shortcode tag to be searched in post content.
    91  * @param callable $func Hook to run when shortcode is found.
    87  * @param callable $func Hook to run when shortcode is found.
    92  */
    88  */
    98 }
    94 }
    99 
    95 
   100 /**
    96 /**
   101  * Removes hook for shortcode.
    97  * Removes hook for shortcode.
   102  *
    98  *
   103  * @since 2.5
    99  * @since 2.5.0
   104  * @uses $shortcode_tags
   100  *
   105  *
   101  * @uses $shortcode_tags
   106  * @param string $tag shortcode tag to remove hook for.
   102  *
       
   103  * @param string $tag Shortcode tag to remove hook for.
   107  */
   104  */
   108 function remove_shortcode($tag) {
   105 function remove_shortcode($tag) {
   109 	global $shortcode_tags;
   106 	global $shortcode_tags;
   110 
   107 
   111 	unset($shortcode_tags[$tag]);
   108 	unset($shortcode_tags[$tag]);
   116  *
   113  *
   117  * This function is simple, it clears all of the shortcode tags by replacing the
   114  * This function is simple, it clears all of the shortcode tags by replacing the
   118  * shortcodes global by a empty array. This is actually a very efficient method
   115  * shortcodes global by a empty array. This is actually a very efficient method
   119  * for removing all shortcodes.
   116  * for removing all shortcodes.
   120  *
   117  *
   121  * @since 2.5
   118  * @since 2.5.0
       
   119  *
   122  * @uses $shortcode_tags
   120  * @uses $shortcode_tags
   123  */
   121  */
   124 function remove_all_shortcodes() {
   122 function remove_all_shortcodes() {
   125 	global $shortcode_tags;
   123 	global $shortcode_tags;
   126 
   124 
   130 /**
   128 /**
   131  * Whether a registered shortcode exists named $tag
   129  * Whether a registered shortcode exists named $tag
   132  *
   130  *
   133  * @since 3.6.0
   131  * @since 3.6.0
   134  *
   132  *
       
   133  * @global array $shortcode_tags List of shortcode tags and their callback hooks.
       
   134  *
       
   135  * @param string $tag Shortcode tag to check.
       
   136  * @return bool Whether the given shortcode exists.
       
   137  */
       
   138 function shortcode_exists( $tag ) {
       
   139 	global $shortcode_tags;
       
   140 	return array_key_exists( $tag, $shortcode_tags );
       
   141 }
       
   142 
       
   143 /**
       
   144  * Whether the passed content contains the specified shortcode
       
   145  *
       
   146  * @since 3.6.0
       
   147  *
   135  * @global array $shortcode_tags
   148  * @global array $shortcode_tags
   136  * @param string $tag
   149  *
   137  * @return boolean
   150  * @param string $content Content to search for shortcodes.
   138  */
   151  * @param string $tag     Shortcode tag to check.
   139 function shortcode_exists( $tag ) {
   152  * @return bool Whether the passed content contains the given shortcode.
   140 	global $shortcode_tags;
       
   141 	return array_key_exists( $tag, $shortcode_tags );
       
   142 }
       
   143 
       
   144 /**
       
   145  * Whether the passed content contains the specified shortcode
       
   146  *
       
   147  * @since 3.6.0
       
   148  *
       
   149  * @global array $shortcode_tags
       
   150  * @param string $tag
       
   151  * @return boolean
       
   152  */
   153  */
   153 function has_shortcode( $content, $tag ) {
   154 function has_shortcode( $content, $tag ) {
       
   155 	if ( false === strpos( $content, '[' ) ) {
       
   156 		return false;
       
   157 	}
       
   158 
   154 	if ( shortcode_exists( $tag ) ) {
   159 	if ( shortcode_exists( $tag ) ) {
   155 		preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
   160 		preg_match_all( '/' . get_shortcode_regex() . '/s', $content, $matches, PREG_SET_ORDER );
   156 		if ( empty( $matches ) )
   161 		if ( empty( $matches ) )
   157 			return false;
   162 			return false;
   158 
   163 
   159 		foreach ( $matches as $shortcode ) {
   164 		foreach ( $matches as $shortcode ) {
   160 			if ( $tag === $shortcode[2] )
   165 			if ( $tag === $shortcode[2] ) {
   161 				return true;
   166 				return true;
       
   167 			} elseif ( ! empty( $shortcode[5] ) && has_shortcode( $shortcode[5], $tag ) ) {
       
   168 				return true;
       
   169 			}
   162 		}
   170 		}
   163 	}
   171 	}
   164 	return false;
   172 	return false;
   165 }
   173 }
   166 
   174 
   169  *
   177  *
   170  * If there are no shortcode tags defined, then the content will be returned
   178  * If there are no shortcode tags defined, then the content will be returned
   171  * without any filtering. This might cause issues when plugins are disabled but
   179  * without any filtering. This might cause issues when plugins are disabled but
   172  * the shortcode will still show up in the post or content.
   180  * the shortcode will still show up in the post or content.
   173  *
   181  *
   174  * @since 2.5
   182  * @since 2.5.0
   175  * @uses $shortcode_tags
   183  *
   176  * @uses get_shortcode_regex() Gets the search pattern for searching shortcodes.
   184  * @global array $shortcode_tags List of shortcode tags and their callback hooks.
   177  *
   185  *
   178  * @param string $content Content to search for shortcodes
   186  * @param string $content Content to search for shortcodes.
   179  * @return string Content with shortcodes filtered out.
   187  * @return string Content with shortcodes filtered out.
   180  */
   188  */
   181 function do_shortcode($content) {
   189 function do_shortcode($content) {
   182 	global $shortcode_tags;
   190 	global $shortcode_tags;
       
   191 
       
   192 	if ( false === strpos( $content, '[' ) ) {
       
   193 		return $content;
       
   194 	}
   183 
   195 
   184 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
   196 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
   185 		return $content;
   197 		return $content;
   186 
   198 
   187 	$pattern = get_shortcode_regex();
   199 	$pattern = get_shortcode_regex();
   201  * 3 - The shortcode argument list
   213  * 3 - The shortcode argument list
   202  * 4 - The self closing /
   214  * 4 - The self closing /
   203  * 5 - The content of a shortcode when it wraps some content.
   215  * 5 - The content of a shortcode when it wraps some content.
   204  * 6 - An extra ] to allow for escaping shortcodes with double [[]]
   216  * 6 - An extra ] to allow for escaping shortcodes with double [[]]
   205  *
   217  *
   206  * @since 2.5
   218  * @since 2.5.0
       
   219  *
   207  * @uses $shortcode_tags
   220  * @uses $shortcode_tags
   208  *
   221  *
   209  * @return string The shortcode search regular expression
   222  * @return string The shortcode search regular expression
   210  */
   223  */
   211 function get_shortcode_regex() {
   224 function get_shortcode_regex() {
   248 
   261 
   249 /**
   262 /**
   250  * Regular Expression callable for do_shortcode() for calling shortcode hook.
   263  * Regular Expression callable for do_shortcode() for calling shortcode hook.
   251  * @see get_shortcode_regex for details of the match array contents.
   264  * @see get_shortcode_regex for details of the match array contents.
   252  *
   265  *
   253  * @since 2.5
   266  * @since 2.5.0
   254  * @access private
   267  * @access private
   255  * @uses $shortcode_tags
   268  * @uses $shortcode_tags
   256  *
   269  *
   257  * @param array $m Regular expression match array
   270  * @param array $m Regular expression match array
   258  * @return mixed False on failure.
   271  * @return mixed False on failure.
   282  *
   295  *
   283  * The attributes list has the attribute name as the key and the value of the
   296  * The attributes list has the attribute name as the key and the value of the
   284  * attribute as the value in the key/value pair. This allows for easier
   297  * attribute as the value in the key/value pair. This allows for easier
   285  * retrieval of the attributes, since all attributes have to be known.
   298  * retrieval of the attributes, since all attributes have to be known.
   286  *
   299  *
   287  * @since 2.5
   300  * @since 2.5.0
   288  *
   301  *
   289  * @param string $text
   302  * @param string $text
   290  * @return array List of attributes and their value.
   303  * @return array List of attributes and their value.
   291  */
   304  */
   292 function shortcode_parse_atts($text) {
   305 function shortcode_parse_atts($text) {
   299 				$atts[strtolower($m[1])] = stripcslashes($m[2]);
   312 				$atts[strtolower($m[1])] = stripcslashes($m[2]);
   300 			elseif (!empty($m[3]))
   313 			elseif (!empty($m[3]))
   301 				$atts[strtolower($m[3])] = stripcslashes($m[4]);
   314 				$atts[strtolower($m[3])] = stripcslashes($m[4]);
   302 			elseif (!empty($m[5]))
   315 			elseif (!empty($m[5]))
   303 				$atts[strtolower($m[5])] = stripcslashes($m[6]);
   316 				$atts[strtolower($m[5])] = stripcslashes($m[6]);
   304 			elseif (isset($m[7]) and strlen($m[7]))
   317 			elseif (isset($m[7]) && strlen($m[7]))
   305 				$atts[] = stripcslashes($m[7]);
   318 				$atts[] = stripcslashes($m[7]);
   306 			elseif (isset($m[8]))
   319 			elseif (isset($m[8]))
   307 				$atts[] = stripcslashes($m[8]);
   320 				$atts[] = stripcslashes($m[8]);
   308 		}
   321 		}
   309 	} else {
   322 	} else {
   320  * only contain the attributes in the $pairs list.
   333  * only contain the attributes in the $pairs list.
   321  *
   334  *
   322  * If the $atts list has unsupported attributes, then they will be ignored and
   335  * If the $atts list has unsupported attributes, then they will be ignored and
   323  * removed from the final returned list.
   336  * removed from the final returned list.
   324  *
   337  *
   325  * @since 2.5
   338  * @since 2.5.0
   326  *
   339  *
   327  * @param array $pairs Entire list of supported attributes and their defaults.
   340  * @param array $pairs Entire list of supported attributes and their defaults.
   328  * @param array $atts User defined attributes in shortcode tag.
   341  * @param array $atts User defined attributes in shortcode tag.
   329  * @param string $shortcode Optional. The name of the shortcode, provided for context to enable filtering
   342  * @param string $shortcode Optional. The name of the shortcode, provided for context to enable filtering
   330  * @return array Combined and filtered attribute list.
   343  * @return array Combined and filtered attribute list.
   357 }
   370 }
   358 
   371 
   359 /**
   372 /**
   360  * Remove all shortcode tags from the given content.
   373  * Remove all shortcode tags from the given content.
   361  *
   374  *
   362  * @since 2.5
   375  * @since 2.5.0
       
   376  *
   363  * @uses $shortcode_tags
   377  * @uses $shortcode_tags
   364  *
   378  *
   365  * @param string $content Content to remove shortcode tags.
   379  * @param string $content Content to remove shortcode tags.
   366  * @return string Content without shortcode tags.
   380  * @return string Content without shortcode tags.
   367  */
   381  */
   368 function strip_shortcodes( $content ) {
   382 function strip_shortcodes( $content ) {
   369 	global $shortcode_tags;
   383 	global $shortcode_tags;
       
   384 
       
   385 	if ( false === strpos( $content, '[' ) ) {
       
   386 		return $content;
       
   387 	}
   370 
   388 
   371 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
   389 	if (empty($shortcode_tags) || !is_array($shortcode_tags))
   372 		return $content;
   390 		return $content;
   373 
   391 
   374 	$pattern = get_shortcode_regex();
   392 	$pattern = get_shortcode_regex();
   382 		return substr($m[0], 1, -1);
   400 		return substr($m[0], 1, -1);
   383 	}
   401 	}
   384 
   402 
   385 	return $m[1] . $m[6];
   403 	return $m[1] . $m[6];
   386 }
   404 }
   387 
       
   388 add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop()