Adăugați tipul mesajului Arhivați legăturile la meniul dvs.

O solicitare obișnuită, în special pentru cei care au creat tipuri personalizate de posturi precum "Știri" sau "Evenimente", este să adăugați un link la pagina de arhivă a tipului de postare din meniul de navigare. În prezent, totuși, acest lucru se poate face numai prin introducerea manuală a adresei URL de arhivă de tip post. În afară de a fi destul de inelegant, această soluție are câteva dezavantaje: aceasta nu apare întotdeauna ca fiind "actuală", dacă schimbați structura dvs. permalink ar putea rupe linkul, adăugând manual adresele URL este obositoare și link-ul nu apare ca fiind " curent "atunci când se află pe postul respectivului post.

În acest tutorial vă voi arăta cum să creați un plugin care creează o meta-casetă în pagina Meniu Aspect -> Meniu, care vă permite să adăugați linkuri de arhivă tip post. Aceste legături nu suferă de dezavantajele menționate mai sus.


Pasul 1 Crearea unui plugin

Acest plugin va fi denumit "My Posts Type Archive Links" și, în acest scop, va crea mai întâi un dosar numit Arhiva-post-tip-mi-link-uri sub dumneavoastră / Wp-content / plugins / dosarul și interiorul care creează un fișier Arhiva-post-tip-mi-links.php. Acest fișier este fișierul plugin principal. O vom înfășura într-o clasă - pur și simplu nu trebuie să ne facem griji că numele funcțiilor noastre se contrazic cu WordPress sau alte pluginuri: pur și simplu trebuie să ne asigurăm că numele nostru de clasă este unic. Adăugați următoarele la Arhiva-post-tip-mi-links.php

  Pagina de meniu pentru a adăuga link-uri de tip arhivă Autorul: Stephen Harris Autor URI: http://profiles.wordpress.org/users/stephenh1988/ * / class My_Post_Type_Archive_Link // Totul merge aici My_Post_Type_Archive_Link :: load (); ?>

Totul din acest tutorial va sta în interiorul acelei clase.


Pasul 2 Încărcarea pluginului

Când fișierul plugin este încărcat, acesta va declanșa metoda de clasă sarcină(). Această metodă va fi responsabil pentru adăugarea de acțiuni și filtre pe diferite cârlige WordPress. Vom trece prin fiecare dintre ei în etapele ulterioare, dar oferă, de asemenea, un rezumat util. Adăugați următoarea metodă la clasa noastră:

 funcția de încărcare publică () // funcția Hook pentru a adăuga metaboxul în pagina de meniu add_action ('admin_init', array (__ CLASS __, 'add_meta_box')); // Javascript pentru caseta meta add_action ('admin_enqueue_scripts', array (__ CLASS __, 'metabox_script')); // Ajax callback pentru a crea un element de meniu și a-l adăuga în meniu add_action ('wp_ajax_my-add-post-type-archive-links', array (__CLASS__, 'ajax_add_post_type')); // Alocați elementul de meniu url-ul corespunzător add_filter ('wp_setup_nav_menu_item', array (__ CLASS __, 'setup_archive_item')); // Creați un post de arhivare post link 'curent' add_filter ('wp_nav_menu_objects', array (__ CLASS __, 'maybe_make_current')); 

Să rezumăm ceea ce face fiecare dintre aceste părți:

  1. Adăugați o meta-casetă - Destul de explicativ. Funcția de cuplare va fi responsabilă pentru adăugarea metalei noastre.
  2. Enqueue JavaScript - Noi folosim admin_enqueue_scripts cârlig pentru a enqueue fișierul nostru JavaScript. JavaScript-ul nostru, când se face clic pe "adăugați la meniu", va declanșa o solicitare AJAX.
  3. AJAX callback - Această funcție este responsabilă pentru gestionarea solicitării AJAX de mai sus. Acesta va crea elementele de meniu și le va adăuga în meniu.
  4. Se configurează elementul de meniu - Acest lucru asigură că atunci când link-ul de arhivă apare în meniul dvs., acesta indică corect arhiva tipului de post.
  5. Poate face curent - Ori de câte ori apare un meniu, elementele sale sunt trecute printr-un filtru, vom asigura că clasa "curent-meniu-element"se adaugă la link-ul corespunzător tip post.

Pasul 3 Adăugarea metaboxului

Mai intai ne definim add_meta_box , care pur și simplu numește funcția WordPress add_meta_box (). Detaliile acestei funcții au fost acoperite de mai multe ori înainte, dar dacă nu sunteți sigur că puteți citi în paginile Codex.

 funcția publică add_meta_box () add_meta_box ('post-type-archives', __ ('Tipuri de posturi', link-uri de tip post-arhivă), array (__ CLASS __, metabox) , 'lateral', 'scăzut'); 

