WordPress基于其他短代码的短代码

时间:2017-09-21 07:36:59

标签: php wordpress shortcode

我正在处理2个WordPress短代码:

  1. 一章。 [章节名称=“开始”] ......内容...... [/ chapter]
  2. 目录[toc] [/ toc]。 toc需要显示一个简单的章节列表。
  3. 规格:

    • 帖子中可以有很多章节。
    • 帖子中可以有一个,两个或没有toc短代码。
    • toc可以在章节之前或之后,也可以在之前和之后。这取决于帖子作者所以我事先不知道。
    • 我不能使用嵌套的短代码,因为编写者很难使用它们。

    我想过使用静态toc数组在每个章节标签上添加章节,然后在toc短代码中输出。唉,toc短代码可以出现在章节之前,然后数组将为空。

    以下帖子html不会显示toc:

    [toc][/toc]
    Here is some content
    [chapter name="hello"]xxx[/chapter]
    In between content may come here
    [chapter name="world"]yyy[/chapter]
    Some more stuff
    

    这是我的开始代码(嵌入在类中):

    public static function register_chapter_shortcode($atts, $content=null){
        $atts = shortcode_atts (
            array (
                'name'       => '',
            ), $atts );
    
        $name = $atts["name"];
        if (self::$toc == null){
            self::$toc = array ($name);
        } else {
            array_push(self::$toc, $name);
        }
        return '
            <h2>'.$atts["name"].'</h2>
            <div>'.do_shortcode($content).'</div>'
        ;
    }
    
    public static function register_toc_shortcode($atts, $content=null){
        $items = "";
        foreach (self::$toc as $item){
            $items = $items. '<li><a href="#">'.$item.'</a></li>';
        }
        return '
            <ul>'.$items.'</ul>            
        ';
    }
    

1 个答案:

答案 0 :(得分:0)

问题在于运行函数的顺序:register_toc_shortcoderegister_chapter_shortcode设置self::$toc之前运行,因此无法显示任何内容。这意味着[toc]必须在[chapter]短代码之后。这个问题是你需要在列出章节之前显示TOC。

正如我在评论中提到的,我可以看到两种解决方法 - 一种是使用javascript将TOC插入DOM中,但如果可能的话我会避免这种情况。

另一种方法是使用register_chapter_shortcode在<{1}}中存储所有内容,并且不输出任何内容。然后self::$toc可以显示所有内容。

这未经过测试,但其背后的基本逻辑应该是正确的:

register_toc_shortcode

然后您可以按如下方式使用它:

public static function register_chapter_shortcode($atts, $content=null){
    $atts = shortcode_atts (
        array (
            'name'       => '',
        ), $atts );

    if (self::$toc == null)
        self::$toc = array ();

    /* add ALL info to self::$toc in an array */
    array_push(self::$toc, array("name" => $atts["name"], "content" => $content));
}

public static function register_toc_shortcode($atts, $content=null){
    /* add the ability to pass in the position of the toc, as required in your comment */
    $atts = shortcode_atts (
        array (
            'position' => 'top', /* e.g. "top" (default), "bottom", "both" */
        ), $atts );

    /* generate the HTML for the TOC */
    $toc_html = "<ul>";
    foreach (self::$toc as $item){
        $toc_html .= '<li><a href="#">'.$item["name"].'</a></li>';
    }
    $toc_html .= "</ul>";

    /* generate the HTML for the chapters */
    $chapters = "";
    foreach (self::$toc as $item){
        $chapters .= '<h2>'.$item["name"].'</h2>
        <div>'.do_shortcode($item["content").'</div>';
    }

    /* generate the output, putting the TOC at the top or bottom as required */
    $html = "";
    if ($position == "top" || $position == "both") $html .= $toc_html;
    $html .= $chapters;
    if ($position == "bottom" || $position == "both") $html .= $toc_html;

    return $html;
}

注意:[chapter name="hello"]xxx[/chapter] [chapter name="world"]yyy[/chapter] [toc position="top"][/toc] 总是必须在[toc]之后,以便为chapter设置它们以显示详细信息。