J'ai besoin de donner each post a unique commande pour plusieurs catégories (par publication), il est po Je peux imaginer une solution utilisant des champs personnalisés dans lesquels pour chaque catégorie il y a un personnalisé correspondant champ pour la commande.
Par exemple.
Catégories: Playlist1 Playlist2 Playlist3
Champs personnalisés pour le message: Playlist1_Order Playlist2_Order Playlist3_Order
Évidemment, cette méthode n’est pas facilement évolutive, alors j'aimerais savoir si quelqu'un a une solution plus élégante.
Je suis en train de créer un site pour accompagner une émission 24h/24 et 7j/7. La liste de lecture de l'émission est une boucle de 12 heures modifiée une fois par semaine. Certains spectacles sont ajoutés et supprimés et l'ordre de certains spectacles est réarrangé. J'ai l'intention de définir un type de publication personnalisé et une taxonomie personnalisée de la liste de lecture. Chaque émission sera ajoutée à une ou plusieurs listes de lecture. Il doit être possible pour le spectacle d'avoir un ordre unique dans chaque playlist.
(J'ai décidé de limiter la question aux articles et catégories plutôt qu'aux types d'articles et aux taxonomies afin d'éviter toute confusion).
Pour clarifier, considérons cet exemple. Il y a un article intitulé "Rod's Radio Roundup". C'est dans les catégories "Mardi Line" et "Mercredi". Mardi c'est le troisième spectacle et mercredi c'est le 7ème spectacle. Plus tard, il quittera mercredi mais passera à la 1ère place jeudi et à la 5ème place samedi. Et il y a 40 autres posts comme celui-ci.
La question essentielle: comment maintenir plusieurs commandes, une par catégorie, pour un seul poste?
Il y a une colonne inutilisée dans la table wp_term_relationships, term_order
, dont la valeur par défaut est 0 et qui est déjà convertie en entier.
Lorsqu'un terme est attribué à une publication, il reçoit une entrée dans cette table pour chaque terme attribué. Un object_ID (post_ID), un term_taxonomy_ID et le terme order sont définis sur 0.
Le term_taxonomy_ID est parfois différent du term_ID, vous devrez donc connaître vos term_taxonomy_ID pour chaque catégorie.
Étant donné que la valeur par défaut est toujours 0, vous avez besoin d'une méthode pour définir un nombre plus élevé, sinon toutes vos nouvelles publications viendront toujours en premier.
Vous aurez également besoin d'un moyen d'interroger ces publications, car term_order
ne fait pas partie de la classe WP_Query.
Vous aurez également besoin d'un moyen de trier ces messages. Je vais décrire la méthode de glisser-déposer Ajax que j’ai utilisée, mais vous pouvez également utiliser un champ métabox ou personnalisé.
Vous devrez créer une page d’options d’administrateur, interroger les publications et les exporter dans un tableau personnalisé ou une liste non ordonnée. Vous pouvez également exécuter cela en utilisant Ajax. Il suffit donc à l'utilisateur de sélectionner une catégorie dans une zone de sélection, puis de charger les publications de cette catégorie. (Je ne fournirai que les fonctions Ajax et Php pour sauvegarder la commande).
add_action ( 'wp_ajax_item_sort', 'wnd_save_item_order' );
function wnd_save_item_order () {
global $wpdb;
$wpdb->flush ();
$posts = $_POST[ 'order' ];
$str = str_replace ( "post-", "", $posts );
$order = explode ( ',', $str );
$cat_id = (int)$_POST[ 'cat' ];
$counter = 1;
foreach ( $order as $item_id ) {
$wpdb->query ( "UPDATE $wpdb->term_relationships SET term_order = '$counter' WHERE object_id = '$item_id' AND term_taxonomy_id = '$cat_id'" );
$counter++;
}
$response = '<div id="message" class="updated fade"> <p>Sort Order successfully updated</p></div>';
echo $response;
die( '<div id="message" class="updated fade"> <p>An error occured, order has not been saved.</p></div>' );
}
// Add this to the admin_enque_scripts and do a $pagenow check.
function sort_order_js() { ?>
jQuery(document).ready(function($) {
var catID = $("#cat-select option:selected").val()
$("#" + catID + "-save-order").bind("click", function() {
$("#" + catID + "-load-animation").show();
$.post(ajaxurl, { action:'item_sort', cat: catID, pos: position, order: $("#" + catID + "-sortable").sortable('toArray').toString() },
function(response) {
$("#" + catID + "-update-response").text('Updated');
$("#" + "-load-animation").hide();
});
return false;
});
<?php } ?>
add_filter('posts_orderby', 'custom_posts_orderby');
function custom_posts_orderby($order) {
$order_by = 'wp_term_relationships.term_order';
$direction = 'DESC';
$order = " ORDER BY $order_by $direction";
return $order;
}
Vous pouvez exécuter cette fonction en lui passant un tableau d'arguments similaire à WP_Query et elle retournera un tableau de post_ids
function custom_get_post_ids( $args ) {
$defaults = array (
'category_id' => NULL,
'exclude_array' => array (),
'post_status_array' => array ( 'publish' ),
'post_status' => NULL,
'post_type_array' => array ( 'post' ),
'post_type' => NULL,
'offset' => 0,
'length' => 7,
'order_by' => 'wp_term_relationships.term_order',
'order_direction' => 'ASC',
'secondary_order_by' => 'post_date',
'secondary_order_direction' => 'DESC',
);
$args = wp_parse_args( $args, $defaults );
extract( $args, EXTR_SKIP );
if ( isset( $post_type ) ) {
$post_type_array = array ( $post_type );
}
// If the post_status passed to us is a string, convert it to an array
if ( isset( $post_status ) ) {
$post_status_array = array ( $post_status );
}
global $wpdb;
$query = 'SELECT wp_posts.ID FROM wp_posts INNER JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)';
$query .= ' WHERE wp_term_relationships.term_taxonomy_id IN (' . intval( $category_id ) . ')';
if ( count( $exclude_array ) > 0 ) {
$exclude = implode( ',', $exclude_array );
$query .= ' AND wp_posts.ID NOT IN (' . $exclude . ')';
}
$query .= " AND wp_posts.post_type IN('" . implode( "','", $post_type_array ) . "')";
$query .= " AND wp_posts.post_status IN('" . implode( "','", $post_status_array ) . "')";
$query .= " ORDER BY $order_by $order_direction";
if ( ! empty( $secondary_order_by ) ) {
$query .= ",$secondary_order_by $secondary_order_direction";
}
$query .= " LIMIT $offset, $length /*_get_post_ids() */";
$num_results = $wpdb->query( $query );
$res = array ();
foreach ( $wpdb->last_result as $r ) {
array_Push( $res, intval( $r->ID ) );
}
return ( $res );
}
function default_sort_order() {
global $post, $wpdb;
$categories = get_the_category( $post->ID);
$id = $post->ID;
foreach ( $categories as $cat ) {
$cat_id = $cat->term_taxonomy_id;
$wpdb->query ( "UPDATE $wpdb->term_relationships SET term_order = 20 WHERE object_id = '$id' AND term_taxonomy_id = '$cat_id'" );
}
}
Cette méthode a été testée et est utilisée par une grande société de presse pour définir l'ordre d'affichage sur la page d'accueil et les pages de catégorie.
Cela devient rapidement très complexe. C’est peut-être pour cette raison que le PO n’est jamais revenu, car organiser des émissions en direct à l’aide de WP n’est pas une bonne idée (insertion d’annonces, règles de rotation, modifications en direct, etc.). La plupart de ces tâches sont mieux gérées par une application disposant d'une API spécifique basée sur ces besoins et disposant de flux XML/JSON permettant de lancer les données si nécessaire (comme dans WP).
Le problème d'ordre
Cette question de la commande en général et de la commande par glisser-déposer semble être un point sensible soulevé dans le passé, la plupart des membres de l’équipe centrale convenant que WordPress doit rester chronologique. Tout le reste devrait être une fonctionnalité de plugin pour les développeurs, le problème est qu'il y a un lot des personnes utilisant WordPress comme plate-forme de développement qui se heurtent à cela, WordPress est un CMS, à droite;)
Alors qu'est-ce que cela nous laisse?
Le glisser-déposer est vraiment intuitif, donc utiliser quelque chose comme la fonction .sortable();
de jQuery UI avec une entrée de base de données personnalisée ou un champ méta fonctionne bien. Vous pouvez à peu près faire la même chose que l’éditeur de galerie de messages par défaut (et l’éditeur de menus), dans lequel vous avez la possibilité de faire glisser une commande et de saisir manuellement un nombre et un paramètre de tri (ASC, DESC) que vous souhaitez. pourrait s'étendre à inclure le nom, ou n'importe quel paramètre WP Query/WPDB
.
Tout ce qui est plus complexe devrait reposer sur une sorte de système de règle de requête qui serait assez spécifique aux exigences actuelles.
Certains plugins que j'ai vus font cela, tels que PostMash et Orderly , mais rien que je sache ne soit vraiment complet, d'où la nécessité de pirater de nombreux fichiers modèles.
Je sais que vous avez dit "publications et catégories", mais je pense que vous ferez mieux de relier les publications aux publications et de stocker la commande en tant que métadonnées de publication:
créer un nouveau type de message, show
(recommandé, mais vous pouvez utiliser post
à la place)
créer un nouveau type de message, playlist
(recommandé, mais vous pouvez utiliser post
à la place)
créer une publication/une liste de lecture, Manche mardi, et enregistrer les métadonnées de la publication shows = 8,73,5,68,994
(une liste ordonnée d'identifiants d'émission). (Le champ de relation ACF ajoute un great UI pour cela, mais le principe est le même sans cela.)
lors de l'affichage de chaque publication/liste de lecture, lisez la valeur de shows
, récupérez ces publications et affichez-les dans l'ordre.
Pour faire cela dans EXTREME code pseudo vous voulez vraiment essayer:
switch($cat_id) {
case 1:
$args = "sort rules for cat 1";
break;
case 2:
$args= "sort rules for cat 2";
break;
etc...
default:
$args= "default sort rules";
break;
}
$posts = get_posts($args);
Remarque: avec cette méthode, définissez uniquement les "exceptions" avec les clauses case
et la "règle" avec default
.
Simple. PHP pour et WordPress get_posts () et quelques vérifications feront l'affaire.
Vous pouvez modifier $args['orderby']
et $args['order']
pour trier la manière dont vous avez besoin de le faire. Afficher Order & Orderby Parameters
Je n'ai pas testé, mais ça devrait marcher!
function get_content($type, $categories){
for($i = 0; $i < count($categories); $i++){
// configure posts
$args = array(
'numberposts' => -1,
'offset' => 0,
'category_name' => $categories[$i],
'include' => '',
'exclude' => '',
'meta_key' => '',
'meta_value' => '',
'post_type' => $type,
'post_mime_type' => '',
'post_parent' => '',
'post_status' => 'publish'
);
// define different sorting methods depending on category
if($categories[$i] == 'playlist-1'){
$args['orderby'] = 'post_date';
$args['order'] = 'DESC';
} elseif($categories[$i] == 'playlist-2'){
$args['orderby'] = 'post_date';
$args['order'] = 'ASC';
} elseif($categories[$i] == 'playlist-3'){
$args['orderby'] = 'post_title';
$args['order'] = 'ASC';
}
// fetch the posts
$postData[$categories[$i]] = get_posts($args);
}
return $postData;
}
// Choose the categories to sort
$categories = array('playlist-1', 'playlist-2', 'playlist-3');
// This will contain all categories and posts inside one array.
$allPosts = get_content('post', $categories);
//print_r($allPosts);
// EXAMPLE: To loop through a set of posts, you will need to access it like so
for($i = 0; $i < count($categories['playlist-1']); $i++){
echo '<h1>'.$categories['playlist-1'][$i]['post_title'].'</h1>';
echo apply_filter('the_content', $categories['playlist-1'][$i]['post_content']);
}
OR
function get_content_taxonomy($tax, $term){
$wp_query = new WP_Query();
$wp_query->query(array('posts_per_page' => -1, 'orderby' => 'title', 'order' => 'ASC', 'tax_query' => array(array('taxonomy' => $tax, 'field' => 'slug', 'terms' => $term))));
$posts = $wp_query->posts;
if(!empty($posts)){
$return = $posts;
}
return $return;
}
// No idea how you have your stuff setup, but it could be like:
$playlist1 = get_content_taxonomy('playlist', '1');
// print_r($playlist1);