Dette er del to i en serie som ser på WordPress 'Rewrite API. I del ett tok vi en fløytestoppturnering av grunnleggende om WordPress 'Rewrite API. I denne opplæringen ser vi på omskrivningsinnstillingene som er tilgjengelige for oss når vi registrerer en posttype eller taksonomi. Mens egendefinerte innleggstyper og taksonomier (i motsetning til standardinnlegg, kategorier og koder) ikke drar nytte av noen Innstillinger -> Permalink-grensesnitt, er det fortsatt ganske enkelt å sette opp omskrivninger for egendefinerte typer. Vi vil også bruke metodene som ble introdusert i del ett, så hvis du ikke allerede har anbefalt jeg, leser du WordPress 'Omskrivnings-API del 1: Grunnleggende.
Når du registrerer en egendefinert type, registrerer WordPress også omskrivningsregler (faktisk, ikke helt, og jeg vil forklare hvorfor i delen "Permastructures"). Som nevnt i del 1, vil disse reglene bare bli inkludert når omskrivningsreglene er "spylt". Temaer og plugin-moduler kan tvinge denne "spylingen" ved å ringe flush_rewrite_rules ()
. Dette trenger, og bør bare gjøres en gang ved aktivering og så igjen på deaktivering (for å rydde opp etter deg selv).
Åpenbart, før du spyler omskrivningsreglene, må du ha lagt til dem. Men den i det
krok på hvilke posttyper som skal registreres, har allerede blitt sparket, og når det var, var plugin-modulen din ikke aktiv ennå, og dine posttyper og taksonomier er ikke registrert ennå. For å registrere omskrivningsregler som følger med posttyper og taksonomier, betyr dette at du må "registrere dem manuelt" ved aktivering, før du spyler omskrivningsreglene. Så, dette burde være ditt oppsett:
funksjon wptuts_register_types () // funksjon som registrerer din egendefinerte posttype og taksonomier add_action ('init', 'wptuts_register_types'); funksjon wptuts_plugin_activation () // Registrer typer for å registrere omskrivningsreglene wptuts_register_types (); // Skyll dem deretter flush_rewrite_rules (); register_activation_hook (__FILE__, 'wptuts_plugin_activation'); funksjon wptuts_plugin_deactivation () flush_rewrite_rules (); register_activation_hook (__FILE__, 'wptuts_plugin_activation');
Temaer kan bruke krokene after_switch_theme
for aktivering og switch_theme
for deaktivering.
Når du registrerer en posttype med register_post_type
En av argumentene som er tilgjengelige for deg, er omskrivningsargumentet. Dette bør være en matrise med følgende nøkler:
slug
- en slug som brukes til å identifisere posttypen i nettadresser. Innleggets slug er vedlagt dette for innleggets permalink f.eks. www.example.com/bøker/trollmannen fra Oz
with_front
- sant eller usant. Hvis innleggets permalinkstruktur begynner med en konstant base, for eksempel '/ blog' - dette kan også legges til din tilpassede posttype permalinkstruktur ved å sette den til sann f.eks. sann vil gi www.example.com/blog/books/
og falsk www.example.com/books/
feeds
- sant eller usant. Hvorvidt å generere feedrewrite-regler, f.eks. www.example.com/books/feed/rss
og www.example.com/book/rss
. Standardverdien er verdien av has_archive
.sider
- sant eller usant. Enten å generere regel for "pen" paginering for posttype arkivet f.eks. www.example.com/books/page/2
i stedet for www.example.com/books?page=2
. Standard er ekte.ep_mask
- Dette pleide å være et eget argument: permalink_epmask
. Fra 3.4 vil det flytte til omskrivningsarrayen. Standard er EP_PERMALINK
.'Feeds' og 'Pages' -tastene gjelder bare arkiv siden etter type (som du må ha satt inn has_archive
argument til sant). Fra denne omskriftsserien håndterer WordPress generasjonen av omskrivningsreglene for innleggene dine automatisk. Som et eksempel:
$ labels = array ('name' => __ ('Bøker', 'din-plugins-translation-domain'), // utvalg av etiketter); $ args = array ('labels' => $ etiketter, 'has_archive' => true, 'rewrite' => array ('slug' => 'bøker', 'with_front' => false, 'feed' => 'sider' => sant)); register_post_type ( 'bok', $ args);
Vil gi følgende omskrivningsregler:
trollmannen fra Oz
': www.example.com/books/the-wizard-of-oz
www.example.com/books
(og www.example.com/books/page/2
)www.example.com/books/feed/rss
(og www.example.com/books/rss
)De register_taxonomy ()
funksjonen tilbyr færre alternativer:
slug
- en slug for å identifisere taksonomien f.eks. www.example.com/sjanger/historie
with_front
- Som ovenfor.hierarkisk
- sant eller usant. Hvis satt til sant og taksonomien er hierarkisk, gjenspeiler begrepet permalink hierarkiet. Standard er falsk.ep_mask
- Lagt til i 3.4. Se EP Mask-delen nedenfor.De to første alternativene ligner på ovennevnte. Det hierarkiske alternativet gir termen permalinks samme struktur som sider. For eksempel, la «Historie» være en sjanger og «Militærhistorie» en undergenre. Med hierarkisk sett til falsk, vil "Militærhistorie" ha en permalink:
www.example.com/genre/military-history
Mens satt til sant, vil det ha:
www.example.com/genre/military/military-history
Registrering av en taksonomi registrerer automatisk taksonomi-vilkårene dine: feeds:
www.example.com/genre/military-history/feed
Du kan få feedlink-permalinken til hvilken som helst taksonomi med
$ feed_link = get_term_feed_link ($ term_id, $ taxonomy, $ feed)
Som standard produserer WordPress ikke "fine" permalinks for den egendefinerte innleggstypens år, måned eller dagarkiv (heller ikke forfatterarkivet - men vi forlater det for nå). Samtidig som:
www.example.com/?post_type=book&year=2012&monthnum=05
Riktig gir et arkiv av alle bøker utgitt i mai 2012:
www.example.com/books/2012/05
Vil gi en 404 feil. Vi kan imidlertid bare legge til ekstra omskrivningsregler ved hjelp av tilgjengelige omskrivnings API-metoder vi dekket i del ett. En metode er å legge til følgende liste over omskrivningsregler når du registrerer posttypen din:
// Legg til dagarkiv (og paginering) add_rewrite_rule ("bøker / ([0-9] 4) / ([0-9] 2) / ([0-9] 2) / side /? ([0-9] 1) /?"," index.php? post_type = bok og år = $ kampene [1] & monthnum = $ matcher [2] & dag = $ kampene [3] paged = $ kampene [4] ','topp'); add_rewrite_rule ( "bøker / ([0-9] 4) / ([0-9] 2) / ([0-9] 2) /?", "index.php? post_type = bok og år = $ kampene [1] & monthnum = $ matcher [2] & dag = $ kampene [3]', 'top'); // Legg til månedsarkiv (og paginering) add_rewrite_rule ("bøker / ([0-9] 4) / ([0-9] 2) / side /? ([0-9] 1,) /?",'index.php?post_type=book&year=$matches[1]&monthnum=$matches[2]&paged=$matches[3]','top '); add_rewrite_rule ( "bøker / ([0-9] 4) / ([0-9] 2) /?", "index.php? post_type = bok og år = $ kampene [1] & monthnum = $ matcher [2 ]','topp'); // Legg til årarkiv (og paginering) add_rewrite_rule ("bøker / ([0-9] 4) / side /? ([0-9] 1,) /?", 'Index.php? Post_type = bok og år = $ kampene [1] & paged = $ kampene [2]', 'top'); add_rewrite_rule ( "bøker / ([0-9] 4) /?", 'index.php post_type = bok og år = $ kampene [1]?', 'top');
Dette kan lett bli litt rotete - spesielt når du vurderer at du vil trenge å legge til ekstra regler hvis du vil at arkivene dine skal støtte riktige nettadresser for feeds. Imidlertid illustrerer ovenstående et viktig faktum om å legge til egendefinerte regler: Ordren der reglene legges til er viktig.
Husk at disse reglene legges til omskrivningsarrayen i den rekkefølgen du ringer til add_rewrite_rule
. Når du analyserer en forespørsel, bruker WordPress først matchende regel. Prøv å bytte rekkefølge der år og måned arkivreglene er lagt til. Du finner det www.example.com/books/2012/04/
tar deg til 2012-arkivet. Dette skyldes at nettadressen stemmer overens med mønstrene for både år og måned arkiver, men førstnevnte ble lagt til først. Husk å alltid legge til mer spesifikk regel først.
På den annen side, hvis du legger til en omskrivningsregel, hvis regex allerede eksisterer som regel, skal den regelen overstyres av den nye.
Det er en enkel måte å oppnå det ovenfor: add_permastruct
. Denne funksjonen brukes av WordPress til å lage "permastructures", hvorfra det genererer omskrivningsregler (som ovenfor) som håndterer paginering og feeds. Når du registrerer en egendefinert innleggstype, oppretter WordPress ikke automatisk alle omskrivningsregler. I stedet registrerer det en permastruktur - og bare når reglene blir generert (dvs. når de spyles), bruker WordPress disse permastrukturene til å generere de faktiske omskrivningsregler.
Et eksempel på en permastruktur er den du bruker i Innstillinger -> Permalinks. Disse aksepterer noen "hardkodede" snegler eller noen tagger som eksisterer som standard eller har blitt lagt til add_rewrite_tag
, som vi dekket i del ett. For eksempel, permastrukturen % Year% /% kategori% /% author%
ville generere følgende omskrivningsregler:
www.example.com/2012/url-rewriting/stephen
www.example.com/2012/url-rewriting/stephen/page/2
www.example.com/2012/url-rewriting/stephen/feed/rss
www.example.com/2012/url-rewriting/
www.example.com/2012/url-rewriting/page/2
www.example.com/2012/url-rewriting/feed/rss
www.example.com/2012/
www.example.com/2012/page/2
www.example.com/2012/feed/rss
add_permastruct
FunksjonDe add_permastruct
funksjonen godtar fire argumenter:
Navn
- En unik slug for å identifisere din permastrukturstruct
- Den permastruktur selv, f.eks. '% Year% /% kategori% /% author%
'with_front
- sant eller usant. Dette er det samme argumentet som når du registrerer posttypenep_mask
- Se EP Mask-delen nedenforEt par advarsler om bruk add_permastruct
må gjøres her. Først: du vil sørge for at en tilpasset permastruktur ikke støter sammen med WordPress 'omskrivningsregler for innlegg og sider. Dette kan gjøres ved å forhåndsbehandle din egendefinerte permastruktur med noe hardkodet. For eksempel:
'Noe-hardkodet /% year% /% monthnum% /% dag%'
For det andre - reglene legges til i den rekkefølgen - så hvis kodene dine er for generiske, kan de sistnevnte reglene aldri bli brukt. For eksempel fungerer strukturen ovenfor (som du kan prøve på Innstillinger -> Permalinks-siden), fungerer generelt bra, bortsett fra at:
www.example.com/2012/page/2
Er tolket som siden av innlegg av forfatteren '2', i kategorien 'side' i 2012. Hvis du vil bruke add_permastruct
og har din paginering og feeds regler cascade pent så må du bruke koder som ikke er "generiske" (som jeg mener at regex uttrykkene ikke er generiske). %forfatter%
og %kategori%
er gode eksempler på en generisk tag som disse vil typisk matche ethvert tegn.
Års-, måned- og dagskodene er derimot veldig spesifikke - matcher bare positive tall i lengder fire og to, slik at vi kan bruke add_permastruct
for posttypens dataarkiv. På grunn av datatagsens spesifikke natur trenger vi disse reglene som skal legges til før posten permalink regel - så legg til følgende umiddelbart før Registrering av posttypen din:
// Vær oppmerksom på at dette bare vil fungere på WordPress 3.4+ http://core.trac.wordpress.org/ticket/19871 add_rewrite_tag ('% book_cpt%', '(book) s', 'post_type ='); add_permastruct ('book_archive', '% book_cpt% /% år% /% monthnum% /% day%');
I det ovennevnte er den egendefinerte taggen % Book_cpt%
fungerer som en hardkodd slug for å skille denne permastrukturen fra andre regler (som ved første advarsel). De genererte reglene gjelder bare hvis % Book_cpt%
matcher "bøker", og i så fall blir bokdelen tatt og tolket som verdien for post_type
. Vær oppmerksom på at add_rewrite_tag
aksepterer bare det tredje argumentet siden WordPress 3.4. Du kan imidlertid bruke følgende arbeidsplass:
global $ wp_rewrite; $ Wp_rewrite-> add_rewrite_tag ( '% book_cpt%', '(bok) s', 'post_type =');
Etter å ha satt opp arkivene, kan du også forvente det
www.example.com/books?year=2012
Ville ta oss til 2012 bokarkivet også. Testing det viser imidlertid at i stedet tar det oss til arkiv siden etter innlegg:
www.example.com/2012/
WordPress har omdirigert oss til en annen side på grunn av noe kjent som canonicalization.
Vanligvis er det mange nettadresser som kan peke på det samme innholdet på nettstedet ditt. For eksempel:
www.example.com/year/2012 www.example.com/year/2012/page/1 www.example.com/2012/////////page/1 www.example.com/index.php / 2012 / www.example.com/index.php////2012///page/1
Vil alt ta deg til den første siden av 2012-arkivet ditt. Fra et SEO-perspektiv er dette ikke bra - vi kan ikke anta at søkemotorer vil gjenkjenne disse nettadressene som samme ressurs, og disse nettadressene kan ende opp med å konkurrere mot hverandre. Google kan også aktivt straffe deg for duplikat innhold, og mens det er bra å bestemme når denne dupliseringen ikke er "ondsinnet", anbefaler den fortsatt å omdirigere disse overflødige nettadressene til en foretrukket "kanonisk" (eller standard) nettadresse. Dette kalles kanonise.
Å gjøre det hjelper ikke bare å konsolidere karakterer som link popularitet, men hjelper også brukerne. Hvis de bruker en stygg eller «feil» nettadresse, blir de tatt til den riktige URL-adressen, og det som er i adresselinjen, er det de sannsynligvis vil returnere til.
Siden 2.1.0 har WordPress håndtert kanonisk omdirigering, selv tar en utdannet gjetning på etterspurt innhold hvis den opprinnelige spørringen returnerte en 404. Dessverre, i dette tilfellet, blir WordPress omdirigert til feil URL. Dette skyldes at nettadressen vi egentlig vil ha, ikke er forstått av WordPress, og den har ignorert delen "posttype" av nettadressen. Heldigvis, men vi kan bruke redirect_canonical
filter for å fikse dette.
add_filter ('redirect_canonical', 'wptuts_redirect_canonical', 10, 2); funksjon wptuts_redirect_canonical ($ redirect_url, $ requested_url) global $ wp_rewrite; // Avbryt hvis ikke bruk ganske permalinks, er en feed, eller ikke et arkiv for posttypen 'bok' hvis (! $ Wp_rewrite-> using_permalinks () || is_feed () ||! Is_post_type_archive ('bok')) returnere $ REDIRECT_URL; // Få de opprinnelige søkedelene $ redirect = @parse_url ($ requested_url); $ original = $ redirect_url; hvis (! isset ($ omdirigere ['spørring'])) $ omdirigering ['query'] = "; // Hvis er år / måned / dag - legg til år hvis (is_year () || er_month () || er_dag $) = $ redirect_url = user_trailingslashit (get_post_type_archive_link ('bok')). $ $ = $ omdirigering ['query'] = remove_query_arg ('år' år; // Hvis er måned / dag - legg til måned hvis (is_month () || er_day ()) $ month = nullise (intval (get_query_var ('monthnum')), 2); $ omdirigere ['query'] = remove_query_arg ('monthnum', $ omdirigere ['query']); $ redirect_url. = '/'.$month; // Hvis er dag - legg til dag hvis (is_day ()) $ day = nullise (intval get_query_var ('day')), 2), $ omdirigere ['query'] = remove_query_arg ('dag', $ omdirigere ['spørring']); $ redirect_url. = '/'.$day; // , append pagination hvis (get_query_var ('paged')> 0) $ paged = (int) get_query_var ('paged'); $ omdirigere ['query'] = remove_query_arg ('paged', $ redirect ['query']) ; hvis ($ paged> 1) $ redirect_url. = user_trailingslashit ("/ side / $ paged", 'paged'); hvis ($ redirect_url == $ original) returnerer $ original; // takk på eventuelle ytterligere spørringer vars $ redirect ['query'] = preg_replace ('# ^ \ ?? & *? #', ", $ omdirigere ['query']), hvis ($ redirect_url &&! empty omdirigere ['query'])) parse_str ($ omdirigere ['query'], $ _parsed_query); $ _parsed_query = array_map ('rawurlencode', $ _parsed_query); $ redirect_url = add_query_arg ($ _parsed_query, $ redirect_url); returnere $ redirect_url;
Ovennevnte funksjon er lang, men ikke veldig komplisert. Det kan forbedres på, og er bare ment som et eksempel på hva du kan gjøre med redirect_canonical
filter. Det kontrollerer først at det er ganske permalinks på, at vi er etter vårt "bok" arkiv, og det er ikke en feed. Det sjekker da igjen:
www.example.com/books/[year]
www.example.com/books/[year]/[monthnum]
www.example.com/books/[year]/[monthnum]/[day]
En annen funksjon som ikke støttes for posttyper eller taksonomier "ute av boksen", er å bruke koder i permalinkstrukturen. Mens tagger som brukes i "slug" i en skrivetype (eller taksonomi) omskrivningsarray, er korrekt tolket, erstatter WordPress ikke disse kodene med de riktige verdiene når de genererer permalinkene. Vi må erstatte det selv. Men ved hjelp av koder som dette bryter også posttypens arkivside - så vi bruker en annen metode. Som et eksempel, la oss anta at vi vil ha vår egendefinerte innleggstype 'bok' for å ha strukturen:
www.example.com/books/[some-genre]/[a-book]
Jeg bruker eksemplet på en egendefinert taksonomi, men de samme metodene kan brukes til enhver permastruktur (for eksempel med dato, forfatter eller til og med et egendefinert felt). Først av alt legger vi til omskrivningsregelen:
funksjon wptuts_custom_tags () add_rewrite_rule ("^ bøker / ([^ /] +) / ([^ /] +) /?", 'index.php? post_type = bok & sjanger = $ kamper [1] & bok = $ kamper [2 ]','topp'); add_action ('init', 'wptuts_custom_tags');
Nå, www.example.com/book/fiction/the-wizard-of-oz
, for eksempel peker på boken 'trollmannen fra Oz
'. Men permalinken generert av WordPress produserer fortsatt www.example.com/book/the-wizard-of-oz
. Det neste trinnet er å endre den produserte permalinken.
Vi gjorde noe lignende i del ett da vi ønsket å bruke en egendefinert kode i post-permalinkstrukturen. Så brukte vi POST_LINK
filter; denne gangen bruker vi ekvivalenten for egendefinerte innleggstyper, den post_type_link
filter. Ved hjelp av denne kroken kan vi injisere strukturen i bøkerens permalinks.
funksjon wptuts_book_link ($ post_link, $ id = 0) $ post = get_post ($ id); hvis (is_wp_error ($ post) || 'book'! = $ post-> post_type || tomt ($ post-> postnavn) returnere $ post_link; // Få sjangeren: $ terms = get_the_terms ($ post-> ID, 'genre'); hvis (is_wp_error ($ terms) ||! $ vilkår) $ genre = 'uncategorized'; ellers $ genre_obj = array_pop ($ termer); $ genre = $ genre_obj-> slug; returner home_url (user_trailingslashit ("bøker / $ sjanger / $ post-> postnavn")); add_filter ('post_type_link', 'wptuts_book_link', 10, 2);
La oss utvide ovenstående permalinkstruktur for å oppnå følgende:
www.example.com/books/[some-genre]/[a-book]
www.example.com/books/[some-genre]
www.example.com/books/
Husk at rekkefølgen der omskrivningsregler legges til sak. Spesielt legger du til regler som først prioriteres.
Så først registrerer vi vår egendefinerte taksonomi 'sjanger' med:
$ args = array (... 'rewrite' => array ('slug' => 'bøker'), ...) register_taxonomy ('genre', $ args);
Dette legger til følgende permastruktur:
www.example.com/books/[some-genre]
Etter å ha registrert taksonomien registrerer vi deretter vår tilpassede posttype som følger:
$ args = array (... 'rewrite' => array ('slug' => 'bøker'), ...) register_post_type ('bok', $ args);
Dette ville registrere følgende regler:
www.example.com/books/
(som vi vil)www.example.com/books/[a-book]
(som vi ikke gjør)Men den andre konflikten med (og er "slått" av) den konkurrerende regelen lagt til da vi registrerte vår taksonomi. Den resulterende strukturen er:
www.example.com/books/fiction/slug
www.example.com/books/slug
www.example.com/books/
Tidligere da vi så på registrering av posttyper, takker taksonomier (eller på annen måte), gir WordPress oss en egen "ep_mask
'. Så hva er de?
I første del så vi på hvordan vi kan legge til endepunkter med add_rewrite_endpoint
. Det andre argumentet i den funksjonen er en konstant (eller kombinasjon av konstanter som bruker bitvise operatorer), som bestemmer hvor sluttpunktet er lagt til. For eksempel:
add_rewrite_endpoint ('form', EP_PAGES);
Legger til omskrivningen form (/(.*))?/?$
til hver side permalink og:
add_rewrite_endpoint ('json', EP_PAGES | EP_PERMALINKS);
Legger til omskrivningen json (/(.*))?/?$
til alle innlegg og sidelink. Så spesifiserer disse konstantene et "sted" (dvs. "på slutten av en post-permalink") og de kalles endepunktsmasker (eller ep masker).
Når du registrerer en posttype, registrerer WordPress en permastruktur - og tilknyttet den en endepunktsmaske. Da når omskrivningsreglene blir generert, legger det også til eventuelle endpoint-omskrivningsregler som er lagt til den endepunktsmasken.
For eksempel, når WordPress registrerer standard 'Side' innleggstype - tilknyttes det endepunktsmasken EP_PAGES
med siden permastrukturen. Deretter ble eventuelle endpoint-omskrivningsregler lagt til i EP_PAGES
er faktisk lagt til siden permastructure. Når du registrerer en posttype, kan du angi din egen endepunktsmaske, eller bruke en eksisterende. Som standard er det EP_PERMALINKS
- noe som betyr at alle endpoint rewrite regler som er lagt til EP_PERMALINKS
blir lagt til i reglene for tilpasset innleggstype.
Selvfølgelig kan det hende du ikke vil ha endepunktsregler lagt til posttypen din (i så fall kan du bruke endepunktsmasken EP_NONE
), eller du vil kanskje legge til noen endpoint omskrivningsregler bare til din egendefinerte innleggstype. For å gjøre dette må du først opprette en endepunktsmaske, noe som ikke er mer enn en konstant som tilfredsstiller:
Kraften til 2 krav er nødvendig fordi WordPress bruker binær logikk for å bestemme hvor sluttpunktsreglene skal legges til. Dessverre er dette nesten umulig å sjekke, så det beste rådet er å legge til endepunktsmasker bare når det er nødvendig og gi det en veldig høy verdi (for eksempel 221). På tidspunktet for skriving 20 opptil 21. 3 brukes av Core.
Definer endepunktsmasken din før du registrerer din posttype eller taksonomi:
definere ('EP_BOOK', 8388608); // 8388608 = 2 ^ 23 $ args = array ('labels' => $ etiketter, 'has_archive' => sant, 'rewrite' => array ('slug' => 'bøker' with_front '=> false' feed ' => true 'pages' => true 'ep_mask' => EP_BOOK)); register_post_type ('bok', $ args); // Så kan du endpoint omskrivningsregler til denne endepunktsmasken add_rewrite_endpoint ('lån', EP_BOOK);
(Merk: Ovenstående bruker WordPress 3.4-argumenter. Hvis du bruker en eldre versjon av WordPress, må du bruke den nå utsatte permalink_epmask
.). Som i WordPress 3.4 kan du spesifisere en endepunktsmaske når du registrerer en taksonomi også.
I denne opplæringen har jeg dekket grunnleggende om omskrivnings-API for posttyper og taksonomier, men også noen mer avanserte emner. WordPress 'håndtering av omskrivninger er (nødvendigvis) komplisert, og den beste måten å forstå det på er å dykke inn i kildekoden og teste den ut ved å bruke det du har lært og en omskrivningsanalysator plugin.
Det er et par billetter som jobber seg gjennom WordPress-utviklingen Trac for øyeblikket, knyttet til Rewrite API. I fremtiden ser vi en mye lettere og konfliktfri måte å levere endepunktsmasker på.