【问题标题】:Nested dynamic menu with knpmenubundle带有 knpmenubundle 的嵌套动态菜单
【发布时间】:2013-09-23 09:20:20
【问题描述】:

我使用 knpmenubundle 构建了一个菜单,它工作得非常好,并且可以从数据库中动态提取导航。然而,客户现在想向它添加一个子菜单。我编写了一个控制器来查找子页面,但是我看不到如何将它们附加到正确父页面下的子导航。目前它所做的一切是将当前元素的副本作为子节点附加到自身。

这里是菜单生成器:

 $sector = $options['sector'];
    $em = $this->getDoctrine()->getManager();
    $navItems = $this->getDoctrine()
    ->getRepository('acmeStyleGuideBundle:pageSector')
    ->findBySectorJoinedToUrl($sector);
    if (!$navItems) throw $this->createNotFoundException('Unable to find any matching pages');
    $menu = $factory->createItem('root');
    foreach ($navItems as $nav)
    {
        // Doesn't have any parents, This is a top level
        $parent = $menu->addChild($nav->getPageName(), array(
            'route' => 'acme_style_guide_pages_show',
            'routeParameters' => array(
                'sector' => $sector,
                'pageUrl' => $nav->getPageUrl()
            )
        ));
        $parent->addChild($nav->getPageName(), array(
            'route' => 'acme_style_guide_pages_show_sub',
            'routeParameters' => array(
                'sector' => $sector,
                'pageParent' => $nav->getPageName(),
                'pageUrl' => $nav->getPageUrl()
            ))
        );
    }

这是父元素的控制器:

 // Render pages from database
public function showAction($sector, $pageUrl)
{
    $em = $this->getDoctrine()->getManager();
    $pages = $this->getDoctrine()
    ->getRepository('acmeStyleGuideBundle:PageContent')
    ->findByUrlJoinedToSector($sector, $pageUrl);

    if (!$pages) throw $this->createNotFoundException('Unable to find any matching pages');
    return $this->render(
        'acmeStyleGuideBundle:Page:pages.html.twig', 
        array(
            'Pages' => $pages,
            'sector' => $sector
        )
    );
}

这是子元素的控制器:

// Render sub pages from database
public function showSubAction($sector, $pageParent, $pageUrl)
{
    $em = $this->getDoctrine()->getManager();
    $pages = $this->getDoctrine()
    ->getRepository('acmeStyleGuideBundle:PageContent')
    ->findByUrlJoinedToSectorAndParent($sector, $pageParent, $pageUrl);

    if (!$pages) throw $this->createNotFoundException('Unable to find any matching pages');
    return $this->render(
        'acmeStyleGuideBundle:Page:pages.html.twig', 
        array(
            'Pages' => $pages,
            'sector' => $sector
        )
    );
}

这两个控制器都使用自定义存储库类从数据库中提取信息。

这是自定义存储库代码:

public function findByUrlJoinedToSector($sector, $pageUrl)
{
    $query = $this->getEntityManager()
        ->createQuery('
            SELECT p, s FROM acmeStyleGuideBundle:PageContent p
            JOIN p.pageSector s
            LEFT JOIN p.pageTypes t
            WHERE p.pageUrl = :url
            AND s.sectorName = :sector
            AND t.typeName != :type'
        )
        ->setParameter('url', $pageUrl)
        ->setParameter('sector', $sector)
        ->setParameter('type', 'Section Headers');

    try {
        return $query->getResult();
    } catch (\Doctrine\ORM\NoResultException $e) {
        return null;
    }
}

public function findByUrlJoinedToSectorAndParent($sector, $pageParent, $pageUrl)
{
    $query = $this->getEntityManager()
        ->createQuery('
            SELECT p, s, c FROM acmeStyleGuideBundle:PageContent p
            JOIN p.pageSector s
            LEFT JOIN p.pageTypes t
            LEFT JOIN p.PageParent c
            WHERE p.pageUrl = :url
            AND s.sectorName = :sector
            AND c.pageUrl = :parent
            AND t.typeName != :type'
        )
        ->setParameter('url', $pageUrl)
        ->setParameter('sector', $sector)
        ->setParameter('parent', $pageParent)
        ->setParameter('type', 'Section Headers');

    try {
        return $query->getResult();
    } catch (\Doctrine\ORM\NoResultException $e) {
        return null;
    }
}

这可能只是星期一早上的问题,所以我会继续自己解决问题,如果我这样做了,我会在此处发布作为答案。

其他信息

