Выпадающее меню 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 } ?>

Author: obmon, 2013-02-20

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, чтобы закрыть все

 1
Author: s.lenders, 2013-02-20 11:45:24

Пришлось немного переработать код, обычно я упорядочиваю структуру меню 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"
            )
        )
    )
);
 1
Author: cernunnos, 2013-02-20 12:17:36