do_shortcodes_in_html_tags

Search only inside HTML elements for shortcodes and process them.

Description

(string) do_shortcodes_in_html_tags( (string) $content, (bool) $ignore_html, (string) $tagnames ); 

Any [ or ] characters remaining inside elements will be HTML encoded to prevent interference with shortcodes that are outside the elements. Assumes $content processed by KSES already. Users with unfiltered_html capability may get unexpected output if angle braces are nested in tags.

Returns (string)

Content with shortcodes filtered out.

Parameters (3)

0. $content (string)
Content to search for shortcodes
1. $ignore_html (bool)
When true, all square braces inside elements will be encoded.
2. $tagnames (string)
List of shortcodes to find.

Usage

  1. if ( !function_exists( 'do_shortcodes_in_html_tags' ) ) { 
  2. require_once ABSPATH . WPINC . '/shortcodes.php'; 
  3.  
  4. // Content to search for shortcodes 
  5. $content = ''; 
  6.  
  7. // When true, all square braces inside elements will be encoded. 
  8. $ignore_html = true; 
  9.  
  10. // List of shortcodes to find. 
  11. $tagnames = ''; 
  12.  
  13. // NOTICE! Understand what this does before running. 
  14. $result = do_shortcodes_in_html_tags($content, $ignore_html, $tagnames); 
  15.  

Defined (1)

The function is defined in the following location(s).

/wp-includes/shortcodes.php  
  1. function do_shortcodes_in_html_tags( $content, $ignore_html, $tagnames ) { 
  2. // Normalize entities in unfiltered HTML before adding placeholders. 
  3. $trans = array( '[' => '[', ']' => ']' ); 
  4. $content = strtr( $content, $trans ); 
  5. $trans = array( '[' => '[', ']' => ']' ); 
  6.  
  7. $pattern = get_shortcode_regex( $tagnames ); 
  8. $textarr = wp_html_split( $content ); 
  9.  
  10. foreach ( $textarr as &$element ) { 
  11. if ( '' == $element || '<' !== $element[0] ) { 
  12. continue; 
  13.  
  14. $noopen = false === strpos( $element, '[' ); 
  15. $noclose = false === strpos( $element, ']' ); 
  16. if ( $noopen || $noclose ) { 
  17. // This element does not contain shortcodes. 
  18. if ( $noopen xor $noclose ) { 
  19. // Need to encode stray [ or ] chars. 
  20. $element = strtr( $element, $trans ); 
  21. continue; 
  22.  
  23. if ( $ignore_html || '<!--' === substr( $element, 0, 4 ) || '<![CDATA[' === substr( $element, 0, 9 ) ) { 
  24. // Encode all [ and ] chars. 
  25. $element = strtr( $element, $trans ); 
  26. continue; 
  27.  
  28. $attributes = wp_kses_attr_parse( $element ); 
  29. if ( false === $attributes ) { 
  30. // Some plugins are doing things like [name] <[email]>. 
  31. if ( 1 === preg_match( '%^<\s*\[\[?[^\[\]]+\]%', $element ) ) { 
  32. $element = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $element ); 
  33.  
  34. // Looks like we found some crazy unfiltered HTML. Skipping it for sanity. 
  35. $element = strtr( $element, $trans ); 
  36. continue; 
  37.  
  38. // Get element name 
  39. $front = array_shift( $attributes ); 
  40. $back = array_pop( $attributes ); 
  41. $matches = array(); 
  42. preg_match('%[a-zA-Z0-9]+%', $front, $matches); 
  43. $elname = $matches[0]; 
  44.  
  45. // Look for shortcodes in each attribute separately. 
  46. foreach ( $attributes as &$attr ) { 
  47. $open = strpos( $attr, '[' ); 
  48. $close = strpos( $attr, ']' ); 
  49. if ( false === $open || false === $close ) { 
  50. continue; // Go to next attribute. Square braces will be escaped at end of loop. 
  51. $double = strpos( $attr, '"' ); 
  52. $single = strpos( $attr, "'" ); 
  53. if ( ( false === $single || $open < $single ) && ( false === $double || $open < $double ) ) { 
  54. // $attr like '[shortcode]' or 'name = [shortcode]' implies unfiltered_html. 
  55. // In this specific situation we assume KSES did not run because the input 
  56. // was written by an administrator, so we should avoid changing the output 
  57. // and we do not need to run KSES here. 
  58. $attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr ); 
  59. } else { 
  60. // $attr like 'name = "[shortcode]"' or "name = '[shortcode]'" 
  61. // We do not know if $content was unfiltered. Assume KSES ran before shortcodes. 
  62. $count = 0; 
  63. $new_attr = preg_replace_callback( "/$pattern/", 'do_shortcode_tag', $attr, -1, $count ); 
  64. if ( $count > 0 ) { 
  65. // Sanitize the shortcode output using KSES. 
  66. $new_attr = wp_kses_one_attr( $new_attr, $elname ); 
  67. if ( '' !== trim( $new_attr ) ) { 
  68. // The shortcode is safe to use now. 
  69. $attr = $new_attr; 
  70. $element = $front . implode( '', $attributes ) . $back; 
  71.  
  72. // Now encode any remaining [ or ] chars. 
  73. $element = strtr( $element, $trans ); 
  74.  
  75. $content = implode( '', $textarr ); 
  76.  
  77. return $content;