自动导航空白 link 按钮显示三个不同父页面的下拉菜单
Auto Nav blank link button to display dropdown with three different parent pages
Image to describe issue better
我的老板正在寻找在导航栏中设置的导航 link,它本身不是页面,而是在下拉列表中显示 3 个单独的父页面 (www.website.com/turkey、/希腊、/意大利)。他希望为新网站保留 url 结构以避免过多的重定向,这个问题对我来说是个问题,我自己尝试解决。
Auto Nav 本身使用 php 生成基于站点结构的导航栏,因此在不进行任何 php 编辑的情况下合并它的唯一方法是将 link 设为一个页面(而不是像我的老板希望的那样只是一个空白 link),但随后它破坏了他想要遵循的 url 文件结构。
我认为这必须在 php 中解决,但我自己并不是很精通,因此非常感谢您的指导!
抱歉,如果这有点不清楚,如果需要更清楚的信息,请告诉我!
<?php defined('C5_EXECUTE') or die(_("Access Denied."));
$navItems = $controller->getNavItems();
/**
* The $navItems variable is an array of objects, each representing a nav menu item.
* It is a "flattened" one-dimensional list of all nav items -- it is not hierarchical.
* However, a nested nav menu can be constructed from this "flat" array by
* looking at various properties of each item to determine its place in the hierarchy
* (see below, for example $navItem->level, $navItem->subDepth, $navItem->hasSubmenu, etc.)
*
* Items in the array are ordered with the first top-level item first, followed by its sub-items, etc.
*
* Each nav item object contains the following information:
* $navItem->url : URL to the page
* $navItem->name : page title (already escaped for html output)
* $navItem->target : link target (e.g. "_self" or "_blank")
* $navItem->level : number of levels deep the current menu item is from the top (top-level nav items are 1, their sub-items are 2, etc.)
* $navItem->subDepth : number of levels deep the current menu item is *compared to the next item in the list* (useful for determining how many <ul>'s to close in a nested list)
* $navItem->hasSubmenu : true/false -- if this item has one or more sub-items (sometimes useful for CSS styling)
* $navItem->isFirst : true/false -- if this is the first nav item *in its level* (for example, the first sub-item of a top-level item is TRUE)
* $navItem->isLast : true/false -- if this is the last nav item *in its level* (for example, the last sub-item of a top-level item is TRUE)
* $navItem->isCurrent : true/false -- if this nav item represents the page currently being viewed
* $navItem->inPath : true/false -- if this nav item represents a parent page of the page currently being viewed (also true for the page currently being viewed)
* $navItem->attrClass : Value of the 'nav_item_class' custom page attribute (if it exists and is set)
* $navItem->isHome : true/false -- if this nav item represents the home page
* $navItem->cID : collection id of the page this nav item represents
* $navItem->cObj : collection object of the page this nav item represents (use this if you need to access page properties and attributes that aren't already available in the $navItem object)
*/
/** For extra functionality, you can add the following page attributes to your site (via Dashboard > Pages & Themes > Attributes):
*
* 1) Handle: exclude_nav
* (This is the "Exclude From Nav" attribute that comes pre-installed with concrete5, so you do not need to add it yourself.)
* Functionality: If a page has this checked, it will not be included in the nav menu (and neither will its children / sub-pages).
*
* 2) Handle: exclude_subpages_from_nav
* Type: Checkbox
* Functionality: If a page has this checked, all of that pages children (sub-pages) will be excluded from the nav menu (but the page itself will be included).
*
* 3) Handle: replace_link_with_first_in_nav
* Type: Checkbox
* Functionality: If a page has this checked, clicking on it in the nav menu will go to its first child (sub-page) instead.
*
* 4) Handle: nav_item_class
* Type: Text
* Functionality: Whatever is entered into this textbox will be outputted as an additional CSS class for that page's nav item (NOTE: you must un-comment the "$ni->attrClass" code block in the CSS section below for this to work).
*/
/*** STEP 1 of 2: Determine all CSS classes (only 2 are enabled by default, but you can un-comment other ones or add your own) ***/
foreach ($navItems as $ni) {
$classes = array();
if ($ni->isCurrent) {
//class for the page currently being viewed
$classes[] = 'nav-selected';
}
if ($ni->inPath) {
//class for parent items of the page currently being viewed
$classes[] = 'nav-path-selected';
}
/*
if ($ni->isFirst) {
//class for the first item in each menu section (first top-level item, and first item of each dropdown sub-menu)
$classes[] = 'nav-first';
}
*/
/*
if ($ni->isLast) {
//class for the last item in each menu section (last top-level item, and last item of each dropdown sub-menu)
$classes[] = 'nav-last';
}
*/
if ($ni->hasSubmenu) {
//class for items that have dropdown sub-menus
$classes[] = 'parent';
}
/*
if (!empty($ni->attrClass)) {
//class that can be set by end-user via the 'nav_item_class' custom page attribute
$classes[] = $ni->attrClass;
}
*/
/*
if ($ni->isHome) {
//home page
$classes[] = 'nav-home';
}
*/
/*
//unique class for every single menu item
$classes[] = 'nav-item-' . $ni->cID;
*/
//Put all classes together into one space-separated string
$ni->classes = implode(" ", $classes);
}
//*** Step 2 of 2: Output menu HTML ***/
echo '<div id="menu">';
echo '<ul class="nav menu">'; //opens the top-level menu
foreach ($navItems as $ni) {
echo '<li class="' . $ni->classes . '">'; //opens a nav item
echo '<a href="' . $ni->url . '" target="' . $ni->target . '" class="' . $ni->classes . '">' . $ni->name . '</a>';
if ($ni->hasSubmenu) {
echo '<ul>'; //opens a dropdown sub-menu
} else {
echo '</li>'; //closes a nav item
echo str_repeat('</ul></li>', $ni->subDepth); //closes dropdown sub-menu(s) and their top-level nav item(s)
}
}
echo '</ul>'; //closes the top-level menu
echo '</div>'; //closes the top-level menu-container
我建议只添加一个特殊配置来修改自动导航菜单的链接,如下所示:
$navItems = $controller->getNavItems();
$special_config = array(
"www.website.com/turkey" /* url */=> array( "level" => 2 ),
"www.website.com/greece" /* url */=> array( "level" => 2 )
// .. rest special config here
);
foreach ($navItems as &$navItem)
{
if ( isset($special_config[$navItem->url]) )
{
foreach ($special_config[$navItem->url] as $k=>$v)
{
// adjust navItem params as needed here by key=>value
$navItem->{$k} = $v;
}
}
}
// rest code follows
// ...
您甚至可以像这样创建函数 ammend_nav_menu
:
function ammend_nav_menu($special_config, &$navItems)
{
foreach ($navItems as &$navItem)
{
if ( isset($special_config[$navItem->url]) )
{
foreach ($special_config[$navItem->url] as $k=>$v)
{
// adjust navItem params as needed here by key=>value
$navItem->{$k} = $v;
}
}
}
}
并这样使用:
$navItems = $controller->getNavItems();
ammend_nav_menu(array(
"www.website.com/turkey" /* url */=> array( "level" => 2 ),
"www.website.com/greece" /* url */=> array( "level" => 2 )
// .. rest special config here
), $navItems);
修改菜单的特殊配置甚至可以放在单独的 php 文件中并根据需要加载/更新
Image to describe issue better
我的老板正在寻找在导航栏中设置的导航 link,它本身不是页面,而是在下拉列表中显示 3 个单独的父页面 (www.website.com/turkey、/希腊、/意大利)。他希望为新网站保留 url 结构以避免过多的重定向,这个问题对我来说是个问题,我自己尝试解决。
Auto Nav 本身使用 php 生成基于站点结构的导航栏,因此在不进行任何 php 编辑的情况下合并它的唯一方法是将 link 设为一个页面(而不是像我的老板希望的那样只是一个空白 link),但随后它破坏了他想要遵循的 url 文件结构。
我认为这必须在 php 中解决,但我自己并不是很精通,因此非常感谢您的指导!
抱歉,如果这有点不清楚,如果需要更清楚的信息,请告诉我!
<?php defined('C5_EXECUTE') or die(_("Access Denied."));
$navItems = $controller->getNavItems();
/**
* The $navItems variable is an array of objects, each representing a nav menu item.
* It is a "flattened" one-dimensional list of all nav items -- it is not hierarchical.
* However, a nested nav menu can be constructed from this "flat" array by
* looking at various properties of each item to determine its place in the hierarchy
* (see below, for example $navItem->level, $navItem->subDepth, $navItem->hasSubmenu, etc.)
*
* Items in the array are ordered with the first top-level item first, followed by its sub-items, etc.
*
* Each nav item object contains the following information:
* $navItem->url : URL to the page
* $navItem->name : page title (already escaped for html output)
* $navItem->target : link target (e.g. "_self" or "_blank")
* $navItem->level : number of levels deep the current menu item is from the top (top-level nav items are 1, their sub-items are 2, etc.)
* $navItem->subDepth : number of levels deep the current menu item is *compared to the next item in the list* (useful for determining how many <ul>'s to close in a nested list)
* $navItem->hasSubmenu : true/false -- if this item has one or more sub-items (sometimes useful for CSS styling)
* $navItem->isFirst : true/false -- if this is the first nav item *in its level* (for example, the first sub-item of a top-level item is TRUE)
* $navItem->isLast : true/false -- if this is the last nav item *in its level* (for example, the last sub-item of a top-level item is TRUE)
* $navItem->isCurrent : true/false -- if this nav item represents the page currently being viewed
* $navItem->inPath : true/false -- if this nav item represents a parent page of the page currently being viewed (also true for the page currently being viewed)
* $navItem->attrClass : Value of the 'nav_item_class' custom page attribute (if it exists and is set)
* $navItem->isHome : true/false -- if this nav item represents the home page
* $navItem->cID : collection id of the page this nav item represents
* $navItem->cObj : collection object of the page this nav item represents (use this if you need to access page properties and attributes that aren't already available in the $navItem object)
*/
/** For extra functionality, you can add the following page attributes to your site (via Dashboard > Pages & Themes > Attributes):
*
* 1) Handle: exclude_nav
* (This is the "Exclude From Nav" attribute that comes pre-installed with concrete5, so you do not need to add it yourself.)
* Functionality: If a page has this checked, it will not be included in the nav menu (and neither will its children / sub-pages).
*
* 2) Handle: exclude_subpages_from_nav
* Type: Checkbox
* Functionality: If a page has this checked, all of that pages children (sub-pages) will be excluded from the nav menu (but the page itself will be included).
*
* 3) Handle: replace_link_with_first_in_nav
* Type: Checkbox
* Functionality: If a page has this checked, clicking on it in the nav menu will go to its first child (sub-page) instead.
*
* 4) Handle: nav_item_class
* Type: Text
* Functionality: Whatever is entered into this textbox will be outputted as an additional CSS class for that page's nav item (NOTE: you must un-comment the "$ni->attrClass" code block in the CSS section below for this to work).
*/
/*** STEP 1 of 2: Determine all CSS classes (only 2 are enabled by default, but you can un-comment other ones or add your own) ***/
foreach ($navItems as $ni) {
$classes = array();
if ($ni->isCurrent) {
//class for the page currently being viewed
$classes[] = 'nav-selected';
}
if ($ni->inPath) {
//class for parent items of the page currently being viewed
$classes[] = 'nav-path-selected';
}
/*
if ($ni->isFirst) {
//class for the first item in each menu section (first top-level item, and first item of each dropdown sub-menu)
$classes[] = 'nav-first';
}
*/
/*
if ($ni->isLast) {
//class for the last item in each menu section (last top-level item, and last item of each dropdown sub-menu)
$classes[] = 'nav-last';
}
*/
if ($ni->hasSubmenu) {
//class for items that have dropdown sub-menus
$classes[] = 'parent';
}
/*
if (!empty($ni->attrClass)) {
//class that can be set by end-user via the 'nav_item_class' custom page attribute
$classes[] = $ni->attrClass;
}
*/
/*
if ($ni->isHome) {
//home page
$classes[] = 'nav-home';
}
*/
/*
//unique class for every single menu item
$classes[] = 'nav-item-' . $ni->cID;
*/
//Put all classes together into one space-separated string
$ni->classes = implode(" ", $classes);
}
//*** Step 2 of 2: Output menu HTML ***/
echo '<div id="menu">';
echo '<ul class="nav menu">'; //opens the top-level menu
foreach ($navItems as $ni) {
echo '<li class="' . $ni->classes . '">'; //opens a nav item
echo '<a href="' . $ni->url . '" target="' . $ni->target . '" class="' . $ni->classes . '">' . $ni->name . '</a>';
if ($ni->hasSubmenu) {
echo '<ul>'; //opens a dropdown sub-menu
} else {
echo '</li>'; //closes a nav item
echo str_repeat('</ul></li>', $ni->subDepth); //closes dropdown sub-menu(s) and their top-level nav item(s)
}
}
echo '</ul>'; //closes the top-level menu
echo '</div>'; //closes the top-level menu-container
我建议只添加一个特殊配置来修改自动导航菜单的链接,如下所示:
$navItems = $controller->getNavItems();
$special_config = array(
"www.website.com/turkey" /* url */=> array( "level" => 2 ),
"www.website.com/greece" /* url */=> array( "level" => 2 )
// .. rest special config here
);
foreach ($navItems as &$navItem)
{
if ( isset($special_config[$navItem->url]) )
{
foreach ($special_config[$navItem->url] as $k=>$v)
{
// adjust navItem params as needed here by key=>value
$navItem->{$k} = $v;
}
}
}
// rest code follows
// ...
您甚至可以像这样创建函数 ammend_nav_menu
:
function ammend_nav_menu($special_config, &$navItems)
{
foreach ($navItems as &$navItem)
{
if ( isset($special_config[$navItem->url]) )
{
foreach ($special_config[$navItem->url] as $k=>$v)
{
// adjust navItem params as needed here by key=>value
$navItem->{$k} = $v;
}
}
}
}
并这样使用:
$navItems = $controller->getNavItems();
ammend_nav_menu(array(
"www.website.com/turkey" /* url */=> array( "level" => 2 ),
"www.website.com/greece" /* url */=> array( "level" => 2 )
// .. rest special config here
), $navItems);
修改菜单的特殊配置甚至可以放在单独的 php 文件中并根据需要加载/更新