Выпадающее меню CSS через PHP, логика побеждает меня
Похоже, сегодня утром мой мозг не хочет работать.. у меня есть следующий массив:
private $nav_pages = [['0', 'Home', 'home'],
['0', 'About Us', 'about'],
['0', 'Our Services', 'services'],
['1', 'PROCURE TO PAY (P2P)', 'procure'],
['1', 'ORDER TO CASH (02C)', 'cash'],
['1', 'GENERAL ACCOUNTING', 'general'],
['2', 'Charting of Accounts', 'charting'],
['2', 'General Ledger Maintenance', 'maintenance'],
['2', 'Accounts Receivable Services', 'receivable'],
['2', 'Accounts Payable Services', 'payable'],
['2', 'Reconciliation of Bank Accounts and Credit Cards', 'reconciliation'],
['2', 'Preparing Financial Statements', 'statements'],
['2', 'Payroll Processing', 'payroll'],
['1', 'CLOSING & REPORTING', 'closing'],
['0', 'How It Works', 'how-it-works'],
['0', 'Contact Us','contact'],
['0', 'Careers', 'careers']];
Затем это передается на страницу php, которая предназначена для размещения многоуровневого выпадающего меню чистого css.. код страницы php выглядит следующим образом:
<ul class="<?php echo $ul_class; ?>">
<?php $this_layer = 0;
// place array content into variables
foreach ($links as $link) {
$item_layer = $link[0];
$item_string = $link[1];
$item_link = $link[2];
if ($item_layer > $this_layer) { ?>
<ul>
<?php $this_layer++; }
elseif ($item_layer == $this_layer) { ?>
<li class="<?php echo $item_link; ?>">
<a class="<?php echo $item_link; ?>"
href="/<?php echo $item_link; ?>">
<?php echo $item_string; ?>
</a>
</li>
<?php }
elseif ($item_layer < $this_layer) { ?>
</li></ul>
<?php $this_layer--; } ?>
<?php } ?>
Вывод неверен, однако, поскольку приведенный выше код всегда закрывает элемент списка, содержащий второй слой, до того, как второй слой будет готов к закрытию. если в этом есть смысл..
<ul class="pages_nav">
<li class="home">
<a class="home"
href="/home">
Home
</a>
</li>
<li class="about">
<a class="about"
href="/about">
About Us
</a>
</li>
<li class="services">
<a class="services"
href="/services">
Our Services
</a>
</li>
<ul>
<li class="cash">
<a class="cash"
href="/cash">
ORDER TO CASH (02C)
</a>
</li>
<li class="general">
<a class="general"
href="/general">
GENERAL ACCOUNTING
</a>
</li>
<ul>
<li class="maintenance">
<a class="maintenance"
href="/maintenance">
General Ledger Maintenance
</a>
</li>
<li class="receivable">
<a class="receivable"
href="/receivable">
Accounts Receivable Services
</a>
</li>
<li class="payable">
<a class="payable"
href="/payable">
Accounts Payable Services
</a>
</li>
<li class="reconciliation">
<a class="reconciliation"
href="/reconciliation">
Reconciliation of Bank Accounts and Credit Cards
</a>
</li>
<li class="statements">
<a class="statements"
href="/statements">
Preparing Financial Statements
</a>
</li>
<li class="payroll">
<a class="payroll"
href="/payroll">
Payroll Processing
</a>
</li>
</li></ul>
</li></ul>
<li class="contact">
<a class="contact"
href="/contact">
Contact Us
</a>
</li>
<li class="careers">
<a class="careers"
href="/careers">
Careers
</a>
</li>
РЕШЕНИЕ:
<ul class="<?php echo $ul_class; ?>">
<?php $this_layer = 0;
// place array content into variables
foreach ($links as $link) {
$item_layer = $link[0];
$item_string = $link[1];
$item_link = $link[2];
// check if link needs to be manipulated
switch($do) {
case 'strtolower':
$item_string = strtolower($item_string);
break;
case 'strtoupper':
$item_string = strtoupper($item_string);
break;
} ?>
<?php if ($item_layer > $this_layer) { ?>
<ul>
<li class="<?php echo $item_link; ?>">
<a class="<?php echo $item_link; ?>"
href="/<?php echo $item_link; ?>">
<?php echo $item_string; ?>
</a>
<?php $this_layer++; }
elseif ($item_layer == $this_layer) { ?>
</li><li class="<?php echo $item_link; ?>">
<a class="<?php echo $item_link; ?>"
href="/<?php echo $item_link; ?>">
<?php echo $item_string; ?>
</a>
<?php }
elseif ($item_layer < $this_layer) { ?>
</li></ul></li><li class="<?php echo $item_link; ?>">
<a class="<?php echo $item_link; ?>"
href="/<?php echo $item_link; ?>">
<?php echo $item_string; ?>
</a>
<?php $this_layer--; } ?>
<?php } ?>
2 answers
Никогда не закрывайте тег li, закрывайте его, когда вы что-то добавляете
foreach ($links as $link) {
if ($item_layer > $this_layer) {
echo '<ul><li> ......';
this_layer++;
}elseif ($item_layer == $this_layer) {
echo '</li><li>......';
}elseif ($item_layer < $this_layer) {
echo '</li></ul><li>......';
$this_layer--;
}
}
Последнее, вам, вероятно, нужно добавить echo '</li></ul>'
за пределами foreach, чтобы закрыть все
Пришлось немного переработать код, обычно я упорядочиваю структуру меню php в виде дерева, что облегчает синтаксический анализ в html-меню, но вот оно:
<ul class="<?php echo $ul_class; ?>">
<?php
$this_layer = 0;
$closeit = false;
// place array content into variables
foreach ($nav_pages as $link) {
$item_layer = $link[0];
$item_string = $link[1];
$item_link = $link[2];
if ($item_layer > $this_layer) {
// Changing level, dont close the previous li
?><ul><?php
$closeit = false;
$this_layer++;
}
if ($item_layer == $this_layer) {
// Same level, check if you need to close previous li
if ($closeit) {
?></li><?php
}
// Render the li
?>
<li class="<?php echo $item_link; ?>">
<a class="<?php echo $item_link; ?>"
href="/<?php echo $item_link; ?>">
<?php echo $item_string; ?>
</a>
<?php
// Close it on next loop
$closeit = true;
}
elseif ($item_layer < $this_layer) {
// Changing layer back down, close the previous li and the current level ul
?>
</li>
</ul>
<?php
$this_layer--;
}
}
// Finished loop, there should still be a li waiting to be closed
if ($closeit) {
?></li><?php
}
// Close menu
?>
</ul>
Должно работать, дайте мне знать, если это не так
Предлагаемая структура меню php:
$menu = array(
array(
"url"=>"/place.php",
"text"=>"Go to place"
),
array(
"url"=>"/place2.php", // not necessary
"text"=>"with submenu",
"children"=>array(
array(
"url"=>"/placewithinplace2.php",
"text"=>"submenu item"
)
)
)
);