So erhalten Sie Itemid per URL und übergeben es an JRoute

14

Ich habe ein Menüelement für eine bestimmte Ansicht in einer benutzerdefinierten Komponente. An diesen Menüpunkt habe ich eine andere Template Styleausgewählt, nicht die Standardvorlage. Der Zugriff auf die Ansicht über das Menü funktioniert gut, da es an die URL der anhängt Itemid.

Jetzt möchte ich mit JRoute eine Ansicht mit einer anderen verknüpfen, JRoute generiert jedoch nicht die gewünschte URL.

echo JRoute::_('index.php?option=com_example&view=reporting');

/index.php?option=com_example&view=reporting

JRoute Die Itemid wird nicht an die URL angehängt, wodurch der ausgewählte Vorlagenstil für das Menüelement nicht funktioniert.

Gibt es eine Möglichkeit, die Itemid zu "berechnen" (abgesehen von einer Abfrage in der Tabelle jos_menuin der Spalte link) und an JRoute anzuhängen?

Valentin Despa
quelle
Wenn Sie die itemid kennen, geben Sie & Itemid = 123 an. Ich rate nicht zu diesem Verfahren, da Ihre benutzerdefinierte Komponente dies automatisch tun sollte, wenn es bereits veröffentlicht ist.
Dan

Antworten:

20

Hier ist eine Technik, die ich benutzt habe (ich kann mich nicht erinnern, wo ich sie gefunden habe).

$app = JFactory::getApplication(); 
$menu = $app->getMenu();
$menuItem = $menu->getItems( 'link', 'index.php?option=com_example&view=reporting', true );
echo JRoute::_('index.php?Itemid='.$menuItem->id);

Das hat Wunder für mich gewirkt.

Jordan Ramstad
quelle
4

Die Ausgabe von JRoute hängt davon ab, was Sie füttern.

JRoute::_("index.php?option=com_content&view=article&id=10"); 

könnte etwas anderes zurückgeben als

JRoute::_("index.php?option=com_content&view=article&id=10&catid=5"); 

In der Tat, wenn Sie eine Blog-Auflistung der Menüelementkategorie für catid = 5 haben, kann diese Ihnen die Menü-URL geben (ich habe diese exakte URL nicht getestet). Versuche es mit verschiedenen get-Parametern, um unterschiedliche Ergebnisse zu erhalten (manchmal sehr falsch, wie @Fedik sagte)

jonasfh
quelle
3

Der Schlüssel hier ist die Einrichtung Ihrer Komponente router.php-Datei (die sich im Stammverzeichnis Ihrer Komponente im Front-End befindet) mit Logik, die nach dem entsprechenden Menüpunkt sucht und diesen auswählt. Ich würde gerne sehen, dass dies automatisch geschieht, aber soweit ich weiß, ist dies nicht der Fall.

Es ist wahrscheinlich am besten, diesen Codeblock in eine Art Hilfsfunktion einzuarbeiten, mit der automatisch das am besten passende Menüelement für den Inhalt gefunden werden kann.

Hier ist der Code, den ich in einigen meiner benutzerdefinierten Komponenten verwendet habe, um das am besten passende Menüelement zu erhalten:

// I use this first empty array to avoid having unset properties in my query
$base_array = array('Itemid'=>'', 'option'=>'', 'view'=>'', 'layout'=>'', 'id'=>'');

$app =& JFactory::getApplication();
$menu       = $app->getMenu();
$active = $menu->getActive();

// hack to protect the actual current item as well as the search module or other places that use JRoute::_('index.php');
if (count($query)==2 && isset($query['option']) && isset($query['Itemid']) && $query['option'] && $query['Itemid']) {
    return $segments;
}

// start with no match found
$match = false;
$match_level = 0;

$query += $base_array;

// we want to find a menu item for this if possible. If the active menu item is the current menu item then we should see if there is a better match.
if (empty($query['Itemid']) || ($query['Itemid'] == $active->id && empty($query['task']))) {
    // load all menu items
    $items = $menu->getMenu();

    // use the current item over others if it ties for the best match
    if ($active->query['option'] == $query['option']) {
        $match_level = 1;
        $match = $active;
        if ($active->query['view'] == $query['view']) {
            $match_level = 2;
            if ($active->query['layout'] == $query['layout'] || ($query['layout']=='default' && !$active->query['layout'])) {
                $match_level = 3;
                if ($active->query['id'] == $query['id']) {
                    $match_level = 4;
                }
            }
        }
    }

    // loop through each menu item in order
    foreach ($items as $item) {
        $item->query += $base_array;
        // base check is that it is for this component
        // then cycle through each possibility finding it's match level
        if ($item->query['option'] == $query['option']) {
            $item_match = 1;
            if ($item->query['view'] == $query['view']) {
                $item_match = 2;
                if (!$query['layout'] && $item->query['layout']) {
                    $query['layout'] = 'default';
                }
                if ($item->query['layout'] == $query['layout'] || ($query['layout']=='default' && !$item->query['layout'])) {
                    $item_match = 3;
                    if ($item->query['id'] == $query['id']) {
                        $item_match = 4;
                    }
                }
            }
        }

        // if this item is a better match than our current match, set it as the best match
        if ($item_match > $match_level) {
            $match = $item;
            $match_level = $item_match;
        }

    }

    // if there is a match update Itemid to match that menu item
    if ($match) {
        $query['Itemid'] = $match->id;
        $menuItem = $menu->getItem($match->id);
    } else {
        $menuItem = $menu->getActive();
    }
}

All dies ist eine Art Chaos (und ich würde Verbesserungen lieben, wenn jemand sie hat!), Aber es wird die Arbeit erledigt. Wenn der aktuelle Menüpunkt der beste ist, bleibt er immer dabei.

Andernfalls sollte die beste Übereinstimmung basierend auf Komponentenname -> Ansichtsname -> Layoutname -> ID-Wert gefunden werden. Je weiter rechts es passt, desto besser finde ich das Spiel!

David Fritsch
quelle
2

Afaik JRoute übernimmt die aktive Itemid(und auch die aktive option), wenn keine bereitgestellt wird. Wenn dies nicht funktioniert, bedeutet dies, dass der Aufruf Ihres Codes zunächst ohne Itemid erfolgt. In diesem Fall ist es am einfachsten, die Itemid zum Anfangsaufruf hinzuzufügen.

Wenn Sie den Menüpunkt nachschlagen müssen, würde ich keine direkte Abfrage durchführen, sondern stattdessen JMenu verwenden.

Bakual
quelle
Mir ist aufgefallen, dass JRouter in einigen Fällen eine verrückte URL zurückgeben kann, wenn Sie versuchen, eine eigene Itemid bereitzustellen, die beispielsweise von JRoute::_('index.php?option=com_example&view=reporting&Itemid=10')JRouter zurückgegeben werden kann /current-path?view=reporting&Itemid=10... Gibt es bestimmte Dinge?
Fedik