检测您是否在“ SINGLE POST”页面中的最佳方法


9

因此,这似乎是一件很卑鄙的事情,但请在这里关注我。

我正在尝试通过pre_get_posts操作添加一些逻辑。这是给我的整个WP_Query对象。(见末)

我考虑过使用的东西:

  • is_single() - 太宽泛。
  • is_singular()-使用此功能为时过早,get_queried_object()目前尚未设置。
  • $query->single 属性-太宽泛了。
  • $query->get('post_type')-未设置,因为它正在使用该name属性。

name真正的唯一指标吗?

WP_Query Object
(
    [query] => Array
        (
            [page] => 
            [name] => abcs-of-mental-health
        )

    [query_vars] => Array
        (
            [page] => 
            [name] => abcs-of-mental-health
            [error] => 
            [m] => 0
            [p] => 0
            [post_parent] => 
            [subpost] => 
            [subpost_id] => 
            [attachment] => 
            [attachment_id] => 0
            [static] => 
            [pagename] => 
            [page_id] => 0
            [second] => 
            [minute] => 
            [hour] => 
            [day] => 0
            [monthnum] => 0
            [year] => 0
            [w] => 0
            [category_name] => 
            [tag] => 
            [cat] => 
            [tag_id] => 
            [author_name] => 
            [feed] => 
            [tb] => 
            [paged] => 0
            [comments_popup] => 
            [meta_key] => 
            [meta_value] => 
            [preview] => 
            [s] => 
            [sentence] => 
            [fields] => 
            [menu_order] => 
            [category__in] => Array
                (
                )

            [category__not_in] => Array
                (
                )

            [category__and] => Array
                (
                )

            [post__in] => Array
                (
                )

            [post__not_in] => Array
                (
                )

            [tag__in] => Array
                (
                )

            [tag__not_in] => Array
                (
                )

            [tag__and] => Array
                (
                )

            [tag_slug__in] => Array
                (
                )

            [tag_slug__and] => Array
                (
                )

            [post_parent__in] => Array
                (
                )

            [post_parent__not_in] => Array
                (
                )

        )

    [tax_query] => 
    [meta_query] => 
    [queried_object] => 
    [queried_object_id] => 0
    [post_count] => 0
    [current_post] => -1
    [in_the_loop] => 
    [comment_count] => 0
    [current_comment] => -1
    [found_posts] => 0
    [max_num_pages] => 0
    [max_num_comment_pages] => 0
    [is_single] => 1
    [is_preview] => 
    [is_page] => 
    [is_archive] => 
    [is_date] => 
    [is_year] => 
    [is_month] => 
    [is_day] => 
    [is_time] => 
    [is_author] => 
    [is_category] => 
    [is_tag] => 
    [is_tax] => 
    [is_search] => 
    [is_feed] => 
    [is_comment_feed] => 
    [is_trackback] => 
    [is_home] => 
    [is_404] => 
    [is_comments_popup] => 
    [is_paged] => 
    [is_admin] => 
    [is_attachment] => 
    [is_singular] => 1
    [is_robots] => 
    [is_posts_page] => 
    [is_post_type_archive] => 
    [query_vars_hash] => f473ebf7f725c2627dc5fd9a1429f626
    [query_vars_changed] => 
    [thumbnails_cached] => 
)

Answers:


10

我已经尝试过出于自己的目的进行整理。据我所知...

  • post_type没有为post帖子类型设置任何位置。
  • 对于page帖子类型,我仅在中看到帖子类型键 queried_object
  • 对于CPT类型,post_typequery_vars和中 都有一个键query
  • 在这方面,导航菜单的行为类似于其他CPT。

数据非常不一致,但是如果您消除页面和CPT,我相信您可以假定该post类型。

编辑:来自@EricHolmes的工作代码:

add_action( 'pre_get_posts', 'something_for_single_posts_only' ) ; 
function something_for_single_posts_only( $query ) { 
  if( $query->is_main_query() 
    && $query->is_singular() 
    && ! $query->get( 'post_type' ) 
    && ! $query->is_page() 
    && ! $query->is_attachment() 
  ) { 
      // do something for single posts only. 
  } 
} 

我们检查is_singular,无柱式(彩色显像管有post_typequery_vars),而不是一个页面或附件。


它在内部pre_get_posts运行(在查询运行之前)?
gmazzap

我想知道是否is_page()设置在该pre_get_posts级别。如果是这样,我可以检查一下是否post_type未在query_vars中进行设置,那么我猜它是否还好?好伤心
埃里克·福尔摩斯

