将路径数组转换为 UL 列表 [英] Convert array of paths into UL list

查看:26
本文介绍了将路径数组转换为 UL 列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在数据库中有一个表,其中包含指向我网站页面的各种路径.每条路径只列出一次.我目前有一个非常长且复杂的查询系列和 PHP 来提取所有这些并将数据重写为无序列表(为我的网站创建一个菜单).似乎可能有一种相对简单的循环方法可以更有效地工作,但我似乎无法让任何工作正常工作.我发现了大量从文件树创建 UL 列表的 PHP 脚本,但它们要么不起作用,要么无法处理查询结果的固有非递归性质(有些需要我的路径的多维数组,这除了我在创建这些时遇到的麻烦之外,一切都很好).我确实找到了一个非常接近的脚本,但是它通过将子列表放在

  • 部分之外来错误地格式化
      部分(我会下面解释)

      I have a table in a database that contains a variety of paths to pages of my website. Each path is listed only one time. I currently have a very long and convoluted series of queries and PHP to pull all these and rewrite the data into an unordered list (to create a menu for my website). It seems that there is probably a relatively simple looping approach that would work MUCH more efficiently, but I cannot seem to get anything working. I have found TONS of PHP scripts that create UL lists from file trees, but all of them either don't work or can't handle the inherently not recursive nature of my query results (some require multi-dimensional arrays of my paths, which would be fine except for my trouble with creating those). I did find a script that works pretty close, but it formats the <ul> portion incorrectly by placing sub-lists outside of the <li> section (I will explain below)

      这是一个示例:

      DB 在结果数组中返回以下内容:

      DB returns the following in results array:

      about/contact/
      about/contact/form/
      about/history/
      about/staff/
      about/staff/bobjones/
      about/staff/sallymae/
      products/
      products/gifts/
      products/widgets/
      

      我想创建以下输出:

      <ul>
        <li>about/
        <ul>
          <li>about/contact/
          <ul>
            <li>about/contact/form/</li>
          </ul>
          </li>
          <li>about/history/</li>
          <li>about/staff/
          <ul>
            <li>about/staff/bobjones/</li>
            <li>about/staff/sallymae/</li>
          </ul>
          </li>
        </ul>
        </li>
        <li>products/
        <ul>
          <li>products/gifts/</li>
          <li>products/widgets/</li>
        </ul>
        </li>
      </ul>
      

      所以我非常接近这里找到的脚本:http://www.daniweb.com/forums/thread285916.html 但我遇到了一个问题.事实证明,我发现的脚本创建了格式不正确的 UL 列表.在正确的情况下,子列表包含在父元素的

    • 中.在此脚本中,父
    • 关闭,然后插入
        块.整个脚本在跟上关卡等方面实际上相当优雅,但我无法完全解决它以找出如何修复它.我在这里有一个函数:

        So I got very close with a script found here: http://www.daniweb.com/forums/thread285916.html but I have run into a problem. It turns out that the script that I found creates improperly formatted UL lists. In a CORRECT situation, a sub-list is contained within the <li> of the parent element. In this scripting, the parent <li> is closed and then a <ul> block is inserted. The overall script is actually fairly elegant in the way that it keeps up with the levels and such, but I cannot wrap my head around it enough to figure out how to fix it. I have the whole thing in a function here:

        function generateMainMenu()
        {
          global $db;
        
          $MenuListOutput = '';
          $PathsArray = array();
        
          $sql = "SELECT PageUrlName FROM `table`";
          $result = mysql_query($sql, $db) or die('MySQL error: ' . mysql_error());
          while ($PageDataArray = mysql_fetch_array($result))
          {
            $PathsArray[] = rtrim($PageDataArray['PageUrlName'],"/"); //this function does not like paths to end in a slash, so remove trailing slash before saving to array
          }
        
          sort($PathsArray);// These need to be sorted.
          $MenuListOutput .= '<ul id="nav">'."
        ";//get things started off right
          $directories=array ();
          $topmark=0;
          $submenu=0;
          foreach ($PathsArray as $value) {
            // break up each path into it's constituent directories
            $limb=explode("/",$value);
            for($i=0;$i<count($limb);$i++) {
              if ($i+1==count($limb)){
                // It's the 'Leaf' of the tree, so it needs a link
                if ($topmark>$i){
                  // the previous path had more directories, therefore more Unordered Lists.
                  $MenuListOutput .= str_repeat("</ul>",$topmark-$i); // Close off the Unordered Lists
                  $MenuListOutput .= "
        ";// For neatness
                }
                $MenuListOutput .= '<li><a href="/'.$value.'">'.$limb[$i]."</a></li>
        ";// Print the Leaf link
                $topmark=$i;// Establish the number of directories in this path
              }else{
                // It's a directory
                if($directories[$i]!=$limb[$i]){
                  // If the directory is the same as the previous path we are not interested.
                  if ($topmark>$i){// the previous path had more directories, therefore more Unordered Lists.
                    $MenuListOutput .= str_repeat("</ul>",$topmark-$i);// Close off the Unordered Lists
                    $MenuListOutput .= "
        ";// For neatness
                  }
        
                  // (next line replaced to avoid duplicate listing of each parent)
                  //$MenuListOutput .= "<li>".$limb[$i]."</li>
        <ul>
        ";
                  $MenuListOutput .= "<ul>
        ";
                  $submenu++;// Increment the dropdown.
                  $directories[$i]=$limb[$i];// Mark it so that if the next path's directory in a similar position is the same, it won't be processed.
                }
              }
            }
          }
          $MenuListOutput .= str_repeat("</ul>",$topmark+1);// Close off the Unordered Lists
        
          return $MenuListOutput."
        
        
        ";
        }
        

        它返回如下内容:

        <ul id="nav">
        <li><a href="/about">about</a></li>
        <ul>
        <li><a href="/about/history">history</a></li>
        <li><a href="/about/job-opportunities">job-opportunities</a></li>
        <li><a href="/about/mission">mission</a></li>
        <li><a href="/about/privacy-policy">privacy-policy</a></li>
        </ul>
        <li><a href="/giftcards">giftcards</a></li>
        <li><a href="/locations">locations</a></li>
        <ul>
        <li><a href="/locations/main-office">main-office</a></li>
        <li><a href="/locations/branch-office">branch-office</a></li>
        </ul>
        <li><a href="/packages">packages</a></li>
        </ul>
        

        任何人都知道我需要在何处添加一些额外的逻辑以及如何实现这一点?关于更好的方法的其他想法?似乎这是一个如此普遍的问题,以至于会有一种简单/标准的方法来处理这样的事情.也许如果我能弄清楚如何从我的路径中创建一个多维数组,那么可以迭代这些数组来完成这项工作?

        Anyone have an idea of where I need to add in some additional logic and how I can accomplish this? Other ideas on a better way to do this? It seems like this is such a common issue that there would be a simple/standard method of handling something like this. Maybe if I could figure out how to create a multi-dimensional array from my paths then those could be iterated to make this work?

        更复杂:-(

        我尝试了 casablanca 的响应,它工作得很好......但我意识到现在我有一个后续行动让事情变得更加困难.为了显示页面的名称",我还需要在数组中包含该信息,因此路径可能更适合作为数组键和值中的名称.关于像这样改变的任何想法:

        I tried casablanca's response and it worked perfectly...except I then realized that now I have a follow-up to make things more difficult. In order to display the "name" of the page, I need to also have that info in the array, thus the path probably works better as the array key and the name in the value. Any thoughts on changing like this:

        $paths = array(
            "about/contact/ " => "Contact Us", 
            "about/contact/form/ " => "Contact Form",
            "about/history/ " => "Our History",
            "about/staff/ " => "Our Staff",
            "about/staff/bobjones/ " => "Bob",
            "about/staff/sallymae/ " => "Sally",
            "products/ " => "All Products",
            "products/gifts/ " => "Gift Ideas!",
            "products/widgets/ " => "Widgets"
        );
        

        然后在 buildUL 函数中使用类似这一行的内容:

        and then using something like this line within the buildUL function:

        echo '<a href="'.$prefix.$key.'/">'.$paths[$prefix.$key].'</a>';
        

        推荐答案

        已更改以适应更新的问题.

        Changed to cater for updated question.

        我使用 __title 的数组索引来保存页面标题.只要你的树中从来没有一个名为 __title 的目录,这应该没问题.您可以随意将此标记值更改为您希望的任何值.

        I'm using an array index of __title to hold the page title. As long as you never have a directory in your tree called __title this should be fine. You're free to change this sentinel value to anything you wish however.

        我还对其进行了更改,以便列表构建函数返回一个字符串,以便您可以存储该值以供稍后在页面中使用.(你当然可以直接执行 echo build_list(build_tree($paths)) 直接输出列表.

        I have also changed it so the list building function returns a string, so that you can store the value for use later in your page. (You can of course just do echo build_list(build_tree($paths)) to output the list directly.

        <?php
        
        $paths = array(
            'about/contact/' => 'Contact Us', 
            'about/contact/form/' => 'Contact Form',
            'about/history/' => 'Our History',
            'about/staff/' => 'Our Staff',
            'about/staff/bobjones/' => 'Bob',
            'about/staff/sallymae/' => 'Sally',
            'products/' => 'All Products',
            'products/gifts/' => 'Gift Ideas!',
            'products/widgets/' => 'Widgets'
        );
        
        function build_tree($path_list) {
            $path_tree = array();
            foreach ($path_list as $path => $title) {
                $list = explode('/', trim($path, '/'));
                $last_dir = &$path_tree;
                foreach ($list as $dir) {
                    $last_dir =& $last_dir[$dir];
                }
                $last_dir['__title'] = $title;
            }
            return $path_tree;
        }
        
        function build_list($tree, $prefix = '') {
            $ul = '';
            foreach ($tree as $key => $value) {
                $li = '';
                if (is_array($value)) {
                    if (array_key_exists('__title', $value)) {
                        $li .= "$prefix$key/ <a href="/$prefix$key/">${value['__title']}</a>";
                    } else {
                        $li .= "$prefix$key/";
                    }
                    $li .= build_list($value, "$prefix$key/");
                    $ul .= strlen($li) ? "<li>$li</li>" : '';
                }
            }
            return strlen($ul) ? "<ul>$ul</ul>" : '';
        }
        
        $tree = build_tree($paths);
        $list = build_list($tree);
        echo $list;
        
        ?>
        

        这篇关于将路径数组转换为 UL 列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