Wordpress外部短代码解析内部短代码内容的html标签

时间:2016-11-02 21:35:04

标签: wordpress

我将编写一些示例代码,因此它是我遇到的问题的缩写示例。

我们说我在数据库中存储了以下文字:



[form]
  <ul>
    [each name="upgrades"]
      <li><input type="checkbox" [value name="upgrade_name" id="1"] />[value name="upgrade_name" id="2"]</li>
    [/each]
  </ul>
[/form]
&#13;
&#13;
&#13;

如果我在此文本上运行do_shortcode,则会解析each内容中的INSIDE html标记内的短代码而不是延迟到each短代码。但是,each内容中的each短代码运行do_shortcode后才会解析value内容中不在html标记中的短代码,这应该是正确的行为。< / p>

换句话说,标识为1的{​​{1}}短代码过早解析(form短代码传递),但value短代码为2each短代码运行do_shortcode之前,不会对其进行解析,因此它会生成正确的值。

我知道我可以将表单短代码上的ignore_html标志设置为true,但这是不正确的,因为用户可能希望为短代码解析html标签。

此行为是否有解决方法?

Wordpress版本4.6.1

编辑:添加可重现的代码

使用以下代码创建一个新插件:

&#13;
&#13;
<?php
/*
Plugin Name: Broken Shortcodes
Description: Shortcodes should not jump the gun in parsing html tag shortcodes of inner shortcode content.
*/

remove_filter('the_content', 'wpautop');

add_shortcode('form', function($atts, $content){
  echo "<textarea>This is the form's content:\n".$content.'</textarea>';
  return "<textarea>This is the rendered form shortcode:\n".do_shortcode($content).'</textarea>';
});

$bad_global_variable = 'first';

add_shortcode('value', function($atts, $content){
  global $bad_global_variable;
  return $bad_global_variable;
});

add_shortcode('each', function($atts, $content){
  global $bad_global_variable;
  $_content = '';
  foreach(array('second', 'third', 'fourth') as $v){
    $bad_global_variable = $v;
    $_content .= do_shortcode($content);
  }
  return $_content;
});



?>
&#13;
&#13;
&#13;

使用以下文字创建一个页面:

&#13;
&#13;
[form]
  [each]
    <div [value]>[value]</div>
  [/each]
[/form]
&#13;
&#13;
&#13;

输出不正确:

&#13;
&#13;
  
<div first>second</div>

<div first>third</div>

<div first>second</div>

<div first>fourth</div>

<div first>second</div>

<div first>third</div>

<div first>second</div>
  
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

快速解决方法是从html标记中解析自己的短代码。

所以你的文字看起来像是:

[form]
  [each]
    <!-- Notice curly brackets -->
    <div {value}>[value]</div>
  [/each]
[/form]

然后你的每个短代码可能如下所示:

add_shortcode('each', function($atts, $content){
  global $bad_global_variable;
  $content = preg_replace('/\{([^}]+)\}/', '[$1]', $content, -1);
  $_content = '';
  add_filter( 'wp_kses_allowed_html', 'parse_tags', 10, 2 );
  foreach(array('second', 'third', 'fourth') as $v){
    $bad_global_variable = $v;
    $_content .= do_shortcode($content);
  }
  remove_filter( 'wp_kses_allowed_html', 'parse_tags', 10, 2 );
  return $_content;
});

// This might be necessary depending on your use-case
function parse_tags($tags, $context){
  $tags['input']['value'] = true;
  return $tags;
}

但是,这不应该是看似简单的事情的解决方案。我认为Shortcode API需要一些TLC。

在此处查看门票:https://core.trac.wordpress.org/ticket/33134