web-dev-qa-db-fra.com

Requête for trier is it it to it one is not to a meter and display of the positions

Je travaille sur un modèle de page de terme de taxonomie personnalisée dans lequel nous voulons que les éléments liés au terme soient triés par date de publication (champ de date personnalisé) - et s’il existe plusieurs éléments le même jour (au format AAAA-MM- DD) pour ensuite les trier par titre et enfin par titre si le champ personnalisé n’a pas été renseigné (éléments plus anciens).

Donc, j'ai essayé cent façons différentes avec WP_query et il renvoie la plupart des résultats comme je les veux - mais dans ce cas, il ne renvoie que les éléments qui ont la méta_key de publication_date. Tous les autres éléments sont ignorés et ne sont pas affichés. J'ai essayé une méta_query en utilisant une relation de "ou" et comparé la publication_date avec EXISTS et NOT EXISTS, mais cela n'a donné aucun résultat.

En outre, le site exécute encore la version 3.5.2 et ne souhaite pas effectuer de mise à niveau.

Voici ma requête la plus récente qui m'obtient les publications pour lesquelles le champ personnalisé publication_date est affiché dans le bon ordre:

$term = get_queried_object(); // find the term of the taxonomy page we are on
$wp_query = new WP_Query( array(
'post_type' => 'resource',
'tax_query' => array(
    array(
        'taxonomy' => 'resource_types',
        'field' => 'slug',
        'terms' => $term->name,
    )), 

'meta_key' => 'publication_date',
'orderby' => 'meta_value_num',
'order' => 'DESC',
'paged' => $paged,
'posts_per_page' => '10',
));

J'ai également essayé d'utiliser wpdb et d'exécuter une requête SQL, mais je ne suis vraiment pas sûr de savoir comment accomplir ce que je veux faire. Si quelqu'un pouvait m'aider, ce serait génial!

Merci d'avance.

19
CSSgirl

Merci à tous pour votre aide!

En fin de compte, la requête ci-dessous m'a permis d'obtenir les résultats souhaités - afficher et trier les articles en fonction d'un champ personnalisé de "date_publication" - en triant par date et par multiple (s'il y en avait plusieurs de la même date). Juin 2013), il les trierait par titre. Ensuite, après avoir parcouru tous les articles auxquels la date de publication est renseignée, il parcourra à nouveau les articles restants, en ordre alphabétique par titre.

Cela me permet d'obtenir les résultats définis dans la même requête et de conserver ma pagination:

$term = get_queried_object();
the_post();
$wp_query = new WP_Query( array(
'post_type' => 'resource',
    'tax_query' => array(
        array(
            'taxonomy' => 'resource_types',
            'field' => 'slug',
            'terms' => $term->name,
        )),
 'meta_query' => array(
       'relation' => 'OR',
        array( //check to see if date has been filled out
                'key' => 'publication_date',
                'compare' => '=',
                'value' => date('Y-m-d')
            ),
          array( //if no date has been added show these posts too
                'key' => 'publication_date',
                'value' => date('Y-m-d'),
                'compare' => 'NOT EXISTS'
            )
        ),
'meta_key' => 'publication_date',
'orderby' => 'meta_value title',
'order' => 'ASC',
'paged' => $paged,
'posts_per_page' => '10',
));
17
CSSgirl

Quelques années plus tard, le code posté par CSSGirl ne fonctionnait pas pour moi car certains messages ne contenaient pas de clé méta ou la clé méta était vide, c'est donc ce que je devais faire pour que tous les messages soient classés par date. et affichez ceux qui ont une valeur de méta-clé en premier:

$args          = array(
'post_type'   => $type,
'post_status' => 'publish',
'nopaging'    => TRUE,
'meta_query'  => array(
    'relation' => 'OR',
    array(
        'key'     => $meta_key,
        'compare' => 'NOT EXISTS',
    ),
    array(
        'relation' => 'OR',
        array(
            'key'   => $meta_key,
            'value' => 'on',
        ),
        array(
            'key'     => $meta_key,
            'value'   => 'on',
            'compare' => '!=',
        ),
    ),
),
'orderby'     => array( 'meta_value' => 'DESC', 'date' => 'DESC' ),
);
6
Ciprian Tepes

Je pense que vous auriez besoin de faire 2 boucles séparées. Vous pouvez capturer tous les articles trouvés dans la première boucle et les exclure assez facilement de la boucle secondaire:

$found_posts = array();
while($loop->have_posts()): $loop->the_post();
    // loop stuff
    $found_posts[] = get_the_id();
