@@ -320,7 +320,39 @@ function output_shortcodes_for_tinymce() {
320320 }
321321
322322
323- // A filter function that runs do_shortcode() but only with this plugin's shortcodes
323+ /**
324+ * Process only this plugin's shortcodes.
325+ *
326+ * If we waited for the normal do_shortcode() call at priority 11,
327+ * then wpautop() and maybe others would mangle all of the code.
328+ *
329+ * So instead we hook in earlier with this function and process
330+ * just this plugins's shortcodes. To do this requires some trickery.
331+ *
332+ * First we need to clear out all existing shortcodes, then register
333+ * just this plugin's ones, process them, and then restore the original
334+ * list of shortcodes.
335+ *
336+ * To make matters more complicated, if someone has done [[code]foo[/code]]
337+ * in order to display the shortcode (not render it), then do_shortcode()
338+ * will strip the outside brackets and when do_shortcode() runs a second
339+ * time later on, it will render it.
340+ *
341+ * So instead before do_shortcode() runs for the first time, we add
342+ * even more brackets escaped shortcodes in order to result in
343+ * the shortcodes actually being displayed instead rendered.
344+ *
345+ * We only need to do this for this plugin's shortcodes however
346+ * as all other shortcodes such as [[gallery]] will be untouched
347+ * by this pass of do_shortcode.
348+ *
349+ * Phew!
350+ *
351+ * @param string $content The post content.
352+ * @param string $callback The callback function that should be used for add_shortcode()
353+ *
354+ * @return string The filtered content, with this plugin's shortcodes parsed.
355+ */
324356 function shortcode_hack ( $ content , $ callback ) {
325357 global $ shortcode_tags ;
326358
@@ -333,6 +365,13 @@ function shortcode_hack( $content, $callback ) {
333365 add_shortcode ( $ shortcode , $ callback );
334366 }
335367
368+ // Extra escape escaped shortcodes because do_shortcode() is going to strip a pair of square brackets when it runs
369+ $ content = preg_replace_callback (
370+ '/ ' . get_shortcode_regex ( $ this ->shortcodes ) . '/ ' ,
371+ array ( $ this , 'shortcode_hack_extra_escape_escaped_shortcodes ' ),
372+ $ content
373+ );
374+
336375 // Do the shortcodes (only this plugins's are registered)
337376 $ content = do_shortcode ( $ content , true );
338377
@@ -343,6 +382,23 @@ function shortcode_hack( $content, $callback ) {
343382 }
344383
345384
385+ /**
386+ * Add extra square brackets around escaped shortcodes.
387+ * This is to counteract the beginning of the do_shortcode_tag() function.
388+ *
389+ * @param array $match The array of matches generated by get_shortcode_regex()
390+ *
391+ * @return string What should be placed into the post content. In this case it's the raw match, or an extra-wrapped raw match.
392+ */
393+ function shortcode_hack_extra_escape_escaped_shortcodes ( $ match ) {
394+ if ( $ match [1 ] == '[ ' && $ match [6 ] == '] ' ) {
395+ return '[ ' . $ match [0 ] . '] ' ;
396+ }
397+
398+ return $ match [0 ];
399+ }
400+
401+
346402 // The main filter for the post contents. The regular shortcode filter can't be used as it's post-wpautop().
347403 function parse_shortcodes ( $ content ) {
348404 return $ this ->shortcode_hack ( $ content , array ( $ this , 'shortcode_callback ' ) );
0 commit comments