1
is_page确实被设置。
s_ha_dum 2013年

@s_ha_dum我删除了评论,因为它似乎不适用于CPT ...
gmazzap

2
在您的答案中添加有效的解决方案。
埃里克·福尔摩斯

0

我不知道这是否有用:

function hwl_home_pagesize( $query ) {
    global $wp_query;
    if (is_main_query() && count($wp_query->posts) < 2) {

    }

}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );

使用$ wp_query-> posts(数组)检查帖子类型。


还没。预先获取帖子发生在$wp_query->posts实际填充变量之前。不过谢谢!
埃里克·福尔摩斯

0

经过一些测试,我发现不幸的是无法在pre_get_posts钩子中获得cpt的帖子类型。仅is_page适用于标准帖子类型,而不能在其中检索cpt。

如果您只有页面和帖子(无cpt),is_single()则以with true作为响应的检查表示帖子类型为post,因为它为页面返回false。

如果您还有CPT,恐怕您必须执行其他查询。我能想到的最简单的方法就是获取post_type发布状态为发布的列,而post_name是必需的列(跳过修订):

function test( $q ) {
  if ( is_single() ) {
    global $wpdb;
    $type = $wpdb->get_var( $wpdb->prepare(
      "SELECT post_type FROM $wpdb->posts WHERE post_name = %s AND post_status = 'publish' AND post_type <> 'revision'",
      $q->query['name']
    ) );
    var_dump($type);
  }
}
add_action( 'pre_get_posts', 'test', 1); 

如果要检查特定的帖子类型,可以编写一个自定义条件标签,该标签仅对具有给定post_type和给定名称的行进行计数:

function is_single_post_type( $type = 'post' ) {
  if ( is_single() ) {
    global $wpdb, $wp_query;
    $is = $wpdb->get_var( $wpdb->prepare(
      "SELECT count(ID) FROM $wpdb->posts WHERE post_name = %s AND post_status = 'publish' AND post_type = %s",
      $wp_query->query['name'], $type
    ) );
    return $is > 0;
  }
  return false;
}

当然这是需要的pre_get_post,在以后的任何挂钩中您都可以使用get_post_type()...


1
这肯定可以,但是在接受的答案中,它是一个简单得多的条件,无需对数据库进行额外查询。:)
埃里克·福尔摩斯

是。我了解您想确切知道您要显示哪种帖子类型。不仅在单个帖子视图中。@EricHolmes
gmazzap

-1

这是我正在使用的,尽管它专用于我自己的目录结构。

/**
 * Function to list all templates used in a page
 * @author Imperative Ideas with thanks to Rarst
 * @uri http://wordpress.stackexchange.com/a/89005
 */

function thelist() {
    $included_files = get_included_files();
    $stylesheet_dir = str_replace( '\\', '/', get_stylesheet_directory() );
    $template_dir   = str_replace( '\\', '/', get_template_directory() );
    echo '<h3 class="debugtitle">Theme file templates used in this page</h3>';
    foreach ( $included_files as $key => $path ) {

        $path   = str_replace( '\\', '/', $path );

        if ( false === strpos( $path, $stylesheet_dir ) && false === strpos( $path, $template_dir ) )
            unset( $included_files[$key] );

        if(!strpos($path, '/wp-content/themes/') === false) { // Files IN this directory
            if(strpos($path, '/library/') === false) { // Ignore this subdir
                if(strpos($path, '/hybrid-core/') === false) { // Ignore this subdir
                    echo $key." = ". $path."</br>"; // Finally, output the list
                }
            }
        }
    }
}

里程可能会有所不同。我检查文件是否位于一个目录中的strpos位,而不是另一个目录中的strpos位,需要针对您的构建进行修改,并且可能可以更高效地进行重构。它们的存在是为了在特定目录结构的上方和下方切出结果。

在页脚中运行thelist()将为您提供用于编译当前视图的每个.php模板文件的编号列表。当处理呈现神秘成分的子主题时,此功能特别有用。


似乎过分杀伤力。很棒的主意吗?
埃里克·福尔摩斯

除了解析模板之外,没有很多好的方法来确定哪些模板在驱动页面。我想,如果您正在寻找像单页vs页面这样简单的内容,是的,这太过分了。尝试运行该函数一段时间,减去多余的忽略条件,您将明白为什么使用此函数。驱动WP页面时会涉及大量文件,了解它们的全部内容可能非常有用。即使这样,也无法识别钩子函数。
势在必行的想法
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.