【问题标题】:Is it possible to nest wordpress shortcodes that are the same shortcode?是否可以嵌套相同简码的 wordpress 简码?
【发布时间】:2012-10-22 10:54:01
【问题描述】:

我知道如果使用 do_shortcode 包装器可以嵌套短代码,但是,codex 指出:

“但是,如果使用短代码宏包含另一个同名宏,解析器将失败:”

有没有办法解决这个问题?

例如,如果我有一个短代码来制作一个 div,例如:

[div]some content in a div[/div]

我希望能够使用:

[div]
    [div]a nested div[/div]
[/div]

但是使用标准的 do_shortcode 包装器会失败。

我的临时解决方法是复制短代码,并在名称后附加 _parent,但除非我创建了 div_parent1、div_parent2 等,否则我只能嵌套 1 级...

【问题讨论】:

  • 您要查找的内容记录在 wordpress 文档中:codex.wordpress.org/Shortcode_API#Nested_Shortcodes
  • @hakre 你能指出其中的哪一行显示了它吗 - 从我所见,它只说明了我在问题中引用的内容,即由于无法嵌套同名短代码上下文无关的正则表达式解析器的限制。
  • 好吧,阅读:“短代码解析器正确处理嵌套的短代码宏,只要它们的处理函数通过递归调用do_shortcode()来支持它” - 就这样做。在您自己的短代码挂钩中调用do_shortcode()。这就是它在 Wordpress 中的完成方式。 -- 顺便说一下,这是“嵌套短代码”部分的第一行。
  • 嗯,对,误读了你。然而,这个问题是已知的,大约在两年前就有报道:core.trac.wordpress.org/ticket/14481
  • @hakre 感谢您的输入 - 对于这个特殊的简码,1 级嵌套应该足够了,所以我将坚持使用附加了 _parent 的重复简码。这应该可以为我节省一些处理资源和开发时间。

标签: php wordpress shortcode


【解决方案1】:

如果您正在编写简码,有一个简单的解决方案。您可以编写多个调用相同函数的简码。我有用于创建 html 块(如 div)的简码,并且有几个名称为 div、block1、block2 等。

add_shortcode('div', 'devondev_block');
add_shortcode('block', 'devondev_block');
add_shortcode('block2', 'devondev_block');

它们都调用相同的函数。只要您记得使用不同的短代码,它们就可以嵌套。

WordPress 短代码支持因尝试仅使用正则表达式进行解析而受到影响。可以使用正则表达式、有限状态机和堆栈的混合来进行这种解析。这种方法可以处理嵌套并且速度非常快,尤其是在短代码很少的情况下。每次遇到这种情况我都想尝试一下。

【讨论】:

  • 谢谢 - 正如问题中提到的那样,这是我最终坚持的,但在其中一个的短代码中附加了“_parent”,因为我只需要嵌套 1 层。
【解决方案2】:

API 照原样告诉它,因此这是不可能的:

This is a limitation of the context-free regexp parser used by do_shortcode() - it is very fast but does not count levels of nesting, so it can't match each opening tag with its correct closing tag in these cases.

最新版本(3.4.2)中涉及的功能有:

function do_shortcode($content) {
    global $shortcode_tags;

    if (empty($shortcode_tags) || !is_array($shortcode_tags))
        return $content;

    $pattern = get_shortcode_regex();
    return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
}

function get_shortcode_regex() {
    global $shortcode_tags;
    $tagnames = array_keys($shortcode_tags);
    $tagregexp = join( '|', array_map('preg_quote', $tagnames) );

    // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
    return
          '\\['                              // Opening bracket
        . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
        . "($tagregexp)"                     // 2: Shortcode name
        . '\\b'                              // Word boundary
        . '('                                // 3: Unroll the loop: Inside the opening shortcode tag
        .     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
        .     '(?:'
        .         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
        .         '[^\\]\\/]*'               // Not a closing bracket or forward slash
        .     ')*?'
        . ')'
        . '(?:'
        .     '(\\/)'                        // 4: Self closing tag ...
        .     '\\]'                          // ... and closing bracket
        . '|'
        .     '\\]'                          // Closing bracket
        .     '(?:'
        .         '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
        .             '[^\\[]*+'             // Not an opening bracket
        .             '(?:'
        .                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
        .                 '[^\\[]*+'         // Not an opening bracket
        .             ')*+'
        .         ')'
        .         '\\[\\/\\2\\]'             // Closing shortcode tag
        .     ')?'
        . ')'
        . '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
}

【讨论】:

  • 是的,我明白了。我在问是否有办法解决它 - 即不使用 do_shortcode 但可能是一些类似的函数,它不使用上下文无关的正则表达式解析器,而是一个计算嵌套级别的解析器
  • 理论上你可以这样做,但你必须不使用标准的短代码功能并将其附加到 the_content 过滤器或类似的东西。最好不要使用 [shortcode] 语法以避免与 Wordpress 冲突。
  • 你也会牺牲性能,解析嵌套模式的内容会很昂贵。
  • 查看wp-incudes/shortcodes.php - 您需要复制此功能并编写自己的正则表达式解析器,因为没有用于修改此行为的挂钩。
  • 感谢您的输入 - 对于这个特定的简码,1 级嵌套应该足够了,所以我将坚持使用附加了 _parent 的重复简码。这应该可以为我节省一些处理资源和开发时间。
【解决方案3】:

您需要为您的简码中的内容再次执行简码。示例:

add_shortcode('div', function($attributes, $content, $tag) {
    ...
    do_shortcode($content);
    ...
});

另请参阅:What is the best way to enable nested shortcodes? (Wordpress SE)

刚刚看到:这并不能解决 Wordpress 中的问题,因此无法回答您的问题。我以为直到现在它都会被修复。

【讨论】:

  • 根据文档,这不适用于相同的嵌套短代码。
  • 哦,即使 PCRE 支持,他们还没有使用递归?嗯,嗯,那么这确实需要 Wordpress 的错误报告,并且是软件的限制。修补 get_shortcode_regex 应该可以解决这个问题。让我看看是否存在补丁。
  • @doublesharp:也许吧。在任何情况下,正则表达式看起来都不是那么好,所以实际上性能方面无论如何都可以改进。
  • 同意,但现在就是这样,尽管如果你为这个正则表达式提供更好的补丁,很多人会喜欢你的 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-07
  • 2021-03-30
  • 2011-06-13
  • 1970-01-01
相关资源
最近更新 更多