Как включить файл в функцию шорткода в WordPress

#php #wordpress #shortcode

#php #wordpress #шорткод

Вопрос:

Я хочу создать шорткод, а в шорткоде я хочу запросить файл. когда пользователь пишет шорткод в редакторе. На выходе будет показан требуемый макет файла.

Я создаю шорткод, но это не работает, вот мой короткий код:

 <?php
    function inner_page( $atts, $content = null ){
    $return_string = require 'foo/foo_artilces_list.php';

    return $return_string;
    }

    add_action('init', 'register_section_shortcodes');
    function register_section_shortcodes(){
        add_shortcode('inner_page', 'inner_page');
    }
?>
 

Вот мой код файла require

 <?php
     /*=========
    Template Name: KBE
 =========*/

     get_header();
?>

<div id="foo_container">

    <h1><?php the_title(); ?></h1>

    <!--Breadcrum-->
    <?php
        if(FOO_BREADCRUMBS_SETTING == 1){
    ?>
        <div class="foo_breadcrum">
            <?php echo foo_breadcrumbs(); ?>
        </div>
    <?php
        }
    ?>
    <!--/Breadcrum-->

    <!--search field-->
    <?php
        if(FOO_SEARCH_SETTING == 1){
    ?>
        <div class="foo_search_field">
            <input name="" type="text" placeholder="Search the knowledgebase..." />
        </div>
    <?php
        }
    ?>
    <!--/search field-->

    <!--content-->
<?php
    if(FOO_SIDEBAR_SETTING == 0){
?>
    <div id="foo_content" class="foo_content_full" >
<?php
    }
    elseif(FOO_SIDEBAR_SETTING == 1){
?>
    <div id="foo_content" class="foo_content_right" >
<?php
    }
    elseif(FOO_SIDEBAR_SETTING == 2){
?>
    <div id="foo_content">
<?php
    }
?>
        <!--leftcol-->
        <div class="foo_leftcol">

            <div class="foo_categories">
        <?php
            $foo_cat_args = array(
                'orderby'       => 'term_order', 
                'order'         => 'ASC',
                'hide_empty'    => true, 
            );

            $foo_terms = get_terms(FOO_POST_TAXONOMY, $foo_cat_args);

            foreach($foo_terms as $foo_cat){
                $foo_term_id = $foo_cat->term_id;
                $foo_term_slug = $foo_cat->slug;
                $foo_term_name = $foo_cat->name;
        ?>
                <div class="foo_category">
                    <h2>
                        <span class="foo_count"><?php echo FOO_ARTICLE_QTY; ?> Articles</span>
                        <a href="<?php echo get_term_link($foo_term_slug, 'foo_cat') ?>" title="<?php 

sprintf( __( "View all posts in %s" ), $foo_term_name ) ?>"><?php echo $foo_term_name; ?></a>
                    </h2>

                    <ul class="foo_article_list">
                <?php
                    $foo_tax_post_args = array(
                        'post_type' => FOO_POST_TYPE,
                        'posts_per_page' => FOO_ARTICLE_QTY,
                        'orderby' => 'name',
                        'order' => 'ASC',
                        'tax_query' => array(
                            array(
                                'taxonomy' => FOO_POST_TAXONOMY,
                                'field' => 'slug',
                                'terms' => $foo_term_slug
                            )
                        )
                    );

                    $foo_tax_post_qry = new WP_Query($foo_tax_post_args);

                    if($foo_tax_post_qry->have_posts()) :
                        while($foo_tax_post_qry->have_posts()) :
                            $foo_tax_post_qry->the_post();
                ?>
                            <li>
                                <a href="<?php the_permalink(); ?>">
                                    <?php the_title(); ?>
                                </a>
                            </li>
                <?php
                        endwhile;
                    else :
                        echo "No posts";
                    endif;
                ?>
                    </ul>
                </div>
        <?php
            }
        ?>
            </div>

        </div>
        <!--/leftcol-->

        <!--aside-->
        <?php
            if((FOO_SIDEBAR_SETTING == 2) || (FOO_SIDEBAR_SETTING == 1)){
                dynamic_sidebar('foo_cat_widget');
            }
        ?>
        <!--/aside-->
    </div><!--content-->

</div>

<?php
    get_footer();
?>
 

Он показывает мне только виджеты, и весь макет становится беспорядочным.
есть идеи

Ответ №1:

Здесь у вас есть две проблемы.

Во-первых, require ничего не возвращает. Он просто «импортирует» код из файла и запускает его именно там, где вы разместили запрос require. Таким образом, все, что содержится в вашем новом файле, отображается раньше, чем все остальное, что обрабатывает WordPress.

Вы можете обойти это с помощью выходного буфера. Это:

 $return_string = require 'foo/foo_artilces_list.php';
 

Должно выглядеть так:

 ob_start();
require 'foo/foo_artilces_list.php';
$return_string = ob_get_flush();
 

Теперь вы можете вернуть строку, а WordPress сделает все остальное.

Вторая проблема: ваши get_header() get_footer() вызовы and . WordPress уже напечатал его заголовок, ваш вызов отобразит его во второй раз. То же самое касается нижнего колонтитула … ваш включенный файл отобразит нижний колонтитул, и WordPress отобразит его во второй раз в конце страницы. Вы должны удалить оба вызова из вашего включенного файла.

Использование выходного буфера для этого не очень чистое решение. Было бы лучше поместить весь ваш вывод во включаемый файл в функцию, которая хранит все в переменной, возвращаемой функцией. Тогда вы могли бы сделать:

 require('foo/foo_artilces_list.php');
$return_string = my_function();
 

Комментарии:

1. В моем случае вывод из файла обрабатывался дважды, пока я не заменил $return_string = ob_get_flush(); на $return_string = ob_get_clean();