it-swarm.it

Come ottenere Itemid tramite URL e passarlo a JRoute

Ho una voce di menu per una vista specifica in un componente personalizzato. In allegato a questa voce di menu ho selezionato un altro Template Style, Non il modello standard. L'accesso alla vista tramite il menu funziona bene, poiché si collega all'URL Itemid.

Ora voglio collegare, usando JRoute, una vista con un'altra, tuttavia JRoute non sta generando l'URL desiderato.

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

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

JRoute non aggiungerà Itemid all'URL, facendo sì che lo stile del modello selezionato per la voce di menu non funzioni.

Esiste un modo per "calcolare" Itemid (oltre a fare una query nella tabella jos_menu Nella colonna link) e collegarlo a JRoute?

14
Valentin Despa

Ecco una tecnica che ho usato (non ricordo dove l'ho trovata).

$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);

Questo ha funzionato a meraviglia per me.

20
Jordan Ramstad

l'output di JRoute dipenderà da ciò che lo alimenta.

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

potrebbe restituire qualcos'altro di

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

In effetti, se hai un elenco di blog di categoria di voci di menu per catid = 5, quest'ultimo potrebbe fornirti il ​​menu-url (non ho testato questo URL esatto). Prova con diversi parametri get per ottenere risultati diversi (a volte molto sbagliato, come ha detto @Fedik)

4
jonasfh

La chiave qui è impostare il file router.php dei componenti (che dovrebbe essere trovato nella cartella principale del componente sul front-end) con la logica che cercherà e selezionerà la voce di menu appropriata. Mi piacerebbe vederlo accadere automaticamente, ma per quanto ne so non è così.

Probabilmente sarebbe meglio inserire questo blocco di codice in un tipo di funzione di supporto che può essere utilizzata per trovare automaticamente la voce di menu più adatta al contenuto.

Ecco il codice che ho usato in molti dei miei componenti personalizzati per ottenere la voce di menu più adatta:

// 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();
    }
}

Tutto questo è un po 'un casino (e mi piacerebbe molto che qualcuno li avesse!), Ma fa il lavoro. Se la voce di menu corrente è la migliore corrispondenza, rimarrà sempre con quella.

Altrimenti dovrebbe trovare la migliore corrispondenza in base al nome del componente -> nome della vista -> nome del layout -> valore id. Più a destra corrisponde, meglio ritengo che la partita!

3
David Fritsch

Afaik JRoute prenderà il Itemid attivo (e anche il option attivo) se non ne viene fornito nessuno. Se non funziona, significa che la chiamata al tuo codice arriva senza Itemid per cominciare. In tal caso, la cosa più semplice sarebbe aggiungere Itemid alla chiamata iniziale.

Se hai bisogno di cercare la voce di menu, non farei una query diretta ma utilizzerei invece JMenu.

2
Bakual