Cách nhận Itemid bằng URL và chuyển nó đến JRoute


14

Tôi có một mục menu cho một chế độ xem cụ thể trong một thành phần tùy chỉnh. Kèm theo mục menu này tôi có một mục khác Template Styleđược chọn, không phải mẫu tiêu chuẩn. Truy cập chế độ xem qua menu hoạt động tốt, vì nó gắn vào URL Itemid.

Bây giờ tôi muốn liên kết, sử dụng JRoute, một chế độ xem với một chế độ khác, tuy nhiên JRoute không tạo ra URL mong muốn.

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

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

JRoute sẽ không nối Itemid vào URL, khiến kiểu mẫu được chọn cho mục menu không hoạt động.

Có cách nào để "tính toán" Itemid (ngoài việc thực hiện một truy vấn trong bảng jos_menutrên cột link) và gắn nó vào JRoute không?


nếu bạn biết itemid hơn làm, báo cáo & Itemid = 123. Tôi không khuyên thủ tục này vì thành phần tùy chỉnh của bạn sẽ tự động làm điều này nếu nó đã được xuất bản.
Dan

Câu trả lời:


20

Đây là một kỹ thuật tôi đã sử dụng (không thể nhớ nơi tôi tìm thấy nó).

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

Điều này đã làm việc kỳ diệu cho tôi.


4

đầu ra từ JRoute sẽ phụ thuộc vào những gì bạn cung cấp cho nó.

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

có thể trả lại một cái gì đó khác

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

Trong thực tế nếu bạn có một danh sách blog danh mục mục menu cho catid = 5, thì danh sách sau có thể cung cấp cho bạn url menu (Tôi chưa kiểm tra url chính xác này). Hãy thử với các tham số get khác nhau để có kết quả khác nhau (đôi khi rất sai, như @Fedik đã nói)


3

Chìa khóa ở đây là thiết lập tệp tin router.php thành phần (cần tìm trong thư mục gốc của thành phần của bạn ở mặt trước) với logic sẽ tìm kiếm và chọn mục menu phù hợp. Tôi rất muốn thấy điều này tự động xảy ra, nhưng theo tôi biết thì đây không phải là trường hợp.

Có lẽ tốt nhất là làm việc khối mã này với một số loại hàm trợ giúp có thể được sử dụng để tự động tìm mục menu phù hợp nhất cho nội dung.

Đây là mã mà tôi đã sử dụng trong một số thành phần tùy chỉnh của mình để có được mục menu phù hợp nhất:

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

Tất cả điều này là một mớ hỗn độn (và tôi rất thích cải tiến nếu có ai có chúng!), Nhưng nó đã hoàn thành công việc. Nếu mục menu hiện tại là phù hợp nhất, nó sẽ luôn luôn gắn bó với điều đó.

Nếu không, nó sẽ tìm thấy kết quả phù hợp nhất dựa trên tên Thành phần -> tên xem -> tên bố cục -> giá trị id. Càng đi đúng về phía bên phải, tôi càng thấy trận đấu tốt hơn!


2

Afaik JRoute sẽ hoạt động Itemid(và cả hoạt động option) nếu không được cung cấp. Nếu điều đó không hiệu quả, điều đó có nghĩa là cuộc gọi đến mã của bạn không có Itemid để bắt đầu. Nếu vậy, điều dễ nhất sẽ là thêm Itemid vào cuộc gọi nội bộ.

Nếu bạn cần tra cứu mục menu, tôi sẽ không thực hiện truy vấn trực tiếp mà thay vào đó sử dụng JMothy.


Tôi nhận thấy rằng trong một số trường hợp, JRouter có thể trả về một số URL điên rồ, nếu thử cung cấp Itemid riêng, ví dụ cho JRoute::_('index.php?option=com_example&view=reporting&Itemid=10')JRouter có thể trả lại /current-path?view=reporting&Itemid=10... có một số điều cụ thể không?
Fedik
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.