Katalogrouting für Magento EE 1.13

7

UPDATE Im
Folgenden finden Sie die ursprüngliche Frage, die sich zwar auf das Problem bezieht, aber tangential ist. Weitere nützliche Hintergrundinformationen finden Sie in den Änderungen, die mit Nummer 2 beginnen

Auf unserer Website finden Sie einige CMS-Seiten, auf denen die Korrelation zwischen zwei verschiedenen Kategorien erläutert wird. Daher ähneln die URLs in der Regel den URLs der Katalogseiten.

  • Ein Beispiel für eine CMS-URL:
    • "brand / category.html"
  • Die Kategorie, die übereinstimmt:
    • "Kategorie"

Gibt es in Magento eine Einstellung, die eine strengere Übereinstimmung der Kategorie-Routen erzwingt?

EDIT: Ich sollte beachten, obwohl es offensichtlich ist: Dies sind nur Beispielnamen

BEARBEITEN 2: Wenn es hilfreich ist, haben alle Katalogseiten URLs relativ zu root (website.com/subcat), wobei subcat ein Kind einer anderen Kategorie ist. Dieses Verhalten unterscheidet sich von der Standardeinstellung in anderen Magento-Installationen. (Hinweis: Dies wird nicht bevorzugt und es ist unklar, warum dies geschieht.)

EDIT 3: Nach mehr Graben fand ich ein Zitat aus einem Artikel von Fabrizio Branca über URL-Schlüssel in 1.13:

Vor 1.13 / 1.8 wurde jede CMS-Seite mit einem URL-Schlüssel, der auch als Kategorie- oder Produkt-URL-Schlüssel verwendet wurde, zuerst ausgewertet. Auf diese Weise können Sie die Hauptkategorien leicht durch cms-Zielseiten ersetzen. Das hat sich jetzt geändert. Obwohl der CMS-Controller zuerst verarbeitet wird, werden die Produkt- und Kategorie-URLs vor Beginn des Routing-Prozesses ausgewertet, was die Anzeige von CMS-Inhalten auf saubere Weise erheblich erschwert.

EDIT 4: Ergebnis weiterer Forschung:

  • "legitime Kategorie" existiert und ist standardmäßig unter zugänglich /a
  • "legitime andere Kategorie" existiert ebenfalls und ist bei b
  • Unabhängig von der Beziehung zwischen diesen beiden Kategorien kann auf beide mit dem anderen als übergeordnetem Element zugegriffen werden ( a/bfunktioniert einwandfrei b/a).
    • Beachten Sie, dass a/bProdukte von b und b/aProdukte von a zeigt
  • Allerdings , b/bfunktioniert nicht, noch tutnon-existant-category/a

Was ich suche, ist eine URL-Struktur ähnlich den vorherigen Magento-Versionen (IE category/subcategory), ohne die Vorteile der Hintergrundindizierung zu verlieren, die 1.13 bietet.

mpw
quelle
Ich denke, Sie müssen etwas genauer erklären, ob es in Magento eine Einstellung gibt, mit der die Routenübereinstimmung für Kategorien strenger gestaltet werden kann.
Benmarks
Nun, klar, Magento macht Annahmen, indem es die Anfrage website.com/brand/category.htmlan die Route anpasst website.com/category. Meine Frage ist, wie ich das nicht erreichen kann.
mpw
Es gibt keine native programmatische Verbindung zwischen URLs der SEF-Kategorie und CMS-Seiten-URLs.
Benmarks
Ich weiß es zu schätzen, dass Sie bei mir bleiben, aber ich bin mir nicht sicher, wie ich diesen Kommentar verwenden soll, um eine Lösung zu finden.
mpw
Sie fragen nach einer Einstellung für "Strenge" für Kategorie-URLs und geben einen Kontext für diese Frage mit CMS-Seiten an. In Magento gibt es keine solche native Verbindung, daher müssen wir mehr über Ihre Frage, Ihre Umgebung (Anpassungen usw.) wissen. Routen für diese Entitäten basieren auf Daten in völlig unterschiedlichen Tabellen, und für jede gibt es separate Router-Klassen.
Benmarks

Antworten:

7

( Ich dachte, ich hätte eine ähnliche Antwort wie Alan gepostet , aber ich hatte keine. Ich sitze hier in LocalStorage. Aber ich kann seine Antwort mit einer interessanten Lösungstheorie versehen. )

Der CMS-Router fügt sich der Front Controller-Instanz hinzu, indem er das controller_front_init_routersEreignis beobachtet , nachdem der Admin- und der Standard-Router hinzugefügt wurden. Mit ein wenig Config XML, wäre es möglich , dies mit dem wechseln controller_front_init_beforeEreignis , wodurch das CMS Hinzufügen Router zunächst , seine Bedeutung match()ing Logik wird vor den anderen laufen.

