Brauchen Sie Hilfe mit add_rewrite_rule

55

LÖSUNG


Ich bin mit Update 3 gegangen und habe es zum Laufen gebracht. Was ich falsch verstanden hatte, war , dass ich glaubte , dass eine Rewrite - Regel ändern würde designers/?designer=some-designer&bid=9zu /designers/some-designer. Aber es ist natürlich umgekehrt.


Ich habe einige Nachforschungen angestellt, aber ich verstehe nicht ganz, wie man add_rewrite_rule () benutzt .

Dieser Beitrag ist ziemlich nah an dem, was ich brauche, aber brauche ich wirklich so viel Code?

Mein aktueller Link ist dieser:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Was ich möchte, ist dieser
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Wie verwende ich add_rewrite_rule()?
  2. Ich muss die Designer-ID (Gebot) übergeben. Wie kann ich das tun, wenn ich Regeln zum erneuten Schreiben verwende, ohne dass sie in der URL angezeigt werden?

Update 1

Ich fand das etwas erklärender. Aber es funktioniert nicht:

function add_rewrite_rules( $wp_rewrite ) 
{
    $new_rules = array(
        '('.$template_page_name.')/designers/(.*?)/?([0-9]{1,})/?$' => 'designers.php?designer='.
        $wp_rewrite->preg_index(1).'&bid='.
        $wp_rewrite->preg_index(2)
    );
       // Always add your rules to the top, to make sure your rules have priority
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');

function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}
add_filter('query_vars', 'query_vars')

Update 2

Hier ist eine andere Lösung, die Jan Fabry in einem anderen Thread vorgeschlagen hat. Ich habe dies in meine functions.php eingefügt, aber es hat keine Auswirkung.

add_action('generate_rewrite_rules', 'add_rewrite_rules');
add_filter('query_vars', 'query_vars');

/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function add_rewrite_rules( $wp_rewrite ) 
{
    add_rewrite_rule('^designers/([^/]*)/([^/]*)$ /designers/?designer=$1&bid=$2 [L]', 'top');
    flush_rewrite_rules(false);
}


function query_vars($public_query_vars) {

    $public_query_vars[] = "designer";
    $public_query_vars[] = "bid";
    return $public_query_vars;
}

Update 3 Auch hier habe
ich einige Beispiele gefunden . Aber das funktioniert auch nicht :(

add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');  

// Remember to flush_rules() when adding rules
function flushRules(){
    global $wp_rewrite;
    $wp_rewrite->flush_rules();
}

// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
    $newrules = array();
    $newrules['(designers)/(\d*)$'] = 'index.php?pagename=designers&designer=$matches[1]';
    return $newrules + $rules;
}

// Adding the bid var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
    array_push($vars, 'designer');
    return $vars;
}

Update 4 Ich habe diese Lösung auch ausprobiert, aber immer noch keinen Erfolg.

add_filter('search_rewrite_rules', 'designers_createRewriteRules');

function designers_createRewriteRules($rewrite) {
global $wp_rewrite;

// add rewrite tokens
$designer_token = '%designers%';
$wp_rewrite->add_rewrite_tag($designer_token, '(.+)', 'designers=');

$bid_token = '%bid%';
$wp_rewrite->add_rewrite_tag($bid_token, '(.+)', 'bid=');

$keywords_structure = $wp_rewrite->root . "designers/$designer_token/$bid_token";
$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);

return ( $rewrite + $keywords_rewrite );

}

Update 5
Es scheint, dass meine Umschreiberegeln nicht hinzugefügt wurden. Das Ausführen der folgenden nachträglichen neuen Regeln:, print_r($wp_rewrite)schließt meine neuen Umschreibregeln nicht ein.

Update 6
Ich habe Jan's Lösung getestet. Aber die URL ändert sich nicht :(

/* Initiation script for NF template
------------------------------------------------------------------------------*/   
add_action('after_setup_theme','norwegianfashion_setup');

if ( ! function_exists( 'norwegianfashion_setup' ) ):

  function norwegianfashion_setup() { 
    /* Here I do a lot of stuff */

    // SEO friendly URL for desigenrs
    add_action( 'init', 'wpa5413_init' );
    add_filter( 'query_vars', 'wpa5413_query_vars' );
  }

endif;


/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        'designers/([^/]+)/?',
        'index.php?pagename=designers&designer=$matches[1]',
        'top' );
}

function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer';
    return $query_vars;
}

Ich würde mich sehr freuen, wenn mir jemand bei der Lösung dieses Problems helfen könnte.

