在自定义字段/帖子元中按日期值筛选的存档列表?

时间:2010-12-22 作者:Dalen

(Moderator\'s Note: 最初的标题是“使用带有自定义日期的按日期存档”)

我在帖子中添加了一个额外的日期作为自定义字段。现在,我希望存档按自定义日期而不是按发布日期显示帖子。例如,我今天发布了一篇帖子(12月22日),但自定义日期设置为1月1日。加载URL时archives/date/2011/01 在浏览器中,不显示与自定义日期匹配的帖子(显然)

是否有方法修改为生成的页面的行为archives/date/2011/01 URL以便按自定义日期检索帖子?

谢谢

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

正如WordPress中的许多内容一样,有几种方法可以实现您的愿望。我要解释其中一个。

删除\'year\', \'monthnum\'\'day\' 查询变量

您可以修改WordPress在\'pre_get_posts\' 钩通过将规则重写到WP_Query 对象调用query_vars 变量\'year\', \'monthnum\'\'day\'.

什么时候$wp_query->query_vars 具有的值\'year\', \'monthnum\'\'day\' WordPress将在查询帖子列表时使用它们the first step is to remove those key-value pairs from the query array 使用PHPunset() 功能(请注意$wp_query 是WordPress中的全局变量,包含当前查询对象作为WP_Query 类别。)

这个yoursite_pre_get_posts() 以下功能由\'pre_get_posts\' 钩子将从query_vars 数组,但仅当查询是主查询*(即$query 传递给钩子的值正好等于全局$wp_the_query$query===$wp_the_query) 并且仅当查询是存档查询时。如果您将此添加到主题functions.php 文件你会发现你的归档页面显示所有帖子,而不仅仅是日期的帖子(所以我们已经达到你想要的一半了…):

add_action(\'pre_get_posts\', \'yoursite_pre_get_posts\' );
function yoursite_pre_get_posts( $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    unset($query->query_vars[\'year\']);
    unset($query->query_vars[\'monthnum\']);
    unset($query->query_vars[\'day\']);
  }
}
为自定义字段添加查询变量现在有点棘手。在v3中。x WordPress仅允许您使用query_var 数组,它也不允许我们将函数应用于这些条件。

以下修改为yoursite_pre_get_posts() 将允许您的存档查询匹配准确的日期,前提是您将日期存储在\'YYYY-MM-DD\' 自定义字段中的格式:

add_action(\'pre_get_posts\', \'yoursite_pre_get_posts\' );
function yoursite_pre_get_posts( $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    $qv = &$query->query_vars;
    $date = mktime(0,0,0,$qv[\'monthnum\'],$qv[\'day\'],$qv[\'year\']);
    $qv[\'meta_key\'] = \'Custom Date\';
    $qv[\'meta_value\'] = date("Y-m-d",$date);
    unset($qv[\'year\']);
    unset($qv[\'monthnum\']);
    unset($qv[\'day\']);
  }
}
下面是屏幕截图中的内容:

当然,这不是你真正想要的。要查询年份(&A);而不仅仅是特定的一天,甚至是一年。正如我之前所说,这就是问题的症结所在。

使用\'posts_where\' 钩子来修改SQLWHERE 基本上,您需要深入研究挂钩,并调用\'posts_where\' 钩子,如果可能的话,我总是尽量避免,因为在SQL查询片段上执行文本查找和替换时,很容易编写与修改相同SQL查询的其他插件不兼容的代码。尽管如此,如果你需要它,而其他任何东西都不起作用,那么它是你的最后手段。

所以yoursite_posts_where() 函数搜索WHERE WordPress为文本构建的子句"AND wp_postmeta.meta_value = \'2011-01\'" 并将其替换为文本"AND SUBSTRING(wp_postmeta.meta_value,1,7) = \'2011-01\'", 代码如下:

add_action(\'posts_where\',\'yoursite_posts_where\',10,2);
function yoursite_posts_where( $where, $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    $meta_value = $query->query_vars[\'meta_value\'];
    $length = strlen($meta_value);
    $find = "AND wp_postmeta.meta_value = \'{$meta_value}\'";
    $replace = "AND SUBSTR(wp_postmeta.meta_value,1,{$length}) = \'{$meta_value}\'";
    $where = str_replace($find,$replace,$where);
  }
  return $where;
}
修改yoursite_pre_get_posts() 为了支持多个年-月-日选项,我们当然需要修改yoursite_pre_get_posts() 支持不同长度元数据的函数:\'YYYY\', \'YYYY-MM\'\'YYYY-MM-DD\' (注意PHP的复杂用法mktime()date() 功能只是为了避免担心这些模式:\'YYYY-M\', \'YYYY-MM-D\'\'YYYY-M-D\'):

add_action(\'pre_get_posts\',\'yoursite_pre_get_posts\' );
function yoursite_pre_get_posts( $query ) {
  global $wp_the_query;
  if ($query===$wp_the_query && $query->is_archive) {
    $qv = &$query->query_vars;  // Make it less tedious to reference
    if ($qv[\'monthnum\']==0) // Just search on YYYY
      $date = $qv[\'year\'];
    else if ($qv[\'day\']==0) // Search on YYYY-MM
      $date = date(\'Y-m\',mktime(0,0,0,$qv[\'monthnum\'],1,$qv[\'year\']));
    else
      $date = date(\'Y-m-d\',mktime(0,0,0,$qv[\'monthnum\'],$qv[\'day\'],$qv[\'year\']));
    $qv[\'meta_key\'] = \'Custom Date\';
    $qv[\'meta_value\'] = $date;
    unset($qv[\'year\']);
    unset($qv[\'monthnum\']);
    unset($qv[\'day\']);
  }
}
这为我们提供了以下内容,基本上概括了您所寻找的内容:

在主题中显示自定义日期的代码顺便说一句,以下是我在主题中用于获取自定义日期元值的代码:

<?php if ($custom_date = get_post_meta($post->ID,\'Custom Date\',true)): ?>
  <h2>Custom Date: <?php echo $custom_date; ?></h2>
<?php endif; ?>
另请记住,用户必须输入\'YYYY-MM-DD\' 格式

请记住,用户需要在\'YYYY-MM-DD\' 使其工作的格式。当然,您可以通过几种不同的方法,即在SQL代码中或通过\'save_post\' 钩子重新设置了日期,但我将把它作为练习留给其他人。

P、 另一种方法是使用\'save_post\' 钩子以正确的格式保存三(3)个隐藏的元数据,以便与匹配\'YYYY-MM-DD\', \'YYYY-MM\'\'YYYY\' 也许有元钥匙\'_custom_date\', \'_custom_date_year_month\' \'_custom_date_year\' 对于其他可能也要修改SQL的插件,这将更有弹性WHERE 子句,但会为每个帖子添加三(3)个额外的隐藏自定义字段,因此对于包含大量帖子的博客来说,这可能不是一个好主意,而且它们可能会以某种方式失去同步。

SO网友:Mark

是-您需要使用query_posts()get_posts() 或者自己编写一个自定义查询。

SO网友:Rarst

试试这个:

复制您的archive.php (index.php 如果您没有存档)模板date.php

  • 英寸date.php 模板使用query_posts() 要覆盖排序,您需要使用orderby parameters
  • preserve original query/year/month/, 你用什么来获取/archives/date/year/month/ ?..

    PPS实际上在看了Mike的答案后,这可能不足以影响帖子的选择。划伤这个。

  • 结束

    相关推荐