it-swarm-vi.com

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

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 Template Style Khác được chọn, không phải mẫu chuẩn. Truy cập chế độ xem qua menu hoạt động tốt, vì nó gắn vào URL là Itemid.

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

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

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

JRoute sẽ không thêm Itemid vào URL, khiến kiểu mẫu đã 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_menu Trên cột link) và để gắn nó vào JRoute?

14
Valentin Despa

Đâ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.

20
Jordan Ramstad

đầ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)

4
jonasfh

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!

3
David Fritsch

Afaik JRoute sẽ sử dụ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.

2
Bakual