NestedSet - 父/子节点

问题描述:

我目前正在致力于从 Doctrine 中的 NestedSet 输出导航菜单的层次结构.

I am currently working on outputting a heirarchy in terms of a navigation menu from a nestedSet in Doctrine.

我有很多父母,然后有几个孩子.

I have a number of parents that then have several children.

目前只有 2 个级别:父母和孩子(没有孙子孙女).

At the moment in time, there are only 2 levels: Parent and Child (no grandchildren).

我有以下代码:

//actions:
public function executeShow(sfWebRequest $request)
{
  $this->tree = Doctrine::getTable('Model')->getMenuTree();
}

//lib:
class ModelTable extends Doctrine_Table
{
  /**
   * Gets tree element in one query
   */
  public function getMenuTree()
  {

    $q = $this->createQuery('g')
      ->orderBy('g.root_id')
      ->addOrderBy('g.lft')
      ->where('g.root_id NOT NULL');

    return $q->execute(array(),  Doctrine_Core::HYDRATE_ARRAY_HIERARCHY);
  }
}


//template:
<?php function echoNode($tree, $parent=null) { ?>
  <ul>
  <?php foreach ($tree as $node): ?>
    <li data-id='<?php echo $node['id'] ?>'>
      <?php echo $node['name'] ?>
      <?php if (count($node['__children']) > 0): ?>
        <?php echo echoNode($node['__children'], $node) ?>
      <?php endif; ?>
    </li>
  <?php endforeach; ?>       
  </ul>
<?php } ?>
<?php echo echoNode($tree) ?>

结果如下:

Parent Node 1
   Child Node 1
   Child Node 2
Parent Node 2
   Child Node 3

这很棒.

问题是,我希望我的网址与父/子关系相匹配.

The problem is, that I'd like my URLs to match the parent/child relationship.

因此子节点 2 的 URL 将是 /parent-node-1/child-node-2(这些作为 slug 字段).

Thus the URL for Child Node 2, would be /parent-node-1/child-node-2 (these as slug fields).

因此,父节点的任何子节点也需要具有父节点的路由 slug.

So any child of a parent, needs to have the parent node's route slug as well.

我希望这是有道理的?

谢谢

嗯,解决这个问题的一种方法是使用 Doctrine_Core::HYDRATE_RECORD_HIERARCHY hydration,它允许您调用节点上的方法.

Well, one way to hadle this is to use Doctrine_Core::HYDRATE_RECORD_HIERARCHY hydration, which allows you to call methods on your nodes.

现在您可以为节点创建自定义方法:

Now you can create a custom method for a node:

class Model extends BaseModel
{
  public function __toString()
  {
    return $this->getSlug();
  }
  public function getUrl()
  {
    //getPath uses __toString method to render a node
    $url = $this->getNode()->getPath('/', true);
    return $url;
  }
}

并像这样在模板中调用它:

And call it in template like this:

<a href="<?php echo $node->getUrl() ?>"><?php echo $node['name'] ?></a>