带knpmenubundle的嵌套动态菜单

时间:2013-09-23 09:20:21

标签: symfony doctrine knpmenubundle knpmenu

我使用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-&gt; getDoctrine()              - &GT; getRepository( 'acmeStyleGuideBundle:pageSector')              - &gt; findSubNav($ sector,$ nav-&gt; 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>

1 个答案:

答案 0 :(得分:1)

您需要遍历所有subElements并为每个{:p>呈现导航链接

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()
            ))
        );
    }
}