146 |
146 |
147 if (empty($shortcode_tags) || !is_array($shortcode_tags)) |
147 if (empty($shortcode_tags) || !is_array($shortcode_tags)) |
148 return $content; |
148 return $content; |
149 |
149 |
150 $pattern = get_shortcode_regex(); |
150 $pattern = get_shortcode_regex(); |
151 return preg_replace_callback('/'.$pattern.'/s', 'do_shortcode_tag', $content); |
151 return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content ); |
152 } |
152 } |
153 |
153 |
154 /** |
154 /** |
155 * Retrieve the shortcode regular expression for searching. |
155 * Retrieve the shortcode regular expression for searching. |
156 * |
156 * |
157 * The regular expression combines the shortcode tags in the regular expression |
157 * The regular expression combines the shortcode tags in the regular expression |
158 * in a regex class. |
158 * in a regex class. |
159 * |
159 * |
160 * The regular expresion contains 6 different sub matches to help with parsing. |
160 * The regular expression contains 6 different sub matches to help with parsing. |
161 * |
161 * |
162 * 1/6 - An extra [ or ] to allow for escaping shortcodes with double [[]] |
162 * 1 - An extra [ to allow for escaping shortcodes with double [[]] |
163 * 2 - The shortcode name |
163 * 2 - The shortcode name |
164 * 3 - The shortcode argument list |
164 * 3 - The shortcode argument list |
165 * 4 - The self closing / |
165 * 4 - The self closing / |
166 * 5 - The content of a shortcode when it wraps some content. |
166 * 5 - The content of a shortcode when it wraps some content. |
|
167 * 6 - An extra ] to allow for escaping shortcodes with double [[]] |
167 * |
168 * |
168 * @since 2.5 |
169 * @since 2.5 |
169 * @uses $shortcode_tags |
170 * @uses $shortcode_tags |
170 * |
171 * |
171 * @return string The shortcode search regular expression |
172 * @return string The shortcode search regular expression |
173 function get_shortcode_regex() { |
174 function get_shortcode_regex() { |
174 global $shortcode_tags; |
175 global $shortcode_tags; |
175 $tagnames = array_keys($shortcode_tags); |
176 $tagnames = array_keys($shortcode_tags); |
176 $tagregexp = join( '|', array_map('preg_quote', $tagnames) ); |
177 $tagregexp = join( '|', array_map('preg_quote', $tagnames) ); |
177 |
178 |
178 // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcodes() |
179 // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag() |
179 return '(.?)\[('.$tagregexp.')\b(.*?)(?:(\/))?\](?:(.+?)\[\/\2\])?(.?)'; |
180 return |
|
181 '\\[' // Opening bracket |
|
182 . '(\\[?)' // 1: Optional second opening bracket for escaping shortcodes: [[tag]] |
|
183 . "($tagregexp)" // 2: Shortcode name |
|
184 . '\\b' // Word boundary |
|
185 . '(' // 3: Unroll the loop: Inside the opening shortcode tag |
|
186 . '[^\\]\\/]*' // Not a closing bracket or forward slash |
|
187 . '(?:' |
|
188 . '\\/(?!\\])' // A forward slash not followed by a closing bracket |
|
189 . '[^\\]\\/]*' // Not a closing bracket or forward slash |
|
190 . ')*?' |
|
191 . ')' |
|
192 . '(?:' |
|
193 . '(\\/)' // 4: Self closing tag ... |
|
194 . '\\]' // ... and closing bracket |
|
195 . '|' |
|
196 . '\\]' // Closing bracket |
|
197 . '(?:' |
|
198 . '(' // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags |
|
199 . '[^\\[]*+' // Not an opening bracket |
|
200 . '(?:' |
|
201 . '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag |
|
202 . '[^\\[]*+' // Not an opening bracket |
|
203 . ')*+' |
|
204 . ')' |
|
205 . '\\[\\/\\2\\]' // Closing shortcode tag |
|
206 . ')?' |
|
207 . ')' |
|
208 . '(\\]?)'; // 6: Optional second closing brocket for escaping shortcodes: [[tag]] |
180 } |
209 } |
181 |
210 |
182 /** |
211 /** |
183 * Regular Expression callable for do_shortcode() for calling shortcode hook. |
212 * Regular Expression callable for do_shortcode() for calling shortcode hook. |
184 * @see get_shortcode_regex for details of the match array contents. |
213 * @see get_shortcode_regex for details of the match array contents. |
188 * @uses $shortcode_tags |
217 * @uses $shortcode_tags |
189 * |
218 * |
190 * @param array $m Regular expression match array |
219 * @param array $m Regular expression match array |
191 * @return mixed False on failure. |
220 * @return mixed False on failure. |
192 */ |
221 */ |
193 function do_shortcode_tag($m) { |
222 function do_shortcode_tag( $m ) { |
194 global $shortcode_tags; |
223 global $shortcode_tags; |
195 |
224 |
196 // allow [[foo]] syntax for escaping a tag |
225 // allow [[foo]] syntax for escaping a tag |
197 if ($m[1] == '[' && $m[6] == ']') { |
226 if ( $m[1] == '[' && $m[6] == ']' ) { |
198 return substr($m[0], 1, -1); |
227 return substr($m[0], 1, -1); |
199 } |
228 } |
200 |
229 |
201 $tag = $m[2]; |
230 $tag = $m[2]; |
202 $attr = shortcode_parse_atts($m[3]); |
231 $attr = shortcode_parse_atts( $m[3] ); |
203 |
232 |
204 if ( isset($m[5]) ) { |
233 if ( isset( $m[5] ) ) { |
205 // enclosing tag - extra parameter |
234 // enclosing tag - extra parameter |
206 return $m[1] . call_user_func($shortcode_tags[$tag], $attr, $m[5], $m[2]) . $m[6]; |
235 return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, $m[5], $tag ) . $m[6]; |
207 } else { |
236 } else { |
208 // self-closing tag |
237 // self-closing tag |
209 return $m[1] . call_user_func($shortcode_tags[$tag], $attr, NULL, $m[2]) . $m[6]; |
238 return $m[1] . call_user_func( $shortcode_tags[$tag], $attr, null, $tag ) . $m[6]; |
210 } |
239 } |
211 } |
240 } |
212 |
241 |
213 /** |
242 /** |
214 * Retrieve all attributes from the shortcodes tag. |
243 * Retrieve all attributes from the shortcodes tag. |
288 if (empty($shortcode_tags) || !is_array($shortcode_tags)) |
317 if (empty($shortcode_tags) || !is_array($shortcode_tags)) |
289 return $content; |
318 return $content; |
290 |
319 |
291 $pattern = get_shortcode_regex(); |
320 $pattern = get_shortcode_regex(); |
292 |
321 |
293 return preg_replace('/'.$pattern.'/s', '$1$6', $content); |
322 return preg_replace_callback( "/$pattern/s", 'strip_shortcode_tag', $content ); |
|
323 } |
|
324 |
|
325 function strip_shortcode_tag( $m ) { |
|
326 // allow [[foo]] syntax for escaping a tag |
|
327 if ( $m[1] == '[' && $m[6] == ']' ) { |
|
328 return substr($m[0], 1, -1); |
|
329 } |
|
330 |
|
331 return $m[1] . $m[6]; |
294 } |
332 } |
295 |
333 |
296 add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop() |
334 add_filter('the_content', 'do_shortcode', 11); // AFTER wpautop() |
297 |
|
298 ?> |
|