插件包装了整个内容

时间:2020-08-25 作者:loliki

我制作了一个小插件,可以从我的另一个博客中获取帖子,并使用一个短代码进行渲染:

<div class="blog__grid">
        <?php
            // If there are posts.
            if ( ! empty( $posts ) ) {

                // For each post.
                foreach ( $posts as $post ) {

                    $featured_img = $post->_embedded->{\'wp:featuredmedia\'}[0]->source_url;
                    $ecerpt = $post->excerpt->rendered;
                    // Format the date.
                    $fordate = date( \'n/j/Y\', strtotime( $post->modified ) );


                    // Show a linked title and post date.
                    ?>
                    <?php
                    $allposts .= "<div class=\'blog__grid__post\'>
                    <div class=\'blog__grid__post__image\'>
                        <img class=\'blog__grid__post__image--img\' src=\'{$featured_img}\' />
                        <a class=\'blog__grid__link\' href=\'/blog/" .$post->slug. "\'>"
                        . esc_html( $post->title->rendered ) .
                        \'</a>
                    </div>
                        <div class="blog__grid__post__meta">\'
                        . esc_html( $fordate ) .
                        \'</div>
                        <div class="blog__grid__post__excerpt">\'
                            .$ecerpt.
                        "</div>
                    </div>";

                }

            return $allposts;
        } ?>
    </div>
现在,当我尝试向使用此短代码的页面添加更多内容时,我编写的所有内容都封装在blog__grid tag,这是inspector的截图,突出显示的元素不应该在这个分区内,我不知道为什么,有人能帮我吗?

enter image description here

1 个回复
最合适的回答,由SO网友:Tom J Nowell 整理而成

有两个主要问题。

第一个是直接在短代码中输出开头divShortcodes must never echo or output directly, they always return a HTML string

因此,在显示帖子内容之前,已经将其发送到浏览器:

<div class="blog__grid">
你很幸运你用这个包装了整个帖子内容,否则你会注意到开头标签总是在开头。

不仅如此,还有:

处理此帖子的AJAX请求将被破坏,REST API端点将被破坏,XMLRPC将被破坏,网站地图将被破坏,如果您的短代码支持嵌套内容,则该内容将出现在短代码之后,而不是短代码内部,如果此短代码出现在另一个短代码中,它也会被破坏,此短代码的一部分将始终出现在帖子内容的开头,即使它不在开头,也会出现无效的XML错误或无效的JSON语法错误

但这导致了第二个问题您永远没有机会输出结束标记

查看此代码:

            return $allposts;
        } ?>
    </div>
请注意,如果找到帖子,$allposts 返回,不提供关闭的机会</div> 待发送。

因此,取而代之的是:

不要输出开始和结束标记,而是在变量中分配它们,让我们调用它$output;$allposts, 将其添加到$output 具有$output .= $allposts;以结束函数return $output;