覆盖默认日历以显示类别中的帖子

时间:2011-01-23 作者:Osu

我正在尝试修改默认的WP日历(get\\u calendar()),以便它显示特定类别的帖子,然后将其用作快捷码。

以下是我所做的:

将get\\u calendar()函数从core(来自wp includes)复制到my child主题的函数中。php文件。为了使其成为“独立”日历,我将get\\u calendar()函数的名称更改为osu\\u get\\u calendar(),并使用osu\\u get\\u calendar()成功地将日历硬编码到我的模板中;

现在,我正试图让我的手更脏一点,并执行以下操作:

1) 将日历中显示的帖子限制为特定类别(同时保持上一个和下一个导航,以便访问者可以按月搜索这些帖子)

2) 把它做成一个短代码,这样我的客户就可以在日历中嵌入他们在帖子底部选择的类别中的帖子。

目前我还停留在1)上,因为看起来我需要修改SQL查询,以便它从特定类别中提取帖子。通过get\\u calendar()函数查看下面的代码,我如何过滤从数据库中提取的帖子,以便它们来自特定类别?这里还有其他SQL查询,但希望有人能帮我解决这个问题:

$previous = $wpdb->get_row("SELECT DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
        FROM $wpdb->posts
        WHERE post_date < \'$thisyear-$thismonth-01\'
        AND post_type = \'post\' AND post_status = \'publish\'
            ORDER BY post_date DESC
            LIMIT 1");
    $next = $wpdb->get_row("SELECT  DISTINCT MONTH(post_date) AS month, YEAR(post_date) AS year
        FROM $wpdb->posts
        WHERE post_date >   \'$thisyear-$thismonth-01\'
        AND MONTH( post_date ) != MONTH( \'$thisyear-$thismonth-01\' )
        AND post_type = \'post\' AND post_status = \'publish\'
            ORDER   BY post_date ASC
            LIMIT 1");
谢谢你,

osu

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

You were starting on the right track but you had several bits of WordPress hookage you still needed to add. An approach I like to use is to encapsulate a call to get_calendar() in a class so we can use the low-level \'query\' hook but only use for it for the one call.

So I wrote up an example which you can drop into your theme\'s functions.php file (or in a .php file for a plugin you might be writing) using a class I named YourSite_Category_Calendar(), and here is how you\'d call it in place of your call to get_calendar():

$cc = new YourSite_Category_Calendar(\'your-category\');
echo $cc->get_calendar();

And here\'s the code for the class:

<?php 

class YourSite_CategoryCalendar {
  var $category;
  var $initial;
  var $echo;
  static function on_load() {
    add_shortcode(\'category-calendar\',array(__CLASS__,\'shortcode\'));
    add_action(\'init\',array(__CLASS__,\'init\'));
    global $wp_rewrite;
    $wp_rewrite->add_rule(\'^events/([0-9]{4})/([0-9]{1,2})/([0-9]{1,2})/([^/]+)/?$\',
      \'index.php?post_type=event&year=$matches[1]&monthnum=$matches[2]&day=$matches[3]&category_name=$matches[4]\',
      \'top\');
    $wp_rewrite->flush_rules(false);  // Remove this after you\'ve got it working
  }
  static function shortcode($attributes) {
    $attributes = wp_parse_args($attributes,array(
      \'category\' => false,
    ));
    $cc = new YourSite_CategoryCalendar($attributes[\'category\']);
    echo $cc->get_calendar();
  }
  static function init() {
    register_post_type(\'event\',array(
      \'hierarchical\'    => true,
      \'label\'          => \'Events\',
      \'public\'          => true,
      \'show_ui\'         => true,
      \'query_var\'       => \'event\',
      \'rewrite\'         => array(\'slug\' => \'events\'),
      \'supports\'        => array(\'title\',\'editor\',\'custom-fields\'),
      \'taxonomies\'      => array(\'category\'),
    ));
  }
  function __construct($category,$initial=true,$echo=true) {
    $this->category = $category;
    $this->initial = $initial;
    $this->echo = $echo;
  }
  function get_calendar() {
    add_filter(\'query\',array(&$this,\'query\'));
    ob_start();
    get_calendar($this->category,$this->initial,$this->echo);
    $calendar = ob_get_clean();
    remove_filter(\'query\',array(&$this,\'query\'));
    list($header,$body) = explode(\'<tbody>\',$calendar);
    $find = \'#(href="http://[^/]+)(/[0-9]{4}/[0-9]{1,2}/[0-9]{1,2}/)#\';
    $replace = \'$1/events$2\'.$this->category.\'/"\';
    $body = preg_replace($find,$replace,$body);
    return "{$header}<tbody>{$body}";
  }
  function query($query) {
    if ($this->category) {
      global $wpdb;
      $find = "FROM {$wpdb->posts}\\\\s+WHERE";
      $add =<<<SQL
INNER JOIN {$wpdb->term_relationships} calendar_term_relationship ON calendar_term_relationship.object_id={$wpdb->posts}.ID
INNER JOIN {$wpdb->term_taxonomy} calendar_term_taxonomy ON calendar_term_taxonomy.term_taxonomy_id=calendar_term_relationship.term_taxonomy_id
INNER JOIN {$wpdb->terms} calendar_term ON calendar_term.term_id=calendar_term_taxonomy.term_id
WHERE calendar_term_taxonomy.taxonomy=\'category\' AND calendar_term.slug=\'%s\' AND
SQL;
      $replace = "FROM {$wpdb->posts} {$add} ";
      $query = preg_replace("#{$find}#Us",$replace,$query);
      $query = preg_replace("#post_type\\s*=\\s*\'post\'#","post_type=\'event\'",$query);
      $query = $wpdb->prepare($query,$this->category);
    }
    return $query;
  }
}
YourSite_CategoryCalendar::on_load();

UPDATE

Based on the comments I\'ve added the URLs rewriting needed as well as a shortcode you\'d call like this:

[category-calendar category="party"]
结束