Apoi definim funcția de retransmisie meta-box, care este responsabilă pentru afișarea insulelor metabox:

 funcția publică funcțională metabox () global $ nav_menu_selected_id; // Obțineți tipuri de post $ post_types = get_post_types (array ('public' => true, '_ builtin' => false), 'object');  

value =“"name =" add-post-type-item-item "/>

Această metodă face pur și simplu toate tipurile de posturi publice personalizate cu get_post_types () și apoi buclele prin ele pentru a crea o listă de casete de selectare. Fiecare casetă de selectare are numele tipului de post ca valoare. În pasul următor vom adăuga javascript care va fi declanșat când un utilizator face clic pe butonul "Adăugați la meniu".


Pasul 4 JavaScript

Vrem doar să închidem JavaScript pe pagina Aspect -> Meniu admin. Am folosit-o admin_enqueue_scripts cârlig care se declanșează numai în paginile de admin și trece ca cârlig cârligul paginii. Cârligul pentru pagina Aspect -> Meniu este nav-menus.php. După ce am enumerat scenariul pe care îl folosim wp_localize_script pentru a face nonce disponibile în JavaScript. Includem aceasta în cererea AJAX pentru a verifica dacă acțiunea a fost intenționată.

 funcția publică metabox_script ($ hook) if ('nav-menus.php'! = $ hook) retur; // Pe Aspect> pagina Meniu, script enqueue: wp_enqueue_script ('my-post-type-archive-links_metabox', plugins_url ('/ metabox.js', __FILE__), array ('jquery')); // Adăugați variabila nonce variabilă wp_localize_script ('my-post-type-archive-links_metabox', 'MyPostTypeArchiveLinks', array ('nonce' => wp_create_nonce ('my-add-post-type-archive-links'))); 

