web-dev-qa-db-fra.com

Remplacement du calendrier par défaut pour afficher les publications d'une catégorie

J'essaie de modifier le calendrier par défaut WP (get_calendar ()) afin qu'il affiche les publications d'une catégorie spécifique, puis l'utilise comme code court.

Voici ce que j'ai fait:

Copié dans la fonction get_calendar () du noyau (à partir de wp-includes) dans le fichier functions.php de mon thème enfant. Afin d'en faire un calendrier "indépendant", j'ai changé le nom de la fonction get_calendar () en osu_get_calendar () et j'ai codé avec succès le calendrier dans mon modèle en utilisant osu_get_calendar ();

Maintenant, j'essaie d'avoir les mains un peu plus sales et de faire ce qui suit:

1) Limitez les messages affichés dans le calendrier à une catégorie spécifique (tout en conservant la navigation précédente et suivante afin que les visiteurs puissent parcourir ces messages par mois)

2) Faites-en un shortcode afin que mon client puisse essentiellement incorporer un calendrier avec des publications de la catégorie de son choix au bas de leurs publications.

Je suis bloqué sur 1) pour le moment, car il semble que je doive modifier les requêtes SQL afin qu'il extrait les publications d'une catégorie spécifique. En regardant le code ci-dessous de la fonction get_calendar (), comment pourrais-je filtrer les publications extraites de la base de données afin qu'elles appartiennent à une catégorie spécifique? Il y a d'autres requêtes SQL là-dedans, mais j'espère que quelqu'un pourra m'aider avec celle-ci pour l'instant:

$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");

Merci,

osu

1
Osu

Vous commenciez sur la bonne voie, mais vous aviez encore plusieurs ajouts à faire à WordPress. Une approche que j'aime utiliser consiste à encapsuler un appel à get_calendar() dans une classe afin que nous puissions utiliser le hook 'query' de bas niveau, mais que nous ne l'utilisions que pour l'appel en question.

J'ai donc écrit un exemple que vous pouvez insérer dans le fichier functions.php de votre thème (ou dans un fichier .php pour un plugin que vous écrivez peut-être) en utilisant une classe J'ai nommé YourSite_Category_Calendar(), et voici comment vous l'appelez à la place de votre appel à get_calendar():

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

Et voici le code de la classe:

<?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();

METTRE À JOUR

Sur la base des commentaires, j'ai ajouté les réécritures d'URL nécessaires ainsi qu'un shortcode que vous appelleriez comme ceci:

[category-calendar category="party"]
3
MikeSchinkel