カスタムコンポーネントの特定のビューのメニュー項目があります。このメニュー項目に添付されているので、標準テンプレートではなく、別の_Template Style
_を選択しています。メニューからビューにアクセスすると、Itemid
というURLにアタッチされるため、うまく機能します。
次に、JRouteを使用してビューを別のビューとリンクしたいのですが、JRouteが目的のURLを生成していません。
echo JRoute::_('index.php?option=com_example&view=reporting');
_/index.php?option=com_example&view=reporting
_
JRoute
は、ItemidをURLに追加しないため、メニュー項目の選択されたテンプレートスタイルが機能しなくなります。
Itemidを "計算"する方法はありますか(列link
でテーブル_jos_menu
_でクエリを実行することを除いて)、それをJRouteにアタッチしますか?
ここに私が使ったテクニックがあります(どこで見つけたか思い出せません)。
$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);
これは私にとって不思議に働きました。
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が言ったように、非常に間違っている場合があります)。
ここで重要なのは、適切なメニュー項目を検索して選択するロジックを備えたコンポーネント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値に基づいて最適な一致を見つけます。右に行くほどマッチすると思います!
Afaik JRouteは、何も指定されていない場合、アクティブItemid
(およびアクティブoption
)を取得します。それがうまくいかない場合、それはあなたのコードへの呼び出しがもともとItemidなしで来ていることを意味します。もしそうなら、最も簡単なことは、最初の呼び出しにItemidを追加することです。
メニュー項目を検索する必要がある場合は、直接クエリを実行せず、代わりにJMenuを使用します。