În pasul anterior, butonul "Adăugați la meniu" a primit ID-ul submit-post-arhive de tip. Utilizăm acum jQuery pentru a viza acel buton și, când faceți clic, trimiteți o solicitare AJAX pentru a crea elementul de meniu și a-l adăuga în meniu. Următoarea este singura parte a acestui tutorial care trăiește în afara clasei noastre. Ar trebui să meargă într-un fișier numit metabox.js, în interiorul dosarului nostru plug-in.

 jQuery (document) .ready (functie ($) $ ('submit-post-type-archives'). ] () ($) () (* # post-type-archive-list de verificare li: checked '). (de exemplu: "my-add-post-type-archive-links", posttypearchive_nonce: MyPostTypeArchiveLinks.nonce, post_types: postTypes, / * AJAX returneaza html pentru a adauga la meniu * / funcția (răspunsul) $ ('# meniu-pentru-editare').

Observați adresa URL la care trimitem solicitarea: ajaxurl. Nu l-am definit nicăieri. Este o variabilă globală stabilită de WordPress numai pe partea de administrare care indică pagina pe care WordPress o folosește pentru a gestiona solicitările AJAX. Când se face clic pe butonul de trimitere, numele tipurilor postate verificate, o acțiune unică și nonce sunt trimise la această adresă URL. Când WordPress primește cererea, declanșează wp_ajax_my-add-post-arhiva-link-uri de tip cârlig. Nonce este o măsură de precauție pentru a vă asigura că acțiunea a fost intenționată.


Pasul 5 AJAX Callback

Definim acum funcția de apel invers AJAX ajax_add_post_type.

 funcția publică ajax_add_post_type () if (! current_user_can ('edit_theme_options')) die ('- 1'); check_ajax_referer ('my-add-post-type-archive-links', 'posttypearchive_nonce'); require_once ABSPATH. 'Wp-admin / include / nav-menu.php'; dacă (gol ($ _ POST ['post_types'])) ieșire; // Creați elemente de meniu și stocați ID-urile în matrice $ item_ids = array (); foreach ((array) $ _POST ['post_types'] ca $ post_type) $ post_type_obj = get_post_type_object ($ post_type); dacă (! $ post_type_obj) continuați; $ menu_item_data = array ('meniu-item-title' => esc_attr ($ post_type_obj-> labels-> nume) $ post_type), 'meniu-item-url' => get_post_type_archive_link ($ post_type)); // Colectați ID-urile elementelor. $ item_ids [] = wp_update_nav_menu_item (0, 0, $ meniu_item_data);  // Dacă a apărut o eroare aici dacă (is_wp_error ($ item_ids)) mor ('- 1'); // Configurați elementele de meniu foreach ((array) $ item_ids ca $ menu_item_id) $ menu_obj = get_post ($ menu_item_id); dacă (! gol ($ meniu_obj-> ID)) $ menu_obj = wp_setup_nav_menu_item ($ meniu_obj); $ menu_obj-> label = $ meniu_obj-> titlu; // nu se afișează "(în așteptare)" în articole adăugate ajax $ menu_items [] = $ menu_obj;  // Aceasta devine codul HTML pentru a-l readuce în meniu dacă (! Empty ($ menu_items)) $ args = array ('după' => 'link_before' => ',' walker '=> Walker_Nav_Menu_Edit nou); echo walk_nav_menu_tree ($ meniu_items, 0, (obiect) $ args);  În final, nu uitați să ieșiți din ieșire; 

Să mergem prin acest apel invers un pic la un moment dat. Mai intai verificam permisiunile utilizatorului, verificam nonce si incarcam nav-menu.php (avem nevoie de unele funcții).

 dacă (! current_user_can ('edit_theme_options')) mor ('- 1'); check_ajax_referer ( 'mi-add-post-tip-archive-link-uri', 'posttypearchive_nonce'); require_once ABSPATH. 'Wp-admin / include / nav-menu.php'; dacă (gol ($ _ POST ['post_types'])) ieșire;

Apoi, creăm un element de meniu pentru fiecare tip de post selectat. Mai întâi verificăm tipul postului pe care l-am primit, verificând valoarea returnată de get_post_type_object (). Putem obține legătura de arhivă cu funcția get_post_type_archive_link ()

Elementele de meniu sunt, de fapt, mesaje de tip post "nav_menu_item"cu post meta construit, inclusiv câmpurile referitoare la"URL-ul","tip' și 'obiect“. Obiectele 'tip"este în mod normal"personalizat","post_type"sau"taxonomie"- dar vom stabili valoarea sa la"post_type_archive“. Obiectele 'obiect"valoarea meta este, în mod normal, utilizată numai pentru elementele"post_type"sau"taxonomie"și se referă la tipul de post sau la taxonomia la care se referă linkul. Vom folosi acest lucru pentru a stoca tipul de post al linkului de arhivă.

 // Creați elemente de meniu și stocați ID-urile în matrice $ item_ids = array (); foreach ((array) $ _POST ['post_types'] ca $ post_type) $ post_type_obj = get_post_type_object ($ post_type); dacă (! $ post_type_obj) continuați; $ menu_item_data = array ('meniu-item-title' => esc_attr ($ post_type_obj-> labels-> nume) $ post_type), 'meniu-item-url' => get_post_type_archive_link ($ post_type)); // Colectați ID-urile elementelor. $ item_ids [] = wp_update_nav_menu_item (0, 0, $ meniu_item_data);  // Dacă a apărut o eroare aici dacă (is_wp_error ($ item_ids)) mor ('- 1');

Apoi vom genera pur și simplu HTML care va fi adăugat la meniu. Noi folosim $ ITEM_IDS array pentru a obține o serie de elemente de meniu și pentru a trece acest lucru la o clasă Walker WordPress pentru a face munca grea pentru noi.

 // Configurați elementele de meniu foreach ((array) $ item_ids ca $ menu_item_id) $ menu_obj = get_post ($ menu_item_id); dacă (! gol ($ meniu_obj-> ID)) $ menu_obj = wp_setup_nav_menu_item ($ meniu_obj); $ menu_obj-> label = $ meniu_obj-> titlu; // nu se afișează "(în așteptare)" în articole adăugate ajax $ menu_items [] = $ menu_obj;  // Aceasta devine codul HTML pentru a-l readuce în meniu dacă (! Empty ($ menu_items)) $ args = array ('după' => 'link_before' => ',' walker '=> Walker_Nav_Menu_Edit nou); echo walk_nav_menu_tree ($ meniu_items, 0, (obiect) $ args);  În final, nu uitați să ieșiți din ieșire;

Pasul 6 Elementul de meniu

Din păcate, din cauza unui bug cu WordPress, dacă tipul articolului nu este "taxonomie","personalizat"sau"post_type"URL-ul este eliminat. Pentru a contracara acest lucru,post_type_archive'este utilizat într-un meniu, re-adăugăm manual adresa URL. Acest lucru asigură, de asemenea, că link-ul de arhivă este "actualizat" (în cazul în care structura permalink a fost modificată).

 funcția publică setup_archive_item ($ menu_item) if ($ menu_item-> type! = 'post_type_archive') retur $ $ menu_item; $ post_type = $ meniu_item-> obiect; $ meniu_item-> url = get_post_type_archive_link ($ post_type); retur $ $ menu_item; 

Pasul 7 Efectuarea curentului de legătură

În cele din urmă, trebuie să facem elementul "curent" atunci când suntem pe pagina potrivită. Vreau ca link-ul de tip arhivă postare să fie evidențiat ca curent dacă suntem pe acea pagină de arhivă sau să vedem o singură postare de acel tip. Pentru aceasta, verific:

  • is_post_type_archive ()
  • is_singular ()

Pentru a face obiectul curent, trebuie doar să adăugăm curent-meniu-element la clasele elementului în care sunt stocate $ Item-> clase. Apoi, trebuie să ne întoarcem prin părinți în meniu și să adăugăm clasele current_item_parent și current_item_ancestor. Să aruncăm o privire asupra fiecărui bit individual:

Vom trece prin fiecare dintre elementele din meniu:

 funcția publică may_make_current ($ items) foreach ($ items as $ item) // Aici verificăm elementul return $ items; 

Dacă elementul nu este "post_type_archive"sau dacă este, dar nu vrem să o facem" curentă ", pur și simplu mergem spre următorul articol. Rețineți că pentru linkurile noastre de arhivă tipul de postare este stocat ca obiect al elementului. Deci, în interiorul pentru fiecare buclă:

 dacă ('post_type_archive'! = $ item-> type) continuați; $ post_type = $ item-> object; dacă (! is_post_type_archive ($ post_type) &&! is_singular ($ post_type)) continuați;

Dacă vrem să facem acest lucru, îl oferim clasei potrivite și apoi îi luăm pe părinți în meniu. Elementul parental al unui element de meniu este stocat ca meta meta cu tasta meta _menu_item_menu_item_parent.

 // Face item curent $ item-> current = true; $ item-> classes [] = 'curent-meniu-element'; // Obțineți strămoșii pentru elementul de meniu: $ _anc_id = (int) $ item-> db_id; $ Active_ancestor_item_ids = array (); în timp ce ($ _anc_id = get_post_meta ($ _anc_id, '_menu_item_menu_item_parent', true)) &&! in_array ($ _anc_id, $ active_ancestor_item_ids)) $ $ active_ancestor_item_ids [] = $ _anc_id; 

Apoi bifăm prin elementele de meniu și le oferim părinților și strămoșilor elementului "curent" clasele corespunzătoare.

 // Faceți buclă prin elemente și dați strămoșilor și părinților clasa potrivită ($ items as $ key => $ parent_item) $ classes = (array) $ parent_item-> classes; // Dacă elementul de meniu este părinte dacă ($ parent_item-> db_id == $ item-> menu_item_parent) $ classes [] = 'current-menu-parent'; $ elemente [$ cheie] -> current_item_parent = true;  // Dacă elementul de meniu este un strămoș dacă (in_array (intval ($ parent_item-> db_id), $ active_ancestor_item_ids)) $ classes [] = 'actual-menu-strămoș'; Articole $ [$ cheie] -> current_item_ancestor = true;  $ elemente [$ cheie] -> clase = array_unique ($ classes); 

Punerea împreună a acestei funcții:

 funcția publică may_make_current ($ items) foreach ($ items as $ item) if ('post_type_archive'! = $ item-> type) continuați; $ post_type = $ item-> object; dacă (! is_post_type_archive ($ post_type) &&! is_singular ($ post_type)) continuați; // Face item curent $ item-> current = true; $ item-> classes [] = 'curent-meniu-element'; // Obțineți strămoșii pentru elementul de meniu: $ _anc_id = (int) $ item-> db_id; $ Active_ancestor_item_ids = array (); în timp ce ($ _anc_id = get_post_meta ($ _anc_id, '_menu_item_menu_item_parent', true)) &&! in_array ($ _anc_id, $ active_ancestor_item_ids)) $ $ active_ancestor_item_ids [] = $ _anc_id;  // Bucle prin strămoși și să le dea foreach-ul "strămoș" sau "părinte" ($ items as $ key => $ parent_item) $ classes = (array) $ parent_item-> classes; // Dacă elementul de meniu este părinte dacă ($ parent_item-> db_id == $ item-> menu_item_parent) $ classes [] = 'current-menu-parent'; $ elemente [$ cheie] -> current_item_parent = true;  // Dacă elementul de meniu este un strămoș dacă (in_array (intval ($ parent_item-> db_id), $ active_ancestor_item_ids)) $ classes [] = 'actual-menu-strămoș'; Articole $ [$ cheie] -> current_item_ancestor = true;  $ elemente [$ cheie] -> clase = array_unique ($ classes);  returnează articolele $; 

Tot ce rămâne este să accesați pagina de administrare a pluginurilor și să activați pluginul.


Concluzie

Există întotdeauna loc pentru îmbunătățire. De exemplu, cu un pic de jQuery puteți adăuga un link "Selectați toate" sub casetele de selectare sau afișați un simbol "încărcare" în timp ce AJAX procesează. Acum acest plugin nu este cea mai simplă soluție - dar funcționează bine și evită capcanele pur și simplu adăugând o legătură personalizată. Pluginul de mai sus, în întregime, poate fi găsit pe GitHub-ul meu. Dacă aveți comentarii sau sugestii, nu ezitați să lăsați un comentariu sau contactați-mă prin Twitter.

Cod