Anpassade omskrivningsregler och sidmallar i WordPress
WordPress Rewrite API är ett solidt API förutsatt att du är bekväm med reguljära uttryck.
Och ärligt talat, även om du inte är det, så gör verktyg som PHP Live RegEx det väldigt enkelt att testa din kod innan du släpper den i add_rewrite_ruleAPI-anropet.
Det finns dock tillfällen då du kan hamna i en situation där du behöver arbeta med omskrivningsregler och sidmallar. Och när så är fallet är det inte alltid lika enkelt som att ringa ett enkelt samtal med ett enda reguljärt uttryck.
Anledningen? Om du har flera sidor som använder samma mall, kommer du inte alltid att ha sidan placerad i samma index i frågan som körs på varje sida.
För det ändamålet måste vi hantera det på ett lite annorlunda sätt än att till exempel bara komma åt ett numeriskt index med information i den globala frågan.
Skriv om regler och sidmallar
Låt oss först anta att vi har två mallar (som inte är i någon speciell ordning):
- mall-alpha.php
- mall-beta.php
Och låt oss sedan säga att vi vill skapa en anpassad URL för sidor som var och en använder en av dessa mallar.
Detta skulle delas upp i följande steg:
- Iterera genom inläggen i frågan,
- Lagra inlägget med mallen i dess respektive array,
- Ställ in omskrivningsreglerna för varje inlägg som har en given fråga.
För det här exemplet kommer jag att hålla omskrivningsreglerna ganska enkla. När allt kommer omkring kan reguljära uttryck vara tillräckligt svåra att följa, så att försöka följa dem när du hanterar frågeobjektet, flera arrayer och hantera reglerna kan vara lite mycket.
Med det sagt, här är exempelkoden som är uppdelad baserat på stegen ovan. I slutet av inlägget kommer jag att dela ett utdrag som samlar allt i några separata funktioner så att du kan se hur allt detta hänger ihop.
Med det sagt, så här hanterar du allt ovanstående.
1 Lägga till omskrivningsregler
Först måste vi läsa lite information från det globala WordPress-frågeobjektet för att hitta alla sidor som har mallar applicerade på dem.
För att göra detta kan vi läsa informationen från det globala frågeobjektet till en lokal variabel. Detta gör det enkelt att undvika resten av koden om det inte finns något att arbeta med.
<?php
$query = $this->query->query([
'post_type' => 'page',
'meta_key' => '_wp_page_template',
'meta_value' => ['template-alpha.php', 'template-beta.php'],
]);
if (!$query) {
return;
}
// More to come...
2 Lagra relevant information i en array
Om vi antar att det finns sidor med mallar, fortsätter vi med att lagra var och en av sidorna i arrayer så att vi enkelt kan hantera deras respektive omskrivningsregler.
<?php
foreach ($query as $post) {
$slug = get_page_template_slug($post->ID);
if ('template-alpha.php' === $slug) {
$this->alphaPages[] = $post;
}
if ('template-find-a-camp.php' === $slug) {
$this->betaPages[] = $post;
}
}
Observera att i ovanstående refererar jag till en global array. Antag att detta helt enkelt initieras som en tom array i klassens konstruktor.
3 Ställ in omskrivningsreglerna
Nu när vi har två arrayer – en för varje mall och sidorna som innehåller den – kan vi iterera igenom dem och tilldela omskrivningsregler för var och en av dessa sidor.
Låt oss till exempel säga att för en mall, säg alfa, vill vi ställa in omskrivningsregler för USA och stater.
Här är koden förtemplate-alpha.php:
<?php
add_rewrite_tag('%country%', '([^&]+)');
add_rewrite_tag('%state%', '([^&]+)');
foreach ($this->alphaPages as $post) {
add_rewrite_rule(
'^'.$post->post_name.'/([^/]*)/([^/]*)/?',
'index.php?page_id='.$post->ID.'&country=$matches[1]&state=$matches[2]',
'top'
);
add_rewrite_rule(
'^'.$post->post_name.'/([^/]*)/?',
'index.php?page_id='.$post->ID.'&country=$matches[1]',
'top'
);
}
Och här är koden för template-beta.php:
<?php
add_rewrite_tag('%acme-id%', '([^&]+)');
foreach ($this->betaPages as $post) {
add_rewrite_rule(
'^(.*)?/([A-Za-z0-9-]+-)(d+)/?',
'index.php?page_id='.$post->ID.'&acme-id=$matches[3]',
'top'
);
}
Naturligtvis är de reguljära uttrycken som används i koden ovan endast för demonstrationsändamål. Din kommer att vara för allt som behövs för ditt projekt.
4 Alla tillsammans nu
Det är viktigt att dela upp all denna funktionalitet i sina egna metoder så att allt enkelt kan kapslas in och testas vid behov.
För detta ändamål, så här kommer den fullständiga koden att se ut:
<?php
public function addRewriteRules()
{
$query = $this->query->query([
'post_type' => 'page',
'meta_key' => '_wp_page_template',
'meta_value' => ['template-alpha.php', 'template-beta.php'],
]);
if (!$query) {
return;
}
$this->setPageTypes($query);
$this->setAlphaRewriteRules();
$this->setBetaRewriteRules();
}
private function setPageTypes($query)
{
foreach ($query as $post) {
$slug = get_page_template_slug($post->ID);
if ('template-alpha.php' === $slug) {
$this->alphaPages[] = $post;
}
if ('template-find-a-camp.php' === $slug) {
$this->betaPages[] = $post;
}
}
}
private function setAlphaRewriteRules()
{
add_rewrite_tag('%country%', '([^&]+)');
add_rewrite_tag('%state%', '([^&]+)');
foreach ($this->alphaRules as $post) {
add_rewrite_rule(
'^'.$post->post_name.'/([^/]*)/([^/]*)/?',
'index.php?page_id='.$post->ID.'&country=$matches[1]&state=$matches[2]',
'top'
);
add_rewrite_rule(
'^'.$post->post_name.'/([^/]*)/?',
'index.php?page_id='.$post->ID.'&country=$matches[1]',
'top'
);
}
}
private function setBetaRewriteRules()
{
add_rewrite_tag('%acme-id%', '([^&]+)');
foreach ($this->betaPages as $post) {
add_rewrite_rule(
'^(.*)?/([A-Za-z0-9-]+-)(d+)/?',
'index.php?page_id='.$post->ID.'&acme-id=$matches[3]',
'top'
);
}
}
Kom dock ihåg; detta är bara baserat på demokoden som delas i det här inlägget. När du arbetar med ditt projekt kommer de reguljära uttrycken, mallarna och så vidare att variera.