endwhile;

wp_reset_query();

$args = array(
    // other args
    'post__not_in' => $found_posts,
);

Ensuite, lancez votre deuxième boucle.

1
GhostToast

Y a-t-il une raison pour laquelle vous ne pourriez pas imposer la méta-clé publication_date à chaque poste ayant simplement une valeur vide?

Ainsi, dans votre action save_post, vous ajouteriez/mettriez à jour la clé méta, que la valeur $_POST soit vide ou non.

Vous devez exécuter un script de mise à jour pour parcourir vos publications plus anciennes et ajouter la clé avec une valeur vide, par exemple:

add_action( 'admin_init', 'update_old_posts' );
function update_old_posts() {
    if ( ! isset( $_GET[ 'update_old_posts' ] ) )
         return;

    foreach( get_posts() as $post ) {
        if ( false === get_post_meta( $post->ID, 'publication_date', true ) ) {
             update_post_meta( $post->ID, 'publication_date', '' );
             echo "Updated {$post->post_title} <br />";
        }
    }

    die;
}

Exécutez-le en recherchant http://example.com/wp-admin/?update_old_posts

Ensuite, vous pouvez utiliser la même requête que vous avez. Vous voudrez peut-être ajouter un filtre supplémentaire pour vous permettre de trier par colonnes différentes dans des directions différentes. Il me semblerait logique de trier par date en ordre décroissant et de titre en ordre croissant.

add_filter( 'posts_orderby', 'multicolumn_orderby', 10, 2 );
function multicolumn_orderby( $orderby, $query ) {
    global $wpdb;

    // check it's the right query
    if ( $query->get( 'meta_key' ) == 'publication_date' ) {
         $orderby = "$wpdb->postmeta.meta_value+0 DESC, $wpdb->posts.post_title ASC";
    }

    return $orderby;
}
0
sanchothefat

J'ai créé une clause where personnalisée. Je l'ai testé en utilisant $wp_query->request juste avant ma boucle principale. Je ne connais pas vraiment bien SQL, mais cela a semblé faire fonctionner les choses.

add_action('pre_get_posts', 'add_trending_sort', 11, 1);
function add_trending_sort($query){
  if(!$query->is_main_query())
    return;

  //Overwrite query arguments
  $query->set('meta_query', array(
    array(
      'key' => 'TRENDING',
      //'value' => 'asdfasdf',//may need a value for older versions of WordPress
      'compare' => 'NOT EXISTS',
    )
  ));
  $query->set('orderby', 'meta_value_num date');
  $query->set('order', 'DESC');
}

add_filter('posts_where', 'add_trending_where');
function add_trending_where($where = ''){
  global $wpdb, $wp_query;
  if(!$wp_query->is_main_query())//Not sure if this really works.  Should be OK
    return $where;

  $where .= " OR ( $wpdb->postmeta.meta_key = 'TRENDING' )";

  // Don't run this twice
  remove_filter('posts_where', 'add_trending_where');

  return $where;
}

Vous pouvez également définir compare sur 'EXISTS' et modifier la ligne de add_trending_where en $where .= " OR ($wpdb->postmeta.post_id IS NULL)";. Ensuite, il vous suffira de changer la valeur de la clé en un seul endroit. Encore une fois, relancez $wp_query->request et jouez si vous voulez mieux comprendre ceci ou modifiez-le.

EDIT: Je viens de remarquer que cela ne fonctionne pas si meta_key est défini sur la requête. Vous pouvez utiliser $query->set('meta_key', NULL); si vous devez le faire.

EDIT 2: Je travaille avec la méthode ci-dessus. Pour une raison quelconque, ce n'était pas au début (peut-être que meta_key était défini ... je ne sais pas).

add_action('pre_get_posts', 'add_trending_sort', 11, 1);
function add_trending_sort($query){
  // Bail if not the main "hidden" query, as opposed to a 'new WP_Query()' call
  if(!$query->is_main_query())
    return;

  // Set meta_query to get shares for orderby, and also get non-shared content.
  $query->set('meta_query', array(
    'relation' => 'OR',
    array(
      'key' => 'TRENDING',
      'compare' => 'NOT EXISTS',
    ),
    array(
      'key' => 'TRENDING',
      'compare' => 'EXISTS',
    )
  ));
  //$query->set('meta_key', NULL);
  $query->set('orderby', array('meta_value_num' => 'DESC', 'date' => 'DESC'));
}
0
Ryan Taylor