0

I have a model that implements NestedSet behaviour:

Page:
  actAs:
    NestedSet:
      hasManyRoots: true
      rootColumnName: root_id
  columns:
    slug: string(255)
    name: string(255)

Example fixtures:

Page:
  NestedSet: true
  Page_1:
    slug: slug1
    name: name1
  Page_2:
    slug: slug2
    name: name2
    children:
      Page_3:
        slug: page3
        name: name3

I am looking for the easiest way to implement breadcrumb navigation (trail). For example, for Page_3 navigation will look like this:

<a href="page2">name2</a> > <a href="page2/page3>name3</a>
4

3 回答 3

1

因为我讨厌在模板(和部分)中有任何类型的逻辑,所以这是我稍微改进的版本。

//module/templates/_breadcrumbElement.php
<?php foreach ($node as $child): ?>
<li>
  <a href="<?php echo $child->getPath($parent) ?>"><?php echo $child->getName() ?></a>
  <?php if (count($child->get('__children')) > 0): ?>
    <ul>
      <?php include_partial('node', array('node' => $child->get('__children'), 'parent' => $child)) ?>
    </ul>
  <?php endif; ?>
</li>
<?php endforeach; ?>

因此,构建 url 的所有逻辑现在都在 Page::getPath() 方法中。

class Page extends BasePage
{
  /**
   * Full path to node from root
   *
   */
  protected $path = false;

  public function __toString()
  {
    return $this->getSlug();
  }
  public function getPath($parent = null)
  {
    if (!$this->path)
    {
      $this->path = join('/', null !== $parent ? array($parent->getPath(), $this) : array($this));
    }
    return $this->path;
  } 
}

我不喜欢将 $parent 传递给 Page::getPath()。它只是没有任何语义意义。

于 2011-05-15T18:48:22.633 回答
0

几乎与其他问题相同,但您必须添加一个“parentUrl”变量:

//module/templates/_breadcrumbElement.php
foreach ($node->get('__children') as $child) :
  if ($child->isAncestorOf($pageNode)):
     $currentNodeUrl = $parentUrl . $child->getSlug() . '/';
     echo link_to($child->getName(), $currentNodeUrl) . ' > ' ;
     include_partial('module/breadcrumbElement', array('node' => $child, 'pageNode' => $pageNode, 'parentUrl' => $currentNodeUrl));
  endif;
endforeach;

将其作为树的根$node(分层水合),将当前页面的节点作为$pageNode,并将 '' 作为$currentNodeUrl并添加 '>' 和指向当前页面的链接。

为什么这个解决方案使用递归而不是递归getAncestors()?因为您的网址似乎暗示着递归。

于 2011-05-15T15:12:42.750 回答
0

另一个答案,更简单(也许更有效),使用 getAncestors() 和递归:

//module/templates/_breadcrumbElement.php
if ($node = array_pop($nodes)) // stop condition
{
    $currentNodeUrl = $parentUrl . $node->getSlug() . '/';
    echo link_to($node->getName(), $currentNodeUrl) . ' > ' ;
    include_partial('module/breadcrumbElement', array(
      'nodes' => $nodes, 'parentUrl' => $currentNodeUrl));
}

用祖先节点数组调用它,或者Doctrine_Collection如果你想getAncestors()直接使用它,可以找到一种方法来弹出 a。同样,您的所有问题都来自于您的 url 是递归计算的事实,如果您有一个带有当前 url 的列路径(但随后您必须计算、更新它)等,那么显示会更简单、更快。 . 如果您的读取次数多于写入次数(如果您的树不经常更改),请考虑这样做。

于 2011-05-15T15:30:01.080 回答