Um diese Theorie zu testen, legen Sie Folgendes in app / etc / local.xml ab :

<frontend>
    <events>
        <!-- fire observer for different event -->
        <controller_front_init_before>
            <observers>
                <cms>
                    <class>Mage_Cms_Controller_Router</class>
                    <method>initControllerRouters</method>
                </cms>
            </observers>
        </controller_front_init_before>
        <!-- disable the original observer -->
        <controller_front_init_routers>
            <observers>
                <cms>
                    <type>disabled</type>
                </cms>
            </observers>
        </controller_front_init_routers>
    </events>
</frontend>

Überprüfen Sie, ob das Problem dadurch behoben wird.

Im Übrigen passt der CMS-Router den Anforderungspfad auf dieselbe Weise an wie das URL-Umschreibemodell.

Benmarks
quelle
Das ist ausgezeichnet. Ich glaube zwar nicht, dass etwas gegen die seltsame neue Methode des Kategorie-Routings unternommen werden muss, aber CMS-Seiten die erste Chance zu geben, eine Übereinstimmung zu erzielen, ist ein langer Weg.
mpw
2
Nennen Sie einfach keine CMS-Seite "admin" oder was auch immer Ihr Administrator-Frontname ist :-)
benmarks
Ok, vergiss 'es. Das funktioniert eigentlich nicht. Um sicherzustellen, dass ich nicht verrückt bin, frontendist richtig verschachtelt als config-> frontend, ja?
mpw
Ja. Stellen Sie sicher, dass es geladen wird, aber Sie können einen Haltepunkt festlegen, einen Mage::log()Anruf (oder ein Echo oder was auch immer) beenden Mage_Core_Controller_Varien_Action::addRouter(), um die Reihenfolge anzuzeigen, in der die Router-Klassen hinzugefügt werden.
Benmarks
Ich kann die addRouterMethode nur in sehen Mage_Core_Controller_Varien_Front. Unabhängig davon war die Reihenfolge gemäß der Protokollausgabe: admin, standard, cms, default.
mpw
6

Ich habe viele interessante Implementierungen (einige gute, andere schlechte) von SEO-Spezialisten gesehen, die im Laufe der Jahre keinen Magento-Hintergrund hatten. Es hört sich so an, als ob Sie Probleme mit benutzerdefiniertem Code haben, den Sie nicht verstehen. Die allgemeine Antwort auf Ihre Frage lautet möglicherweise "Wenden Sie sich an die Person, die den SEO-Code geschrieben und / oder die Erweiterung installiert hat, die Sie nicht verstehen", oder suchen Sie einen Magento-Berater, der einen Blick darauf wirft und ihn schnell für Sie zerlegt.

Ihre Frage ist trotz ihrer Klärung immer noch zu verwirrend. Im wahrsten Sinne des Wortes gibt es in Magento keine Einstellung, um "das Routing von Kategorien strenger zu gestalten". Ich werde in groben Zügen erklären, wie das Routing von Kategorien im Vergleich zum CMS-Routing in einem Standard-Magento-System funktioniert. Dies gibt Ihnen (hoffentlich) genügend Informationen, um eine neue Frage zu stellen, unter der wir sie verstehen können. Außerdem habe ich bereits ausführlich über den Versand von Magentos Anfragen geschrieben. Wenn Sie also an den wichtigsten Details interessiert sind, würde ich dort beginnen .

Kategorie-Routing

Streng genommen gibt es in Magento kein "Kategorie" -Routing. Auf einer Website mit deaktivierten SEO-freundlichen URLs sieht eine Kategorieliste wie folgt aus.

http://magento.example.com/catalog/category/view/id/8

Wenn SEO-freundliche URLs aktiviert sind, erstellt Magento (in einem Indizierungsprozess) zwischen einem und mehreren Einträgen in der

core_url_rewrite

Tabelle für diese Kategorie. Die request_pathSpalte ist hier die Importspalte. Wenn Magento entscheidet, wie mit einer bestimmten URL umgegangen werden soll, wird diese zuerst in dieser Tabelle angezeigt. Wenn die aktuelle URL mit der übereinstimmt request_path, ändert Magento die interne Darstellung der URL so, dass sie wie die target_pathSpalte aussieht .

In den Beispieldaten gibt es also eine Zeile, die so aussieht

*************************** 1. row ***************************
url_rewrite_id: 17
      store_id: 1
   category_id: 8
    product_id: NULL
       id_path: category/8
  request_path: electronics/cell-phones.html
   target_path: catalog/category/view/id/8
     is_system: 1
       options: NULL
   description: NULL
1 row in set (0.01 sec)

