วิธีรับ Itemid ด้วย URL และส่งต่อไปยัง 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 จะไม่ต่อท้าย Itemid กับ URL ทำให้สไตล์เทมเพลตที่เลือกไว้สำหรับรายการเมนูไม่ทำงาน

มีวิธีการ "คำนวณ" Itemid (นอกเหนือจากการทำแบบสอบถามในตารางjos_menuในคอลัมน์link) และแนบกับ JRoute หรือไม่


ถ้าคุณรู้ว่ามีรายการมากกว่าให้รายงาน & รายการ = 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 รายการหลังอาจให้เมนู URL (ฉันยังไม่ได้ทดสอบ URL ที่แน่นอนนี้) ลองใช้พารามิเตอร์รับที่แตกต่างกันเพื่อให้ได้ผลลัพธ์ที่แตกต่างกัน (บางครั้งผิดอย่างมากเช่น @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 ของตัวเองตัวอย่างสำหรับJRoute::_('index.php?option=com_example&view=reporting&Itemid=10')JRouter สามารถกลับมา/current-path?view=reporting&Itemid=10... มีบางสิ่งที่พิเศษหรือไม่?
Fedik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.