URLでItemidを取得してJRouteに渡す方法


14

カスタムコンポーネントの特定のビューのメニュー項目があります。このメニュー項目に添付してTemplate Style、標準テンプレートではなく、別のテンプレートを選択しています。メニューからビューにアクセスすると、URLに添付されるため、うまく機能しますItemid

次に、JRouteを使用してビューを別のビューとリンクしますが、JRouteは目的のURLを生成しません。

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

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

JRoute URLにItemidを追加しないため、メニュー項目の選択されたテンプレートスタイルは機能しません。

Itemidを「計算」してjos_menu列のテーブルでクエリを実行する以外にlink)、JRouteにアタッチする方法はありますか?


あなたがdoよりitemidを知っている場合、reporting&Itemid = 123。カスタムコンポーネントが既に公開されている場合、これを自動的に行う必要があるため、この手順はお勧めしません。
ダン

回答:


20

ここに私が使用したテクニックがあります(どこで見つけたか覚えていません)。

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

これは私にとって驚異的な働きをしました。


4

JRouteからの出力は、提供する内容によって異なります。

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

以外のものを返す可能性があります

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

実際、catid = 5のメニュー項目カテゴリのブログリストがある場合、後者はmenu-urlを提供する可能性があります(この正確なURLはテストしていません)。異なるgetパラメータを使用して、異なる結果を取得してみてください(@Fedikが言ったように、非常に間違っている場合があります)


3

ここで重要なのは、適切なメニュー項目を検索して選択するロジックを使用して、コンポーネントのrouter.phpファイル(フロントエンドのコンポーネントのルートフォルダーにあります)をセットアップすることです。私はこれが自動的に起こるのを楽しみにしていますが、私が知る限りではそうではありません。

おそらく、このコードブロックを、コンテンツに最適なメニュー項目を自動的に見つけるために使用できる何らかの種類のヘルパー関数に組み込むのが最善でしょう。

以下は、最適なメニュー項目を取得するためにいくつかのカスタムコンポーネントで使用したコードです。

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

これはすべて一種の混乱です(そして、もし誰かがそれらを持っているなら、私は改善が大好きです!)、それは仕事を終わらせます。現在のメニュー項目が最良の一致である場合、常にそれが維持されます。

それ以外の場合は、コンポーネント名->ビュー名->レイアウト名-> id値に基づいて最適な一致を見つける必要があります。一致するほど右にあるほど、一致すると判断します。


2

Afaik JRouteは、何も提供されていない場合、アクティブItemid(およびアクティブoption)を取ります。それがうまくいかない場合は、コードの呼び出しが最初からItemidなしで行われることを意味します。その場合、最も簡単なことは、最初の呼び出しにItemidを追加することです。

メニュー項目を検索する必要がある場合は、直接クエリを実行せず、代わりにJMenuを使用します。


場合によっては、JRouterがクレイジーなURLを返すことがあることに気づきました。独自のItemidを提供しようとすると、JRouterの例がJRoute::_('index.php?option=com_example&view=reporting&Itemid=10')返すことができ/current-path?view=reporting&Itemid=10ます...特定のことはありますか?
フェディック
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.