Steven
quelle
Dies ähnelt der ersten Frage, die Sie hier gestellt haben und auf die ich eine Antwort gegeben habe . Hat sich die Situation seitdem geändert, sodass meine Antwort nicht mehr gültig ist? Wenn Sie die Designer-ID nicht in Ihrer URL haben möchten, müssen Sie den "Slug" selbst in die ID konvertieren. WordPress kann dies nicht für Sie tun. Sind Designer noch ein externes Objekt?
Jan Fabry
@Jan Fabry Ja, ich habe das entdeckt, nachdem ich das gepostet habe (ich hatte es vergessen). Jetzt verstehe ich Ihren Vorschlag besser. Sehen Sie meinen aktualisierten Code hier. Meine Designer sind noch Einträge in einer benutzerdefinierten Datenbank. Ist es möglich, POST-Insteed und GET zu verwenden, um die Daten weiterzuleiten bid?
Steven
Die Verwendung einer POST-Anfrage funktioniert nicht, wenn ich den Link kopiere und an eine andere Person sende. Ist es ein Problem, den Slug eindeutig zu machen und die Daten von dort aus zu suchen?
Jan Fabry
@ Jan Fabry: Was meinst du damit slug? `Designer Das Abrufen von Daten ist viel einfacher , mit bidnichtdesigner
Steven

Antworten:

87

Einige Hintergrundinformationen zu Umschreiberegeln

Das WP Rewrite-System sieht kompliziert aus, aber tatsächlich ist es nicht so schwer zu verstehen, wie es funktioniert. Es wird verwendet, um hübsche URLs ( /designers/) so zu analysieren, als wären sie nicht hübsch ( /index.php?pagename=designers). Die Grundidee ist, dass Sie eine Liste von Umschreibregeln und regulären Ausdrücken haben, die mit den eingehenden URLs übereinstimmen können, und diese in andere URLs umschreiben, meist in Form index.phpeiniger Abfragevariablen. Diese Variablen werden auf Teile des regulären Ausdrucks festgelegt, die mit der URL übereinstimmen. Die Regeln werden von oben nach unten ausgewertet. Wenn also zwei Regeln übereinstimmen, gewinnt die erste.

Diese Umschreiberegeln werden durch Aufrufen in der Datenbank gespeichert. flush_rewrite_rules()Da das Generieren und Schreiben dieser Regeln jedoch eine kostspielige Operation ist, sollten Sie dies nicht bei jedem Vorgang tun init. Stattdessen tun Sie dies nur, wenn Sie die Regeln ändern: Wahrscheinlich bei der Aktivierung des Plugins (mithilfe von register_activation_hook()) oder manuell über die Seite mit den Einstellungen für Permalinks ( da dies bei der Aktivierung des Themas nur schwer automatisch möglich ist ). Wenn Sie die Regeln nicht löschen, hat der Aufruf add_rewrite_rule()keine Auswirkung. Es ist kein Problem, add_rewrite_rule()jeden anzurufen init, auch nachdem Sie die Regeln gelöscht haben.

Es gibt viele Möglichkeiten, um Ihre Umschreiberegeln hinzuzufügen, und wenn Sie nur eine Regel hinzufügen möchten, können Sie dies mit tun add_rewrite_rule(). Da die Regeln für Posts, Seiten, Taxonomien usw. zu mehreren Regeln führen, werden sie mit Funktionen auf hoher Ebene erstellt add_rewrite_tag(), add_permastruct()z.

Es gibt auch einige Filter, sodass Sie Ihre Regeln auch mit den Haken generate_rewrite_rulesoder hinzufügen können generate_rewrite_rules_array. Diese geben Ihnen eine sehr detaillierte Kontrolle über die gesamten Regeln, aber auch hier add_rewrite_rule()ist es ausreichend, wenn Sie nur eine Regel hinzufügen möchten.

Ich habe ein kleines Plugin erstellt, mit dem Sie die aktuellen Umschreiberegeln analysieren können , und (natürlich) ich empfehle, es zu verwenden, wenn Sie versuchen, etwas zu ändern.

Zusätzliche Informationen erhalten Sie über die URL

Bauen wir auf dem Beispiel auf, das Sie gegeben haben. Sie haben die Designermarke Batlak og Selvigmit der numerischen ID ( bid) 9. Sie möchten nicht diese ID in der URL, sondern nur den Namen. Wir nennen die URL-Version des Namens (ohne Leerzeichen oder Sonderzeichen) der Schnecke : Batlak-og-Selvig.

Im Allgemeinen sollte die URL alle Informationen enthalten, um den Inhalt zu identifizieren, den Sie auf der Seite anzeigen möchten. Sie können Cookies oder POST-Anfragen verwenden, um die tatsächliche Designer-ID zu speichern, die Sie anzeigen möchten. Dies wird jedoch unterbrochen, wenn jemand den Link teilt, indem Sie ihn per E-Mail, Facebook, Twitter oder einfach per Telefon vorlesen. Wenn Sie die numerische ID nicht in Ihrer URL verwenden möchten, sollten Sie sicherstellen, dass der Slug eindeutig ist. Führen Sie dann zunächst eine Suche nach der ID basierend auf dem Slug durch und fahren Sie wie zuvor fort.

Was wir jetzt gelernt haben, ist, dass wir eine Umschreiberegel für das Muster " /designers/gefolgt von irgendetwas bis zum nächsten /" hinzufügen und dieses "irgendetwas" in der designer_slugAbfragevariablen speichern möchten . In Ihrem Fall, glaube ich, möchten Sie auch die Seite mit dem Slug designersals allgemeinen Seiteninhalt verwenden, also werden wir dies auch WordPress mitteilen.

add_action( 'init', 'wpa5413_init' );
function wpa5413_init()
{
    // Remember to flush the rules once manually after you added this code!
    add_rewrite_rule(
        // The regex to match the incoming URL
        'designers/([^/]+)/?',
        // The resulting internal URL: `index.php` because we still use WordPress
        // `pagename` because we use this WordPress page
        // `designer_slug` because we assign the first captured regex part to this variable
        'index.php?pagename=designers&designer_slug=$matches[1]',
        // This is a rather specific URL, so we add it to the top of the list
        // Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
        'top' );
}

Sie müssen WordPress lediglich anweisen, auch die designer_slugin der Abfrage enthaltenen Variablen beizubehalten, damit Sie später darauf zugreifen können. WordPress verwendet eine Whitelist mit zulässigen Abfragevariablen, um zu verhindern, dass Benutzer jeden Parameter der Posts-Abfrage über die URL ändern. Alles, was nicht auf dieser Liste steht, wird ignoriert. Haken Sie einfach in den query_varsHaken ein und fügen Sie Ihre zusätzliche Variable hinzu:

add_filter( 'query_vars', 'wpa5413_query_vars' );
function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer_slug';
    return $query_vars;
}

Wie Sie sehen können, ist diese Antwort im Grunde die gleiche wie meine vorherige Antwort , jedoch ohne das Löschen der Regeln im Code (sodass Sie sie in Ihrem Theme functions.phpanstelle eines Plugins verwenden können) und mit etwas mehr Sicherheit und Erklärung, weil ich gelernt habe Viel über das Umschreiben von Regeln seit (und wegen) der Beantwortung Ihrer ersten Frage.

Chat-Raum Diskussion

Wir haben die letzten Fragen zu dieser Frage im Chatraum geklärt . Am Ende benutzte Steven den generate_rewrite_rulesHaken, weil die add_rewrite_rule()Funktion für ihn nicht zu funktionieren schien.

Jan Fabry
quelle
2
@Steven: pagenameist der Slug der WordPress-Seite, die Sie anzeigen möchten ( Eintrag in der Datenbank). Auf dieser Seite kann dann angegeben werden, dass die designers.phpVorlagendatei im WP-Administrationsbereich verwendet werden soll. Sie verweisen also auf die Seite und nicht auf den Vorlagennamen, da dieselbe Vorlage für mehrere Seiten verwendet werden kann: In diesem Fall weiß WordPress nicht, was Sie tun möchten.
Jan Fabry
1
@Steven: Ich denke, Sie machen die Einrichtung der Haken zu kompliziert. Entfernen Sie die add_rewrite_rules()Funktion und rufen Sie add_filter()/add_action()direkt an. Wenn es sich um eine Designdatei handelt, entfernen Sie die flush_rewrite_rules()und besuchen Sie einfach die Seite mit den Einstellungen für Permalinks, um die Regeln zu löschen (oder fügen Sie sie hinzu wpse5413_init()und entfernen Sie sie später). Und mein Plugin zeigt die aktuellen Umschreiberegeln an. Denken Sie daran, dass dies nur die Art und Weise ändert, wie eingehende URLs behandelt werden, und nicht, wie Ihr Code die URLs in HTML schreibt.
Jan Fabry
1
@Steven: Ich glaube nicht, dass du den Speichern-Button drücken musst, nur das Öffnen der Permalinks-Seite wird es auch leeren. Und wieder wird dies nur die Fähigkeit für WordPress hinzufügen, /designers/designer-slug/URLs zu akzeptieren . Sie müssen die Stellen ändern, an denen Sie diese URLs in Ihrem HTML selbst schreiben. Testen Sie es, indem Sie /designers/Batlak-og-Selvig/selbst entscheiden, ob dies funktioniert. Suchen Sie alle Stellen, an denen diese URLs generiert werden, und ändern Sie sie, um die neue Struktur zu verwenden.
Jan Fabry
1
Ah, jetzt denke ich, dass ich anfange zu verstehen. Ich dachte, dass die Umschreiberegeln die Anzeige der URL im URL-Feld des Browsers ändern würden. Aber was bedeutet ist, dass ich die URL tatsächlich ausgeben muss www.mysite.com/batlat-og-selvig/9und diese dann "übersetzt" wird/?designer=Batlak-og-Selvig&bid=9
Steven
1
@Steven: Ja, in der Tat: Die Umschreiberegeln behandeln eingehende Links und wirken sich (nur in einigen ausgewählten Fällen) nicht auf die generierten Links in Ihrem Code aus.
Jan Fabry