更新的构建器 // 找到所有有父母的项目。然后将找到的项目附加到其父项。 $subNavItems = $this->getDoctrine() ->getRepository('acmeStyleGuideBundle:pageSector') ->findSubNav($sector, $nav->getPageParent());

        // loop over them and add a link for each one:
        foreach ($subNavItems as $child) {
            if ($child->getPageParent() != NULL) {
                $parent->addChild($child->getPageName(), array(
                    'route' => 'acme_style_guide_pages_show_sub',
                    'routeParameters' => array(
                        'sector' => $sector,
                        'pageParent' => $child->getPageName(),
                        'pageUrl' => $child->getPageUrl()
                        )
                    )
                );
            }
        }
    }

正在输出:

<ul>
    <li><a href="link">Target Item</a></li>
    <li><a href="link">Item</a></li>
    <li><a href="link">Item</a></li>
    <li><a href="link">Child</a>
        <ul>
            <li><a href="link">Child</a></li>
        </ul>
    </li>
</ul>

而我需要它来输出:

<ul>
    <li><a href="link">Target Item</a>
        <ul>
            <li><a href="link">Child</a></li>
        </ul>
    </li>
    <li><a href="link">Item</a></li>
    <li><a href="link">Item</a></li>
    <li><a href="link">Child</a></li>
</ul>

这是 PageContent 表的架构

<database name="styleguide">
        <!-- Table PageContent -->
        <table name="PageContent">
            <column name="id">1</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Text Elements</column>
            <column name="pageUrl">text-elements</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">2</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Buttons</column>
            <column name="pageUrl">buttons</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">3</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Forms</column>
            <column name="pageUrl">forms</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">4</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Lists</column>
            <column name="pageUrl">lists</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">5</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Tables</column>
            <column name="pageUrl">tables</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">6</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Search Box</column>
            <column name="pageUrl">search-box</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">7</column>
            <column name="pageTypesId">2</column>
            <column name="pageName">Pods</column>
            <column name="pageUrl">pods</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">8</column>
            <column name="pageTypesId">3</column>
            <column name="pageName">Business</column>
            <column name="pageUrl">business</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">9</column>
            <column name="pageTypesId">3</column>
            <column name="pageName">Residential</column>
            <column name="pageUrl">residential</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">NULL</column>
        </table>
        <table name="PageContent">
            <column name="id">10</column>
            <column name="pageTypesId">1</column>
            <column name="pageName">Paragraphs</column>
            <column name="pageUrl">paragraphs</column>
            <column name="richText">&lt;p&gt;Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.&lt;/p&gt;&lt;p&gt;Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.&lt;/p&gt;</column>
            <column name="PageParent">1</column>
        </table>
    </database>

【问题讨论】:

  • 您的query 或您的数据库有错误。你的代码是正确的。我猜child 项目链接到数据库中的错误父项。
  • 我认为这可能是因为我的数据布局方式(添加了表模式的 XML 来质疑)。而不是以一对多关系包含一组孩子的父母。我试图对包含对它的父级的引用的子级进行一对一的关系。这似乎是最明智的做法,但看起来它可能会导致问题。你认为围绕这​​个编写代码会很容易还是我应该改变我的数据库结构?

标签: symfony doctrine knpmenubundle knpmenu


【解决方案1】:

您需要遍历所有subElements 并为每个@ 渲染一个导航链接:

foreach ($navItems as $nav)
{
    // Doesn't have any parents, This is a top level
    $parent = $menu->addChild($nav->getPageName(), array(
        'route' => 'acme_style_guide_pages_show',
        'routeParameters' => array(
            'sector' => $sector,
            'pageUrl' => $nav->getPageUrl()
        )
    ));

    // find all sub-items:
    $subNavItems = $this->getDoctrine()
    ->getRepository('acmeStyleGuideBundle:pageSector')
    ->findByUrlJoinedToSectorAndParent($sector, $parent, /* $pageUrl */);

    // loop over them and add a link for each one:
    foreach ($subNavItems as $child) {
        $parent->addChild($child->getPageName(), array(
            'route' => 'acme_style_guide_pages_show_sub',
            'routeParameters' => array(
                'sector' => $sector,
                'pageParent' => $child->getPageName(),
                'pageUrl' => $child->getPageUrl()
            ))
        );
    }
}

【讨论】:

  • 效果很好。我不得不为它创建一个自定义存储库方法,因为“findByUrlJoinedToSectorAndParent()”这个方法并不合适。谢谢! :)
  • 您只需要记住子元素与根元素没有什么不同。如果您牢记这一点,knpMenus 真的很容易创建。
  • 其实。我刚刚注意到它仍然没有按我预期的方式工作。它只输出现在有父母的项目,但它仍然把项目的副本放在自己下面。我已将新输出放在我的问题中。
  • 您能否更新您的问题以添加输出html 和您当前的menu builder
  • 您需要将信息添加到您的问题中,而不是我的答案中。另请提供树枝模板代码。
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-25
  • 2010-11-04
相关资源
最近更新 更多