[ Index ]

PHP Cross Reference of BackPress

title

Body

[close]

/includes/ -> functions.shortcodes.php (source)

   1  <?php
   2  // Last sync [WP12206]
   3  
   4  /**
   5   * WordPress API for creating bbcode like tags or what WordPress calls
   6   * "shortcodes." The tag and attribute parsing or regular expression code is
   7   * based on the Textpattern tag parser.
   8   *
   9   * A few examples are below:
  10   *
  11   * [shortcode /]
  12   * [shortcode foo="bar" baz="bing" /]
  13   * [shortcode foo="bar"]content[/shortcode]
  14   *
  15   * Shortcode tags support attributes and enclosed content, but does not entirely
  16   * support inline shortcodes in other shortcodes. You will have to call the
  17   * shortcode parser in your function to account for that.
  18   *
  19   * {@internal
  20   * Please be aware that the above note was made during the beta of WordPress 2.6
  21   * and in the future may not be accurate. Please update the note when it is no
  22   * longer the case.}}
  23   *
  24   * To apply shortcode tags to content:
  25   *
  26   * <code>
  27   * $out = do_shortcode($content);
  28   * </code>
  29   *
  30   * @link http://codex.wordpress.org/Shortcode_API
  31   *
  32   * @package WordPress
  33   * @subpackage Shortcodes
  34   * @since 2.5
  35   */
  36  
  37  /**
  38   * Container for storing shortcode tags and their hook to call for the shortcode
  39   *
  40   * @since 2.5
  41   * @name $shortcode_tags
  42   * @var array
  43   * @global array $shortcode_tags
  44   */
  45  $shortcode_tags = array();
  46  
  47  /**
  48   * Add hook for shortcode tag.
  49   *
  50   * There can only be one hook for each shortcode. Which means that if another
  51   * plugin has a similar shortcode, it will override yours or yours will override
  52   * theirs depending on which order the plugins are included and/or ran.
  53   *
  54   * Simplest example of a shortcode tag using the API:
  55   *
  56   * <code>
  57   * // [footag foo="bar"]
  58   * function footag_func($atts) {
  59   *     return "foo = {$atts[foo]}";
  60   * }
  61   * add_shortcode('footag', 'footag_func');
  62   * </code>
  63   *
  64   * Example with nice attribute defaults:
  65   *
  66   * <code>
  67   * // [bartag foo="bar"]
  68   * function bartag_func($atts) {
  69   *     extract(shortcode_atts(array(
  70   *         'foo' => 'no foo',
  71   *         'baz' => 'default baz',
  72   *     ), $atts));
  73   *
  74   *     return "foo = {$foo}";
  75   * }
  76   * add_shortcode('bartag', 'bartag_func');
  77   * </code>
  78   *
  79   * Example with enclosed content:
  80   *
  81   * <code>
  82   * // [baztag]content[/baztag]
  83   * function baztag_func($atts, $content='') {
  84   *     return "content = $content";
  85   * }
  86   * add_shortcode('baztag', 'baztag_func');
  87   * </code>
  88   *
  89   * @since 2.5
  90   * @uses $shortcode_tags
  91   *
  92   * @param string $tag Shortcode tag to be searched in post content.
  93   * @param callable $func Hook to run when shortcode is found.
  94   */
  95  function add_shortcode($tag, $func) {
  96      global $shortcode_tags;
  97  
  98      if ( is_callable($func) )
  99          $shortcode_tags[$tag] = $func;
 100  }
 101  
 102  /**
 103   * Removes hook for shortcode.
 104   *
 105   * @since 2.5
 106   * @uses $shortcode_tags
 107   *
 108   * @param string $tag shortcode tag to remove hook for.
 109   */
 110  function remove_shortcode($tag) {
 111      global $shortcode_tags;
 112  
 113      unset($shortcode_tags[$tag]);
 114  }
 115  
 116  /**
 117   * Clear all shortcodes.
 118   *
 119   * This function is simple, it clears all of the shortcode tags by replacing the
 120   * shortcodes global by a empty array. This is actually a very efficient method
 121   * for removing all shortcodes.
 122   *
 123   * @since 2.5
 124   * @uses $shortcode_tags
 125   */
 126  function remove_all_shortcodes() {
 127      global $shortcode_tags;
 128  
 129      $shortcode_tags = array();
 130  }
 131  
 132  /**
 133   * Search content for shortcodes and filter shortcodes through their hooks.
 134   *
 135   * If there are no shortcode tags defined, then the content will be returned
 136   * without any filtering. This might cause issues when plugins are disabled but
 137   * the shortcode will still show up in the post or content.
 138   *
 139   * @since 2.5
 140   * @uses $shortcode_tags
 141   * @uses get_shortcode_regex() Gets the search pattern for searching shortcodes.
 142   *
 143   * @param string $content Content to search for shortcodes
 144   * @return string Content with shortcodes filtered out.
 145   */
 146  function do_shortcode($content) {
 147      global $shortcode_tags;
 148  
 149      if (empty($shortcode_tags) || !is_array($shortcode_tags))
 150          return $content;
 151  
 152      $pattern = get_shortcode_regex();
 153      return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content);
 154  }
 155  
 156  /**
 157   * Retrieve the shortcode regular expression for searching.
 158   *
 159   * The regular expression combines the shortcode tags in the regular expression
 160   * in a regex class.
 161   *
 162   * The regular expresion contains 6 different sub matches to help with parsing.
 163   *
 164   * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]]
 165   * 2 - The shortcode name
 166   * 3 - The shortcode argument list
 167   * 4 - The self closing /
 168   * 5 - The content of a shortcode when it wraps some content.
 169   *
 170   * @since 2.5
 171   * @uses $shortcode_tags
 172   *
 173   * @return string The shortcode search regular expression
 174   */
 175  function get_shortcode_regex() {
 176      global $shortcode_tags;
 177      $tagnames = array_keys($shortcode_tags);
 178      $tagregexp = join( '|', array_map('preg_quote', $tagnames) );
 179  
 180      // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes()
 181      return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)';
 182  }
 183  
 184  /**
 185   * Regular Expression callable for do_shortcode() for calling shortcode hook.
 186   * @see get_shortcode_regex for details of the match array contents.
 187   *
 188   * @since 2.5
 189   * @access private
 190   * @uses $shortcode_tags
 191   *
 192   * @param array $m Regular expression match array
 193   * @return mixed False on failure.
 194   */
 195  function do_shortcode_tag($m) {
 196      global $shortcode_tags;
 197  
 198      // allow [[foo]] syntax for escaping a tag
 199      if ($m[1] == '[' && $m[6] == ']') {
 200          return substr($m[0], 1, -1);
 201      }
 202  
 203      $tag = $m[2];
 204      $attr = shortcode_parse_atts($m[3]);
 205  
 206      if ( isset($m[5]) ) {
 207          // enclosing tag - extra parameter
 208          return $m[1] . call_user_func($shortcode_tags[$tag], $attr, $m[5], $m[2]) . $m[6];
 209      } else {
 210          // self-closing tag
 211          return $m[1] . call_user_func($shortcode_tags[$tag], $attr, NULL, $m[2]) . $m[6];
 212      }
 213  }
 214  
 215  /**
 216   * Retrieve all attributes from the shortcodes tag.
 217   *
 218   * The attributes list has the attribute name as the key and the value of the
 219   * attribute as the value in the key/value pair. This allows for easier
 220   * retrieval of the attributes, since all attributes have to be known.
 221   *
 222   * @since 2.5
 223   *
 224   * @param string $text
 225   * @return array List of attributes and their value.
 226   */
 227  function shortcode_parse_atts($text) {
 228      $atts = array();
 229      $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/';
 230      $text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text);
 231      if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) ) {
 232          foreach ($match as $m) {
 233              if (!empty($m[1]))
 234                  $atts[strtolower($m[1])] = stripcslashes($m[2]);
 235              elseif (!empty($m[3]))
 236                  $atts[strtolower($m[3])] = stripcslashes($m[4]);
 237              elseif (!empty($m[5]))
 238                  $atts[strtolower($m[5])] = stripcslashes($m[6]);
 239              elseif (isset($m[7]) and strlen($m[7]))
 240                  $atts[] = stripcslashes($m[7]);
 241              elseif (isset($m[8]))
 242                  $atts[] = stripcslashes($m[8]);
 243          }
 244      } else {
 245          $atts = ltrim($text);
 246      }
 247      return $atts;
 248  }
 249  
 250  /**
 251   * Combine user attributes with known attributes and fill in defaults when needed.
 252   *
 253   * The pairs should be considered to be all of the attributes which are
 254   * supported by the caller and given as a list. The returned attributes will
 255   * only contain the attributes in the $pairs list.
 256   *
 257   * If the $atts list has unsupported attributes, then they will be ignored and
 258   * removed from the final returned list.
 259   *
 260   * @since 2.5
 261   *
 262   * @param array $pairs Entire list of supported attributes and their defaults.
 263   * @param array $atts User defined attributes in shortcode tag.
 264   * @return array Combined and filtered attribute list.
 265   */
 266  function shortcode_atts($pairs, $atts) {
 267      $atts = (array)$atts;
 268      $out = array();
 269      foreach($pairs as $name => $default) {
 270          if ( array_key_exists($name, $atts) )
 271              $out[$name] = $atts[$name];
 272          else
 273              $out[$name] = $default;
 274      }
 275      return $out;
 276  }
 277  
 278  /**
 279   * Remove all shortcode tags from the given content.
 280   *
 281   * @since 2.5
 282   * @uses $shortcode_tags
 283   *
 284   * @param string $content Content to remove shortcode tags.
 285   * @return string Content without shortcode tags.
 286   */
 287  function strip_shortcodes( $content ) {
 288      global $shortcode_tags;
 289  
 290      if (empty($shortcode_tags) || !is_array($shortcode_tags))
 291          return $content;
 292  
 293      $pattern = get_shortcode_regex();
 294  
 295      return preg_replace('/'.$pattern.'/s', '$1$6', $content);
 296  }


Generated: Thu Dec 26 01:01:01 2024 Cross-referenced by PHPXref 0.7.1