Activarea articolelor sticky pentru custom post_type
Am acest custom post_type: tvr_apartment
function custom_post_apartment() {
$labels = array(
'name' => 'Apartamente',
'singular_name' => 'Apartament',
'add_new' => 'Adaugă Nou',
'add_new_item' => 'Adaugă Apartament Nou',
'edit_item' => 'Editează Apartament',
'new_item' => 'Apartament Nou',
'all_items' => 'Toate Apartamentele',
'view_item' => 'Vezi Apartament',
'search_items' => 'Caută Apartamente',
'not_found' => 'Nu s-au găsit apartamente',
'not_found_in_trash' => 'Nu s-au găsit apartamente în coșul de gunoi',
'parent_item_colon' => '',
'menu_name' => 'Apartamente'
);
$args = array(
'labels' => $labels,
'public' => true,
'query_var' => true,
'rewrite' => true,
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => null,
'taxonomies' => array('rf_apartment_feature'),
'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt' )
);
register_post_type( 'tvr_apartment', $args );
}
Și aș dori să activez funcționalitatea de postări sticky pentru acesta,
Am căutat aici: http://codex.wordpress.org/Function_Reference/post_type_supports
Dar se pare că nu este calea de urmat, aveți idei?

Conform biletului trac extins și de lungă durată #12702, tipurile personalizate de postări (CPT) nu oferă (și probabil nu vor oferi niciodată) suport pentru funcționalitatea de postări lipicioase (sticky).
Probabil nu este imposibil să refolosim această funcționalitate (cu o cantitate imensă de cod duplicat și cazuri limită) pentru CPT într-un site personalizat, dar în opinia mea o soluție personalizată (probabil bazată pe câmpuri personalizate) ar fi o abordare mai practică și mai curată.

Folosesc un plugin https://cs.wordpress.org/plugins/seamless-sticky-custom-post-types/

Editare 2022:
Acum poți folosi plugin-ul menționat în răspunsul lui @Ray! Testat și pare să salveze atributul sticky într-un mod nativ, astfel încât poți folosi de exemplu ignore_sticky_posts
Răspunsul Original:
Deoarece niciunul dintre plugin-urile existente pentru acest scop nu suportă WP5, o soluție simplă (dar nu ideală) este să folosești o nouă metabox. În plugin-ul tău pentru CPT:
add_meta_box('pseudosticky', 'Este sticky', 'addbox', 'SLUG-UL TĂU PENTRU TIPUL DE POSTARE PERSONALIZATĂ AICI', 'normal', 'high');
function addbox($post, $metabox) {
$entered = get_post_meta($post->ID, 'pseudosticky', true);
?>
<label><input name="pseudosticky" type="checkbox"<?if($entered=="on")echo' checked="checked"';?>> Este sticky</label>
<?
}
Apoi în interogare
'meta_query' => array(
array(
'key' => 'pseudosticky',
'value' => "on",
'compare' => '='
)
//aici pot fi adăugate mai multe condiții meta sub formă de array-uri
),

Am reușit să fac următoarea soluție să funcționeze. Permiteți-mi să descriu tehnica astfel încât să puteți decide dacă să o utilizați sau nu.
codul utilizează două hook-uri, unul declanșat chiar înainte ca meta box-urile "laterale" să fie plasate și altul imediat după secțiunea "dată/ora" din meta box-ul de publicare.
primul hook (înainte) înregistrează tipul original de postare, apoi îl schimbă la "post", WordPress crede că este o postare și setează câmpurile implicite specifice tipului de postare "post".
al doilea hook (după) va reseta tipul de postare înapoi la cel original.
Dacă cineva întâmpină probleme sau poate identifica cazuri de utilizare neprevăzute în care această tehnică ar putea eșua, vă rog să răspundeți.
// vezi /wp-admin/edit-form-advanced.php .. de la wp 2.5.0
add_action( 'submitpost_box', function() {
// fyi .. nu se poate folosi acțiunea "post_submitbox_minor_actions" (/wp-admin/includes/meta-boxes.php) deoarece $post_type este setat devreme
global $post;
if ( isset( $post->post_type ) && in_array( $post->post_type, array( 'post_type_1', 'post_type_2' ) ) ) {
echo 'înainte'; // depanare
$post->post_type_original = $post->post_type;
$post->post_type = 'post';
}
} );
// vezi /wp-admin/includes/meta-boxes.php .. de la wp 2.9.0
add_action( 'post_submitbox_misc_actions', function() {
global $post;
if ( isset( $post->post_type_original ) && in_array( $post->post_type_original, array( 'post_type_1', 'post_type_2' ) ) ) {
echo 'după'; // depanare
$post->post_type = $post->post_type_original;
unset( $post->post_type_original );
}
} );
Notă: codul de mai sus se ocupă de adăugarea opțiunii în interfața utilizatorului, dar tot va trebui să verificați și să lucrați cu postări sticky în șabloanele/ieșirile dumneavoastră .. ceva similar cu următorul exemplu (doar fără plugin):

Pentru cei care caută, pot confirma că acest plugin funcționează în versiunea WP 5.9: https://wordpress.org/plugins/sticky-posts-switch/

Am fost surprins să aflu că această funcționalitate încă nu este disponibilă.
Speram cel puțin că în WP_Query
vom avea ceva similar cu sticky_posts
unde să putem trimite ID-urile postărilor, dar nu am găsit așa ceva.
Așa că am făcut următoarea soluție:
<?php
$args = array( 'post_type' => 'some_post_type', 'posts_per_page' => 20 , 'orderby' => 'title', 'order' => 'ASC');
$loop = new WP_Query( $args );
$sticky_posts = array( 11462 ); // aici introduci ID-urile postărilor pe care dorești să le faci sticky
// Este necesar să afișăm postările sticky
while ( $loop->have_posts() ) : $loop->the_post();
if ( in_array($post->ID, $sticky_posts) ):
echo "Sunt STICKY!";
endif;
endwhile;
while ( $loop->have_posts() ) : $loop->the_post();
if ( !in_array($post->ID, $sticky_posts) ):
echo "Nu sunt sticky :( ";
endif;
endwhile;
Desigur, aceasta nu este cea mai bună soluție, are mai multe limitări, dar a funcționat pentru cerința mea simplă unde aveam nevoie doar de o singură postare să fie mereu în top.
Probleme/Limitări:
- Trebuie să modifici blocul de cod unde ai interogările și să adaugi mai multe bucle.
- Nu poți ordona postările într-un mod personalizat.
- Doar postările din interogarea curentă vor apărea, deci dacă ai o postare sticky dincolo de limita setată de posts per page, atunci acea postare nu va fi sticky, cel puțin nu pe acea pagină.
