Obține slug-ul tipului de postare personalizat pentru o pagină de arhivă
Cum pot descoperi slug-ul tipului de postare personalizat când mă aflu pe o pagină de arhivă?
De exemplu, dacă /products/
declanșează șablonul archive-products.php
, cum pot obține (programatic) slug-ul tipului de postare?
Mulțumesc

Pentru a obține tipul curent de postare folosește get_post_type()
. Apoi folosește get_post_type_object()
pentru toate datele de care ai nevoie, de exemplu slug-ul:
$post_type = get_post_type();
if ( $post_type )
{
$post_type_data = get_post_type_object( $post_type );
$post_type_slug = $post_type_data->rewrite['slug'];
echo $post_type_slug;
}

Cred că (nu am testat) get_queried_object()
ar obține aceeași informație cu mai puține operații.

@Rarst Poate, dar cred că codul pe care l-am sugerat este mai ușor de înțeles.

Soluția lui Toscho este greșită, deoarece get_post_type returnează tipul de postare al paginii curente, iar când te afli pe o pagină de arhivă, această funcție returnează întotdeauna "page". Caut să rezolv același lucru: Când sunt pe pagina de arhivă pentru 'cărți' (de exemplu), vreau să obțin: 'cărți'. Când o să reușesc, voi posta soluția.

din păcate nu este atât de simplu, deși ar fi mai bine să folosești doar $posttype = get_query_var('post_type');
... Am adăugat o alternativă cuprinzătoare.

Nu cred că acest răspuns acoperă întreaga poveste. Ar trebui să verifici regulile de rescriere instalate, deoarece multe filtre (cum ar fi pagina de magazin WooCommerce) fac modificări. Folosește mecanismul propriu al WordPress în schimb, vezi răspunsul meu mai jos.

Folosesc acest cod în afara loop-ului în template-ul archive.php pentru a afla în ce arhivă de postări personalizate mă aflu.
Este o combinație a metodelor recomandate atât de @toscho cât și de @Rarst:
$post_type = get_queried_object();
echo $post_type->rewrite['slug'];
Actualizare: @majick a menționat că acest lucru funcționează doar dacă ai setat rewrite slug pentru CPT-ul tău. Rewrite slug este opțional la înregistrarea unui CPT și implicit va folosi post_type dacă nu este setat.

când am încercat asta am primit Notice: Undefined property: stdClass::$rewrite in ***\wp-content\themes\marks-remarks\archive.php on line 4

acest lucru va funcționa doar dacă rewrite slug este setat pentru CPT înregistrat, deoarece este opțional și implicit este post_type

Mulțumesc pentru observație @majick! Am actualizat postarea pentru a reflecta informația ta.

Răspunsurile devin confuze. Și poate și eu sunt, dar întrebarea principală este:
Obține slug-ul tipului de postare personalizat pentru o pagină de arhivă
Dacă te referi la pagina de arhivă a tipului de postare (landing-page), și când is_post_type_archive()
returnează true
, iar tu vrei slug-ul care răspunde arhivei curente vizualizate:
/* returnează /products/ */
$responding_name = str_replace(get_home_url(), '', get_post_type_archive_link(get_query_var('post_type')));
/* continuă să obții 'products' fără slash-uri */
$responding_name = str_replace('/', '', $responding_name);
-- SFÂRȘITUL RĂSPUNSULUI LA ÎNTREBARE --
Explicație:
Nu te poți baza pe slug-ul înregistrat. Nici WordPress nu o face. De exemplu, când apelezi get_post_type_archive_link()
, WordPress verifică regulile de rescriere curente pentru instalarea ta.
Oriunde te afli, în interiorul sau în afara loop-ului, în arhiva curentă sau într-un post singular, inversează mecanismul get_post_type_archive_link()
. (Cu permalink-uri activate.)
Considerații:
După cum s-a menționat aici, tipul/tipurile de postări din interogarea curentă pot fi un array
. Poți merge mai departe cu intențiile tale prin filtrarea tipului de postare pe care îl cauți, de exemplu:
$post_type = get_query_var('post_type');
if(is_array($post_type)) $post_type = reset($post_type);
sau
if(isset($post_types[0])) $post_type = $post_types[0];
Alt punct de vedere:
Exemplu WooCommerce, este înregistrat cu obiectul tip de postare 'products', dar în realitate folosește numele rescris al regulii (shop):
/* returnează shop */
$responding_name = str_replace('/', '', str_replace(get_home_url(), '', get_post_type_archive_link('product')));
Mark, folosesc
$responding_name
, deoarece obiectivele pot varia. O arhivă de postări nu există, este doar un URL.

Asta a clarificat foarte mult situația, mulțumesc. Căutam această soluție. Dacă întrebarea nu era despre „doar numele tipului de postare”, acesta ar fi trebuit să fie răspunsul votat cel mai mult.