Wenn Magento die URL sieht http://magento.example.com/electronics/cell-phones.html, stimmt sie mit dieser Zeile überein, da die request_pathVariable ist electronics/cell-phones.html. Anschließend ändert es seine interne Darstellung der URL in target_path( catalog/category/view/id/8). Dann behandelt Magento die URL normal.

Das ist wahrscheinlich ein bisschen zu folgen, wenn Sie nicht daran gewöhnt sind, aber das Wichtigste, was Sie mitnehmen sollten, ist das System, das entscheidet, wie mit der URL umgegangen wird. Es ist egal, ob es sich um eine Kategorie-URL handelt, es ist nur wichtig, dass es einen Eintrag gibt in der core_url_rewriteTabelle . Dieselbe Tabelle wird für Produktnamen-URLs verwendet. Viele SEO-Erweiterungen und benutzerdefinierte Codelösungen verwenden diese Tabelle ebenfalls.

CMS-Seitenrouting

Nachdem Magento die Referenzierung der core_url_rewriteTabelle abgeschlossen hat, geschieht Folgendes

  1. Es wird nach Übereinstimmungen mit Admin-Anwendungsseiten gesucht (Produkte verwalten, Kategorien verwalten usw.).

  2. Es wird nach Übereinstimmungen mit der Frontend-Anwendungsseite gesucht (Produktlistenseite, oben genannte Kategorielistenseite usw.).

  3. Wenn die Nummern 1 und 2 keine Übereinstimmungen enthalten, wird nach einer CMS-Seitenübereinstimmung gesucht.

Magento nicht verwenden , um die core_url_rewriteTabelle für CMS - Seiten. Wenn stattdessen Schritt 3 erreicht ist, wird versucht, die URL mit der URL Keyauf dem CMS-Seitenobjekt festgelegten Menge abzugleichen. (Es wäre genauer zu sagen, dass Magento, wenn es nach einer CMS-Seitenübereinstimmung sucht, eine URL verwendet, die bereits durch den core_url_rewriteProzess geändert wurde - aber die Dinge sind bereits verwirrend genug.)

Die wichtigsten Aspekte hierbei sind: Der CMS-Abgleich erfolgt erst, nachdem ein Abgleich der Kategorieseiten fehlgeschlagen ist.

Es hört sich so an, als ob externe Prozesse die core_url_rewriteTabelle ändern oder ein benutzerdefiniertes Router-Objekt zu Ihrem System hinzugefügt wird, das zusätzliches Routing ausführt, oder sogar ein Nicht-Magento-System, das Dinge tut, um URLs zu ändern.

Ich fürchte, es gibt keine schnelle und einfache Antwort auf Ihre Situation.

Alan Storm
quelle
Ich kann eine Lösung haben, siehe meine Antwort
Benmarks
Ich glaube nicht, dass sich ein benutzerdefinierter Code auf das Umschreiben der Kategorie-URL auswirkt (obwohl ich mir die core_url_rewriteTabelle genauer ansehen werde ). Ich kann mich von Anfang an daran erinnern, dass subcategorydies /subcategory.html(im Gegensatz zu category/subcategory.html) übereinstimmen würde - noch bevor externer Code eingeführt wurde. ( \n) Angenommen, dies hätte früher nützlich sein können, aber ist es möglich, dass es eine Änderung gab in EE 1.13 könnte das dies verursachen?
mpw
@ MPW Ich weiß es nicht. Mein Ansatz ist es, diese Dinge von unten nach oben zu debuggen.
Alan Storm
Ich habe gerade den core_url_rewriteTisch überprüft . Es ist leer. Könnte dies etwas mit meinen Problemen zu tun haben?
mpw
1
Soweit ich das beurteilen kann, wird core_url_rewrite in 1.13 nicht verwendet, obwohl ich mir nicht sicher bin. Ich denke, dass jetzt nur Enterprise_url_rewrite verwendet wird.
Josh
5

Was ich suche, ist eine URL-Struktur ähnlich den vorherigen Magento-Versionen (IE-Kategorie / Unterkategorie), ohne die Vorteile der Hintergrundindizierung zu verlieren, die 1.13 bietet.

Dies ist ein Problem, das ich mir angesehen habe und das bisher keine gute Lösung zu haben scheint. Wir haben einige tief verschachtelte Kategorien, zum Beispiel:

Cat A
    Cat B
        Cat C
            Cat D

Vor 1.13 wurde die Kategorie-URL als www.domain.com/cat-a/cat-b/cat-c/cat-d/ generiert, jetzt wird sie jedoch als www.domain.com/catd generiert. Wenn Sie mehrere "Cat D" haben, kann dies beispielsweise zu www.domain.com/catalog/category/view/s/cat-d/id/132/ führen.

