WordPress是否支持从短码调用中调用自身的短码?

时间:2012-10-24 作者:Dwayne Charrington

我构建了一个超级疯狂的Wordpress框架,它有一百万个短代码,其中之一是一个列短代码,它支持一个count参数,允许您定义一个列,并将添加相应的类。

My shortcode is as follows:

add_shortcode(\'column\', \'column_shortcode\');
function column_shortcode($atts, $content = \'\')
{
    extract(shortcode_atts(array(
       \'count\' => 12
    ), $atts));

    if (stripos($count, \'_\') === FALSE)
    {
        if ((int) $count > 12)
        {
            $count = 12;
        }
    }

    $html = \'<div class="column-\'.$count.\' column">\';
    $html .= do_shortcode($content);
    $html .= \'</div>\';

    return $html;
}
然而,当在列中使用列短代码时,似乎存在一个问题,这是一个已知问题还是Wordpress不支持将相同名称的短代码嵌套在另一个列中?

实际上,在输出的HTML中,内部的列被过早地关闭了,我看到在前端显示了用段落标记包装的[/column]。然而,如果我创建另一个快捷码并将其称为child,则使用与上面完全相同的代码,只有child shrotcode只是[child],而不是[column],一切都按预期工作。

以下是Wordpress安装中所见即所得编辑器的代码。图表A是理想的场景,我不想使用两个不同的短代码来完成相同的事情。附件B是通过简单地复制短代码来实现的。

Exhibit A - does not work

[column count="9"]

[column count="8_9"]

Welcome to the site.

Who\'s brave enough to fly into something we all keep calling a death sphere? Well, then good news! It\'s a suppository. A true inspiration for the children. Ah, computer dating. It\'s like pimping, but you rarely have to use the phrase "upside your head."

[/column]

[/column]

Exhibit B - works

[column count="9"]

[child count="8_9"]

Welcome to the site.

Who\'s brave enough to fly into something we all keep calling a death sphere? Well, then good news! It\'s a suppository. A true inspiration for the children. Ah, computer dating. It\'s like pimping, but you rarely have to use the phrase "upside your head."

[/child]

[/column]

3 个回复
最合适的回答,由SO网友:Mridul Aggarwal 整理而成

这是一个已知的问题。如果您在另一个具有相同名称的短代码中有一个短代码,wordpress解析器将无法正确处理它们。这在codex page for shortcode API 在限制下。

从链接页面However the parser will fail if a shortcode macro is used to enclose another macro of the same name

我建议的解决方案是向主快捷码调用添加额外的参数&;在shortcode函数中,根据是否存在这些额外参数递归调用自身

示例

[column count="9" child="8_9" 8_9_text="

Welcome to the site.

Who\'s brave enough to fly into something we all keep calling a death sphere? Well, then good news! It\'s a suppository. A true inspiration for the children. Ah, computer dating. It\'s like pimping, but you rarely have to use the phrase "upside your head."
" /]
然后在代码中

function shortcode_handler($atts, $content, $tag) {
    if(isset($atts[\'child\']))
        $output = shortcode_handler(array(\'count\'=>$atts[\'child\']), $atts[$atts[\'child\'].\'_text\'])

    // Do something else with the output

}
我知道这看起来不太好,但也许你可以在应用程序的上下文中解决一些问题。

SO网友:Trey Welstad

我编写了一个小函数,它将启用自身的短代码。它应该能很好地解决你的问题。这对我非常有帮助。

打开文件“wp includes/shortcode”。并将do\\u shortcode()函数(第201行)更改为

function do_shortcode($content) {
    global $shortcode_tags;

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

    $content = enable_recursive_shortcodes($content);

    $pattern = get_shortcode_regex();
    return preg_replace_callback( "/$pattern/s", \'do_shortcode_tag\', $content );
}
所有更改都是添加*$内容=enable\\u recursive\\u短代码($内容)*

该函数遍历传递给它的$内容,并为其内部的短代码的短代码名称添加后缀。然后只处理外部的短码,当处理它们的内容时,后缀将被删除,从而允许处理它们。它的深度是无限的。(示例:[框][框][框][框]内容][框][框][框])

在do\\u shortcode()函数上方添加以下函数

/**
 * Add shortcode suffix enabling recursive shortchodes.
 *
 * This function goes inside the set of $recursive_tags and adds a suffix to
 * the shortcode name so it will allow a shortcode to call itself in its content
 *
 * @since 2.5
 * @return string Content with recursive shortcodes modified out.
 */
function enable_recursive_shortcodes($content) {

    $recursive_tags = array( \'column\', \'div\', \'span\', \'table\' ); // define recursive shortcodes, these must have closing tags 
    $suffix = \'__recursive\'; // suffix is added to the tag of recursive shortcodes

    $content = str_replace( $suffix, \'\', $content ); // remove old suffix on shortcodes to start process over

    foreach( $recursive_tags as $recursive_tag ) {

        $open_tag = \'[\' . $recursive_tag . \' \';
        $close_tag = \'[/\'. $recursive_tag . \']\';

        $open_tags = 0;

        $open_pos = stripos( $content, $open_tag ); // find first opening tag

        $offset = $open_pos + strlen( $open_tag ); // set offset for first closing tag

        while( $open_pos !== false ) {

            $close_pos = stripos( $content, $close_tag, $offset ); // find first closing tag

            if(++$open_tags > 1) { // if we are inside an open tag

                // modify open tag from original shortcode name
                $content = substr( $content, 0, $open_pos ) . 
                            \'[\' .$recursive_tag . $suffix . \' \' . 
                              substr( $content, $offset ); 
                // modify closing tag from original shortcode name
                $content = substr( $content, 0, $close_pos + strlen($suffix) ) . 
                            \'[/\'.$recursive_tag.\'__recursive]\' . 
                            substr( $content, $close_pos + strlen( $close_tag ) + strlen($suffix) ); 
                $open_tags--;
            }

            $open_pos = stripos( $content, $open_tag, $offset ); // find next opening tag

            if( $close_pos < $open_pos ) $open_tags--; // if closing tag comes before next opening tag, lower open tag count

            $offset = $open_pos + strlen($open_tag); // set new offset for next open tag search

        }

    }

    return $content;

}
请确保根据需要更新$recursive\\u tags变量。只有这些标记才会检查同名子项。这些标记必须有结束标记[列][列],因为[列/]不起作用。由于函数在标记中的搜索方式,它们在开始标记中的短代码名称后面必须有空格,而在结束标记中必须没有空格。如果有人更新代码以允许[列]或[列/]样式的短代码工作,请共享。

SO网友:John Watkins

我找到的最简单的解决方案(虽然可能不是最好的)是在轻微变化的情况下多次添加标记。例如,在提问者的情况下,可能是:

function render_column( $atts, $content ) {
    // etc.

    return apply_filters( \'the_content\', $content );
}

add_shortcode( \'column\', \'render_column\' );
add_shortcode( \'column-level-2\', \'render_column\' );
add_shortcode( \'column-level-3\', \'render_column\' );
这需要一些额外的文档,有些用户可能无法立即掌握,但我觉得这比要求用户将短代码的内容放入属性中要直观一些。当然,该解决方案引入了在短代码属性中处理引号的单独问题。

结束

相关推荐

通过Java脚本for Google Maps API从Custom Post中提取地址

我创建了一个带有自定义帖子的主题,并将其输出到带有位置标记的谷歌地图。用户将创建一个自定义贴子用户,并包括街道地址,这些地址将使用谷歌地图API v3进行地理编码,并在谷歌地图上放置一个标记。我对自定义Wordpress主题的编码和设计相对较新,因此我正在尝试用javascript为Google Maps API从每个自定义帖子中获取信息。有人能解释一下这是怎么做到的吗?谢谢,AME