Trebuie remarcat faptul că, dacă has_archive
este setat la true în timpul înregistrării Tipului de Postare Personalizat (CPT), arhiva tipului de postare /cptslug/
va fi rescrisă intern la ?post_type=cptslug
. Aceasta înseamnă, de asemenea, că is_post_type_archive()
va returna true.
Din păcate, atunci când slug-ul de rewrite înregistrat este diferit de tipul de postare, nu obții în mod fiabil post_type
. De exemplu, dacă tipul tău de postare este myplugin_cars
și slug-ul tău de rewrite este cars
, iar tu ai nevoie să obții myplugin_cars
, chiar și acest cod (pentru a preveni erori dacă obiectul interogat curent nu este un tip de postare personalizat) va eșua:
$queryobject = get_queried_object();
if (has_property('rewrite',$queryobject)) {
if (isset($queryobject->rewrite['slug'])) {
$posttype = $queryobject->rewrite['slug'];
}
}
Dar, deoarece is_post_type_archive
este true, această abordare este mai fiabilă:
if (is_post_type_archive()) {
$posttype = get_query_var('post_type');
// care este practic același lucru cu:
// global $wp_query;
// $posttype = $wp_query->query_vars['post_type'];
}
else ($posttype = 'post';}
Dar stai, mai este ceva... se pare că, după câteva teste, nu este atât de simplu... Ce se întâmplă dacă ești pe o pagină de arhivă a taxonomiei cu mai multe tipuri de postări în taxonomie? Sau atribuiți etichete de postări unui tip de postare personalizat diferit de post? Sau sunteți pe o pagină de arhivă a autorului? Pagină de arhivă după dată? ...sau chiar aveți un tax_query
sau meta_query
complex pentru WP_Query
?
Singurul răspuns fiabil (fără a testa fiecare caz posibil de arhivă) este să parcurgi postările efective din interogare... Iată funcția completă pe care am conceput-o pentru a funcționa atât pe paginile singular, cât și pe cele de arhivă, permițându-vă să transmiteți opțional un obiect de interogare personalizat (sau un obiect de postare/ID de postare pentru postări singular):
function get_current_post_types($object=null) {
// dacă este transmisă o valoare numerică, presupunem că este un ID de postare
if ( ($object) && (is_numeric($object)) ) {$object = get_post($object);}
// dacă este transmis un obiect, presupunem că este un obiect de postare
if ( ($object) && (is_object($object)) ) {return get_post_type($object);}
// verificări standard pentru tipul de postare singular
if (is_404()) {return '';}
// actualizare: am eliminat această verificare, gestionată de is_singular
// if (is_single()) {return 'post';}
if (is_page()) {return 'page';}
if (is_attachment()) {return 'attachment';}
if (is_singular()) {return get_post_type();}
// dacă nu a fost transmis un obiect de interogare personalizat, folosește globalul $wp_query
if ( (!$object) || (!is_object($object)) ) {
global $wp_query; $object = $wp_query;
}
if (!is_object($object)) {return '';} // nu ar trebui să eșueze
// dacă variabila de interogare post_type a fost setată explicit
// (sau implicit setată pe CPT prin redirect has_archive)
// adică acest lucru este adevărat pentru is_post_type_archive cel puțin
// $vqueriedposttype = get_query_var('post_type'); // doar $wp_query
if (property_exists($object,'query_vars')) {
$posttype = $object->query_vars['post_type'];
if ($posttype) {return $posttype;}
}
// gestionează toate celelalte cazuri parcurgând postările din obiectul de interogare
$posttypes = array();
if (method_exists($object,'found_posts')) {
if ($object->found_posts > 0) {
$queriedposts = $object->posts;
foreach ($queriedposts as $queriedpost) {
$posttype = $queriedpost->post_type;
if (!in_array($posttype,$posttypes)) {$posttypes[] = $posttype;}
}
if (count($posttypes == 1)) {return $posttypes[0];}
else {return $posttypes;}
}
}
return ''; // nimic de văzut aici
}
Aceasta va returna în mod fiabil (am spus asta?) un array de tipuri de postări dacă sunt prezente mai multe, sau un șir cu tipul unic de postare dacă există doar unul. Tot ce trebuie să faci este:
$posttypes = get_current_post_types();
// sau transmite un ID de postare
$posttypes = get_current_post_types($postid);
// sau transmite un obiect de postare
$posttypes = get_current_post_types($post);
// sau transmite o interogare personalizată - care a fost executată
$posttypes = get_current_post_types($query);
Exemplu de Utilizare (doar pentru distracție):
add_filter('the_posts','myplugin_fading_thumbnails',10,2);
function myplugin_fading_thumbnails($posts,$query) {
if (!is_archive()) {return $posts;}
$cptslug = 'myplugin_slug'; $dosomethingcool = false;
$posttypes = get_current_post_types($query);
if ( (is_array($posttypes)) && (in_array($cptslug,$posttypes)) ) {$dosomethingcool = true;}
elseif ($cptslug == $posttypes) {$dosomethingcool = true;}
if ($dosomethingcool) {
global $fadingthumbnails; $fadingthumbnails = $cptslug;
if (!has_action('wp_footer','myplugin_cpt_script')) {
add_action('wp_footer','myplugin_cpt_script');
}
}
function myplugin_cpt_script() {
global $fadingthumbnails;
echo "<script>var thumbnailclass = 'img.thumbtype-".$fadingthumbnails."';
function fadeoutthumbnails() {jQuery(thumbnailclass).fadeOut(3000,fadeinthumbnails);}
function fadeinthumbnails() {jQuery(thumbnailclass).fadeIn(3000,fadeoutthumbnails);}
jQuery(document).ready(function() {fadeoutthumbnails();});
</script>";
}
return $posts;
}
Pentru a vedea efectul, schimbă tipul de postare personalizat din cod în post
și adaugă un atribut de clasă thumbtype-post
la imaginile miniatură ale postărilor tale...

este nevoie de $queried_object->query_var['post_type'];
pentru ca asta să funcționeze...

Nu. $queried_object->query_var conține doar șirul tipului de post. nu este obiect sau array. uită-te la această imagine: http://prntscr.com/bd58e1

ok, dar doar dacă obiectul interogat este cu siguranță un obiect de tip post personalizat, vei obține un obiect diferit și astfel o valoare goală pentru paginile de arhivă de categorie/taxonomie/tag/autor de exemplu. chiar și pentru ?post_type=post
primesc gol. compară cu get_query_var('post_type');