Ich habe an verschiedenen Ideen herumgebastelt, um dies zu beheben. Ich versuche gerade, die loadByRequestPath-Methode von Enterprise_UrlRewrite_Model_Resource_Url_Rewrite so zu ändern, dass zuerst nach einem vollständigen Pfad gesucht wird, bevor das Standardverhalten verwendet wird. Ich habe das getan, indem ich diese Methode hinzugefügt habe:

protected function tryLoadByFullPath($object, $paths)
{
    if (count($paths) > 1) {
        $_path = implode('/', $paths);

        $select = $this->_getReadAdapter()->select()
            ->from(array('m' => $this->getMainTable()))
            ->where('m.request_path = ?', $_path);

        $result = $this->_getReadAdapter()->fetchRow($select);

        if ($result) {
            $object->setData($result);
            $this->unserializeFields($object);
            $this->_afterLoad($object);

            return true;
        }
    }

    return false;
}

und dann diesen Code oben in loadByRequestPath () hinzufügen:

if ($this->tryLoadByFullPath($object, $paths)) {
        return $this;
}

Es scheint zu funktionieren, auf den ersten Blick jedenfalls habe ich es noch nicht sehr gut getestet. Der Nachteil dabei ist, dass der url_key für jede Kategorie manuell auf den vollständigen Pfad gesetzt werden muss, sodass Sie den url-Schlüssel für Cat D auf "cat-a / cat-b / cat-c / cat-d" setzen müssen ". Das ist offensichtlich nicht ideal.

Wie auch immer, das ist wahrscheinlich nicht sehr hilfreich, aber vielleicht hat jemand eine bessere Einstellung zu diesem Ansatz.

Josh
quelle
Ich bin nur froh, damit nicht alleine zu sein! Wenn wir eine Lösung finden, werde ich sie auf jeden Fall melden.
mpw
5

@benmarks Antwort ist schon gut. Sie haben jedoch weiterhin Probleme, wenn Ihre Produkt-URLs mit Ihren CMS-Seiten-URLs übereinstimmen. Die URL-Umschreibungen aus der Tabelle core_url_rewritewerden überprüft, bevor die Router überprüft werden - siehe Mage_Core_Controller_Varien_Front::dispatch:

public function dispatch()
{
    // [...]
    $this->_getRequestRewriteController()->rewrite();

    Varien_Profiler::start('mage::dispatch::routers_match');
    $i = 0;
    while (!$request->isDispatched() && $i++ < 100) {
        foreach ($this->_routers as $router) {
            /** @var $router Mage_Core_Controller_Varien_Router_Abstract */
            if ($router->match($request)) {
                break;
            }
        }
    }
    // [...]
}

Wenn eine Produkt-URL mit den aktuellen Mage_Core_Model_Url_Rewrite_Request::_rewriteDbPfadinformationen übereinstimmt, werden die Pfadinformationen der Anforderung geändert , sodass der CMS-Router nicht mehr übereinstimmt, obwohl er vor dem Katalogrouter aufgerufen wird (wenn Sie @benmarks config.xml angewendet haben). .

Zum Glück gibt es eine nette Flagge namens straight, die auf a gesetzt werden kann Mage_Core_Controller_Request_Http. Wenn das Flag gesetzt ist, wird das Umschreiben der URL aus der Datenbank nicht überprüft. Daher besteht meine Lösung darin, ein Ereignis zu beobachten, das früh genug ausgelöst wird ( controller_front_init_before), und das straightFlag für die darin enthaltene Anforderung zu setzen, wenn die aktuellen Pfadinformationen mit einer CMS-Seitenkennung übereinstimmen:

In Ihrer config.xml:

<global>
    <events>
        <controller_front_init_before>
            <observers>
                <namespace_module>
                    <class>namespace_module/observer</class>
                    <method>controllerFrontInitBefore</method>
                </namespace_module>
            </observers>
        </controller_front_init_before>
    </events>
<global>

Ihre Beobachtermethode:

class Namespace_Module_Model_Observer
{

    public function controllerFrontInitBefore(Varien_Event_Observer $observer)
    {
        /** @var Mage_Core_Controller_Request_Http $request */
        $request = $observer->getFront()->getRequest();

        $identifier = trim($request->getPathInfo(), '/');
        $pageId = Mage::getModel('cms/page')->checkIdentifier($identifier, Mage::app()->getStore()->getId());

        if ($pageId) {
            $request->isStraight(true);
        }
    }

}

Da der Katalogrouter nicht übereinstimmt, wenn die Datenbank-URL nicht neu geschrieben wird, sollte diese Lösung eigenständig funktionieren und Sie benötigen nicht einmal die Datei config.xml von @benmarks.

Hoffe, das hilft jemandem - das Debuggen hat einige Mühe gekostet!

Simon
quelle
Sehr schöner Fund.
Benmarks