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"]