摘录不会以快捷码显示在分类页面上

时间:2015-11-27 作者:Iurie

我使用的第三方插件添加了一个显示广告列表(CPT帖子)的短代码。shortcode函数包括(带有include 语句)模板list.php 文件,该文件显示一个搜索表单,并依次包括第二个模板list-item.php 文件,该文件显示广告本身的列表。

此列表的每个条目仅包括帖子缩略图、帖子标题、帖子日期和广告项目的价格。通过更改列表项。php代码我还添加了文章的摘录。问题是,当我们浏览主广告列表页面时,摘录会正确显示,而当我们浏览类别页面时,摘录不会显示。

当我们浏览分类页面时,广告列表的构建方式部分受应用于the_content() 滤器问题是:为什么分类页面上不显示摘录

这是显示广告列表(并包括list.php模板)的shortcode函数:

add_shortcode(\'adverts_list\', \'shortcode_adverts_list\');
/**
 * Generates HTML for [adverts_list] shortcode
 * 
 * @param array $atts Shorcode attributes
 * @since 0.1
 * @return string Fully formatted HTML for adverts list
 */
function shortcode_adverts_list( $atts ) {

    wp_enqueue_style( \'adverts-frontend\' );
    wp_enqueue_style( \'adverts-icons\' );

    wp_enqueue_script( \'adverts-frontend\' );

    extract(shortcode_atts(array(
        \'name\' => \'default\',
        \'category\' => null,
        \'columns\' => 2,
        \'paged\' => adverts_request("pg", 1),
        \'posts_per_page\' => 20,
    ), $atts));

    $taxonomy = null;
    $meta = array();

    $query = adverts_request("query");
    $location = adverts_request("location");

    if($location) {
        $meta[] = array(\'key\'=>\'adverts_location\', \'value\'=>$location, \'compare\'=>\'LIKE\');
    }

    if($category) {
        $taxonomy =  array(
            array(
                \'taxonomy\' => \'advert_category\',
                \'field\'    => \'term_id\',
                \'terms\'    => $category,
            ),
    );
    }

    $loop = new WP_Query( array( 
        \'post_type\' => \'advert\', 
        \'post_status\' => \'publish\',
        \'posts_per_page\' => $posts_per_page, 
        \'paged\' => $paged,
        \'s\' => $query,
        \'meta_query\' => $meta,
        \'tax_query\' => $taxonomy
    ) );

    $paginate_base = get_the_permalink() . \'%_%\';
    $paginate_format = stripos( $paginate_base, \'?\' ) ? \'&pg=%#%\' : \'?pg=%#%\';

    // adverts/templates/list.php
    ob_start();
    include_once ADVERTS_PATH . \'templates/list.php\';
    return ob_get_clean();
}
这是list.php 其中包括list-item.php 模板:

<div class="adverts-list">
    <?php if( $loop->have_posts() ): ?>
    <?php while ( $loop->have_posts() ) : $loop->the_post(); ?>
    <?php include ADVERTS_PATH . \'templates/list-item.php\' ?>
    <?php endwhile; ?>
    <?php else: ?>
    <div class="adverts-list-empty"><em><?php _e("There are no ads matching your search criteria.", "adverts") ?></em></div>
    <?php endif; ?>
    <?php wp_reset_query(); ?>
</div>
这是定制的完整代码list-item.php:

<div class="advert-item advert-item-col-<?php echo (int)$columns ?>">

    <?php $image = adverts_get_main_image( get_the_ID() ) ?>
    <div class="advert-img">
        <?php if($image): ?>
            <img src="<?php esc_attr_e($image) ?>" alt="" class="advert-item-grow" />
        <?php endif; ?>
    </div>

    <div class="advert-post-title">
        <span title="<?php esc_attr_e( get_the_title() ) ?>" class="advert-link"><?php the_title() ?></span>
        <a href="<?php the_permalink() ?>" title="<?php esc_attr_e( get_the_title() ) ?>" class="advert-link-wrap"></a>
    </div>

   <!-- THIS IS WHAT WAS CUSTOMIZED -->
    <div class="advert-post-excerpt">
        <span class="advert-excerpt"><?php echo get_the_excerpt(); ?></span>
    </div>
    <!-- END OF CUSTOMIZATION -->

    <div class="advert-published ">

        <span class="advert-date"><?php echo date_i18n( get_option( \'date_format\' ), get_post_time( \'U\', false, get_the_ID() ) ) ?></span>

        <?php $price = get_post_meta( get_the_ID(), "adverts_price", true ) ?>
        <?php if( $price ): ?>
        <div class="advert-price"><?php esc_html_e( adverts_price( get_post_meta( get_the_ID(), "adverts_price", true ) ) ) ?></div>
        <?php endif; ?>
    </div>fun

</div>
这是应用于the_content() 浏览单个帖子和类别页面时进行筛选(在这种情况下,再次调用第一个快捷码函数):

add_filter(\'the_content\', \'adverts_the_content\');

function adverts_the_content($content) {
    global $wp_query;

    if (is_singular(\'advert\') && in_the_loop() ) {
        ob_start();
        $post_id = get_the_ID();
        include ADVERTS_PATH . \'templates/single.php\';
        $content = ob_get_clean();
    } elseif( is_tax( \'advert_category\' ) && in_the_loop() ) {
        $content = shortcode_adverts_list(array(
            "category" => $wp_query->get_queried_object_id()
        ));
    }

    return $content;
}

UPDATE

这是adverts_request() 函数,由调用shortcode_adverts_list() 功能:

function adverts_request($key, $default = null) {
    if(isset($_POST[$key])) {
        return $_POST[$key];
    } elseif(isset($_GET[$key])) {
        return $_GET[$key];
    } else {
        return $default;
    }
}

2 个回复
最合适的回答,由SO网友:tao 整理而成

我使用相同的主题和相同的插件复制了您的环境。开箱即用,插件不会将CPT注册到excerpt. 您需要注册它:

add_post_type_support(\'advert\', array(\'excerpt\'));
这个应该放进去functions.php 你(孩子?)主题我唯一的问题是:如果帖子类型没有启用摘录,您如何以及为什么在单数页上获取摘录?我想是WPfeature/bug 这不是摘录本身,而是内容的删减/剥离版本(默认为55个字符)WP构建,我猜它没有检查是否为特定的帖子类型启用了摘录。

或者,您可以添加excerpt 至第108行,共wpadverts/wpadverts.php, 但是如果你这样做,如果你更新插件,你就会失去这个mod。

更新

我想我终于明白了你最初的要求。我自己对插件和主题的测试is here. I do not know why the_excerpt() 不返回上内容的精简版本advert category 没有手动摘录的帖子页面。但是,为了解决这个问题,我制作了一个“自定义摘录”,用于list-item.php. 这是:

<div class="advert-post-excerpt">
    <span class="advert-excerpt">
        <?php
        global $post;
        $limit = 55;
        $content = strip_tags($post->post_content);
        echo has_excerpt($post->ID) ?
            $post->post_excerpt :
            ( strlen($content) > $limit ?
                substr($content, 0, $limit).\'...\' :
                $content
            )
        ;?>
    </span>
</div>
更改55 到所需的摘录长度。上述代码应替换您的首字母:

<div class="advert-post-excerpt">
    <span class="advert-excerpt"><?php echo get_the_excerpt(); ?></span>
</div>
我是一个务实的人,如果一种方法行不通,我会找到一种方法。但是,如果有人能告诉我为什么the_excerpt() 退货null 在这种情况下,我要感谢他们。

SO网友:Pieter Goosen

据我所知,您的代码存在一些问题,可能会影响输出,也可能不会影响输出

在我开始之前,有几点很重要

所有代码都未经测试,需要PHP 5.4+。应首先在本地安装上测试所有代码,并将debug设置为true

我给你的是最低限度的。有些代码可以改进,所有代码都可以修改以满足您的确切需要

adverts_list 短代码

您永远不应该使用extract(). 就像query_posts(), 这是一个邪恶的函数,它可以让你在调试地狱里无所事事。extract() 在几个版本之前从core中删除,甚至codex也进行了更新以删除它。WordPress中globals的使用已经是一团糟,然后extract() 出现并创建更多的左右和中间。但不管怎样,我不打算详述,你应该在自己的时间阅读以下内容

并且在研究这个问题时也要做一些研究

另一个问题是使用来自属性的未初始化和未验证的值。这是一个很危险的安全漏洞,很容易被利用。

请注意,如果可以的话,应该避免使用输出缓冲从短代码返回输出。这应该是你最后的选择。而是使用返回其输出的函数对应项,而不是回显输出,并将所有内容连接到一个变量,然后返回该变量。您可以检查this post 例如。

您可能可以按如下方式重写短代码:

add_shortcode(\'adverts_list\', \'shortcode_adverts_list\');
/**
 * Generates HTML for [adverts_list] shortcode
 * 
 * @param array $atts Shorcode attributes
 * @since 0.1
 * @return string Fully formatted HTML for adverts list
 */
function shortcode_adverts_list( $atts ) {

    wp_enqueue_style( \'adverts-frontend\' );
    wp_enqueue_style( \'adverts-icons\' );

    wp_enqueue_script( \'adverts-frontend\' );

    // Coorect way to set attribute defaults
    $attributes = shortcode_atts(
        [
            \'name\'           => \'default\',
            \'category\'       => 0,
            \'columns\'        => 2,
            \'paged\'          => adverts_request("pg", 1),
            \'posts_per_page\' => 20,
        ], 
        $atts
    );

    // Now we can set our variables and sanitize/validate
    $name            = filter_var( $attributes[\'name\'],            FILTER_SANITIZE_STRING );
    $category        = filter_var( $attributes[\'category\'],        FILTER_VALIDATE_INT    );
    $columns         = filter_var( $attributes[\'columns\'],         FILTER_VALIDATE_INT    );
    $paged           = filter_var( $attributes[\'paged\'],           FILTER_VALIDATE_INT    );
    $posts_per_page  = filter_var( $attributes[\'posts_per_page\'],  FILTER_VALIDATE_INT    );

    $query    = adverts_request("query");
    $location = adverts_request("location");

    $meta_query = [];
    if($location) {
        $meta_query[] = [
            \'key\'     => \'adverts_location\', 
            \'value\'   => $location, 
            \'compare\' => \'LIKE\'
        ];
    }

    $taxonomy = [];
    if($category) {
        $taxonomy =  [
            [
                \'taxonomy\' => \'advert_category\',
                \'terms\'    => $category,
            ],
        ];
    }

    $loop = new WP_Query( [
        \'post_type\'      => \'advert\', 
        \'post_status\'    => \'publish\',
        \'posts_per_page\' => $posts_per_page, 
        \'paged\'          => $paged,
        \'s\'              => $query,
        \'meta_query\'     => $meta_query,
        \'tax_query\'      => $taxonomy
    ] );

    $paginate_base   = get_the_permalink() . \'%_%\';
    $paginate_format = stripos( $paginate_base, \'?\' ) ? \'&pg=%#%\' : \'?pg=%#%\';

    // adverts/templates/list.php
    ob_start();
    include_once ADVERTS_PATH . \'templates/list.php\';
    return ob_get_clean();
}

list.php

清除所有php垃圾邮件。只有在php和HTML之间移动时才打开和关闭php标记。当您在仍然是php的行之间移动时,使用php标记绝对没有用

值得注意的是,wp_reset_query() 应与一起使用query_posts(), 我说过你永远不应该用它。它可能会产生意外的结果。适当的重置方法WP_Querywp_reset_postdata(). 当没有帖子时,您也不想重置任何内容,因为您没有更改$post 全球的始终使用wp_reset_postdata() 在您的endwhileendif 声明。

为了便于调试和代码编辑器,请注意,不要使用卷曲而不是:endif/endwhile

您可能可以按如下方式重写代码:

<div class="adverts-list">
    <?php 
        if( $loop->have_posts() ) {
            while ( $loop->have_posts() ) {
            $loop->the_post();

                include ADVERTS_PATH . \'templates/list-item.php\'

            } //endwhile
            wp_reset_postdata();
        } else { 
    ?>
            <div class="adverts-list-empty"><em><?php _e("There are no ads matching your search criteria.", "adverts") ?></em></div>
    <?php 
        } // endif
    ?>
</div>

list-item.phpecho get_the_excerpt(); 可以重写为the_excerpt() 因为这正是the_excerpt()

the_content 过滤不幸的是,你的短代码一团糟,而且你的短代码的使用

不能将php变量传递给短代码。您需要修改您的短代码以合并可变部分。由于这是一个插件,您不想更改插件本身。因此,最好是删除shorcode的回调函数,并用自己的回调函数替换它。

您可以使用快捷码执行以下操作:

// First, we want to remove the original callback function
remove_shortcode( \'adverts_list\', \'shortcode_adverts_list\', 11 );

// Now we add our own callback, \'custom_shortcode_adverts_list\' to the shortcode
add_shortcode( \'adverts_list\', \'custom_shortcode_adverts_list\', 12 );
/**
 * Generates HTML for [adverts_list] shortcode
 * 
 * @param array $atts Shorcode attributes
 * @since 0.1
 * @return string Fully formatted HTML for adverts list
 */
function custom_shortcode_adverts_list( $atts ) {

    wp_enqueue_style( \'adverts-frontend\' );
    wp_enqueue_style( \'adverts-icons\' );

    wp_enqueue_script( \'adverts-frontend\' );

    // Coorect way to set attribute defaults
    $attributes = shortcode_atts(
        [
            \'name\'           => \'default\',
            \'category\'       => 0,
            \'columns\'        => 2,
            \'paged\'          => adverts_request("pg", 1),
            \'posts_per_page\' => 20,
        ], 
        $atts
    );

    // Now we can set our variables and sanitize/validate
    $name            = filter_var( $attributes[\'name\'],            FILTER_SANITIZE_STRING );
    $category        = filter_var( $attributes[\'category\'],        FILTER_VALIDATE_INT    );
    $columns         = filter_var( $attributes[\'columns\'],         FILTER_VALIDATE_INT    );
    $paged           = filter_var( $attributes[\'paged\'],           FILTER_VALIDATE_INT    );
    $posts_per_page  = filter_var( $attributes[\'posts_per_page\'],  FILTER_VALIDATE_INT    );

    $query    = adverts_request("query");
    $location = adverts_request("location");

    $meta_query = [];
    if($location) {
        $meta_query[] = [
            \'key\'     => \'adverts_location\', 
            \'value\'   => $location, 
            \'compare\' => \'LIKE\'
        ];
    }

    // We need to set $category correctly according to page
    $category = ( is_tax( \'advert_category\' ) ) ? get_queried_object_id() : $category;
    $taxonomy = [];
    if($category) {
        $taxonomy =  [
            [
                \'taxonomy\' => \'advert_category\',
                \'terms\'    => $category,
            ],
        ];
    }

    $loop = new WP_Query( [
        \'post_type\'      => \'advert\', 
        \'post_status\'    => \'publish\',
        \'posts_per_page\' => $posts_per_page, 
        \'paged\'          => $paged,
        \'s\'              => $query,
        \'meta_query\'     => $meta_query,
        \'tax_query\'      => $taxonomy
    ] );

    $paginate_base   = get_the_permalink() . \'%_%\';
    $paginate_format = stripos( $paginate_base, \'?\' ) ? \'&pg=%#%\' : \'?pg=%#%\';

    // adverts/templates/list.php
    ob_start();
    include_once ADVERTS_PATH . \'templates/list.php\';
    return ob_get_clean();
}
我真的不知道目的是什么$post_id = get_the_ID(); 有,可能可以删除,因为我看不到它有任何用处

就DRY而言,首先检查您是否在循环中,然后返回/停止执行过滤器,这将是一个额外的好处。这节省了时间,而且速度更快

the_content 过滤器应用于get_the_content() 在通过the_content(). 因此,您可以简单地将短代码添加到the_content 滤器

您可以尝试以下操作:(根据需要进行调整,因为我不知道确切的用例)

add_filter( \'the_content\', function ( $content )
{
    // Check if we are in the loop, if not, return
    if ( !in_the_loop() )
        return $content;

    // If this is a single page, execute the following
    if ( is_singular(\'advert\') ) {
        ob_start();
        include ADVERTS_PATH . \'templates/single.php\';
        $content = ob_get_clean();
    }

    // If this is a taxonomy page, run the following
    if ( is_tax( \'advert_category\' ) ) {
        $content = \'[adverts_list]\';
    }

    return $content;
});

adverts_request()

您不应该使用未统计的值,特别是来自$_GET$_POST 变量。这是黑客用来向网站注入恶意代码的最受欢迎的地点。ALWAYS ALWAYS 消毒和NEVER EVER 相信任何地方的意见,甚至不要相信自己

我利用filter_input 对来自超级全局的键/值对进行santize(如果指定)和vaildate的筛选器。

另外,将值设置为参数,并确保在执行某些操作之前传递了值,以避免不必要的错误。

考虑到这一点,可以采取以下措施:

function adverts_request( $key = \'\', $default = null) 
{
    // Santize our $default value. I accept this is a string value, if not, adjust the filter
    if ( $default !== null )
        $default = filter_var( $default, FILTER_SANITIZE_STRING ); 

    // Check if we have a value, if not return $default
    if ( !$key )
        return $default; 

    // Sanitize $key, again I accept it to be a string, adjust filter accordingly if not
    $key = filter_var( $key, FILTER_SANITIZE_STRING ); 

    // Get our value from $_POST and $_GET. Again, I accepted that $key is a string
    $post_input = filter_input( INPUT_POST, $key, FILTER_SANITIZE_STRING );
    $get_input  = filter_input( INPUT_GET,  $key, FILTER_SANITIZE_STRING );

    if( $post_input ) {
        $output = $post_input;
    } elseif ( $get_input ) {
        $output = $get_input;
    } else {
        $output = $default
    }

    return $output
}

相关推荐

覆盖WC_ShortCodes类中的静态方法(ShortCode)

我正在尝试覆盖product_categories 来自WooCommerce的短代码,以便我可以向包装器添加其他类[product_categories number=\"0\" parent=\"0\" class=\"container\"] 所以我看了一下WooCommerce code, 并创建了一个扩展WC_Shortcodes 我只是复制了静态方法product_categories /** * Updated product categories shortcod