让孩子进入控制器内以显示在树枝模板上

时间:2013-09-30 14:15:56

标签: symfony doctrine twig hierarchy

我正在尝试构建一个页面,该页面收集网站上的所有页面并与他们的孩子一起显示(如果有的话)。

到目前为止,我已经设法让它遍历所有顶级页面并显示它们,但是我在使它在正确的位置显示子页面时遇到了一些困难。似乎我可以检索它们但是它们最终出现或者根本没有检索它们。

我需要它看起来像这样:

<div id="parent" class="guide-item">
    <h2>Parent</h2>
    <p>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.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
    <div id="child" class="guide-item">
        <h2>Child</h2>
        <p>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.</p><p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</p>
    </div>
</div>

这是我的控制器(包括我尝试让它循环遍历孩子们:

// Render pages from database
public function sectorAction($sector)
{
    $em = $this->getDoctrine()->getManager();
    $pages = $this->getDoctrine()
    ->getRepository('acmeStyleGuideBundle:pageSector')
    ->findBySectorJoinedToUrlTopLevel($sector);

    if (!$pages) throw $this->createNotFoundException('Unable to find any matching sectors');

    foreach ($pages as $page) {
        if ($page->getChildPages()) {
            $children = $this->getDoctrine()
                ->getRepository('acmeStyleGuideBundle:pageContent')
                ->findBySectorAndParent($sector, $page->getPageUrl());
        }
    }

    return $this->render(
        'acmeStyleGuideBundle:Page:pages.html.twig', 
        array(
            'Pages' => $pages,
            'Children' => $children,
            'header' => $sector
        )
    );
}

以下是相关存储库:

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

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

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

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

这是我的twig模板,我想输出代码:

{% extends 'acmeStyleGuideBundle::landing.html.twig' %}
{% block definition %}
    <article class="js-load pageLoad">
        <h1>
            {% if header is defined %}
                {{ header | title }}
            {% else %}
                {{ Pages[0].pageName }}
            {% endif %}
        </h1>
        {% for pe in Pages %}
            <div id="{{ pe.pageUrl | lower}}" class="guide-item">
                <h2>{{ pe.pageName }}</h2>
                {{ pe.richText | raw }}
            </div>
        {% endfor %}
    </article>
{% endblock %}

我认为我可能已经能够在控制器中循环遍历子项,然后将其作为“子项”而不是“页面”应用于树枝模板,但这似乎不能像下面的代码一样重复数据库中的最后一个元素,它不是子页面。:

{% for ce in Children %}
    <div class="childPage">
        <div id="{{ ce.pageUrl | lower}}" class="guide-item">
            <h2>{{ ce.pageName }}</h2>
            {{ ce.richText | raw }}
            <div class="explanation">
                <div class="card active">
                    <h3>Example</h3>
                    {# ce.example | raw#}
                </div>
                <div class="card">
                    <h3>Code Example</h3>
                    <pre name="code" class="{#ce.lang#}">{# ce.example #}</pre>
                </div>
            </div>
        </div>
    </div>
{% endfor %}

我一直在看这个问题已经有一段时间了,所以我可能再也看不到树木了,所以我可以随意把我的代码拉成碎片。无论如何,我是symfony / twig / doctrine的学习者,所以我很乐意接受你关心给我的任何反馈。

1 个答案:

答案 0 :(得分:0)

我设法找到了解决方案。

我没有尝试在一个控制器和模板中执行所有操作,而是创建了一个名为childpages.html.twig的新模板并输入以下代码:

{% for pe in Pages %}
        <div id="{{ pe.pageUrl | lower}}" class="guide-item child">
            <h2>{{ pe.pageName }}</h2>
            {{ pe.richText | raw }}
            {{ render(controller('acmeStyleGuideBundle:Page:findCodeExamples', { 'pageParent': pe.codeExample })) }}
        </div>
{% endfor %}
然后我写了一个新的控制器:

    // Render children from database (Similar to showSubAction but without the $pageUrl requirement)
    public function findChildrenAction($pageParent, $sector)
    {
        $em = $this->getDoctrine()->getManager();
        $pages = $this->getDoctrine()
        ->getRepository('acmeStyleGuideBundle:PageSector')
        ->findBySectorJoinedToParent($sector, $pageParent);
        return $this->render(
            'acmeStyleGuideBundle:Page:childPages.html.twig', 
            array(
                'Pages' => $pages,
                'sector' => $sector
            )
        );
    }

并在我需要它出现在原始模板中的地方引用它:

{{ 
    render(controller('acmeStyleGuideBundle:Page:findChildren', { 
        'pageParent': pe.id, 
        'sector': 'residential'
    }))
}}

不确定它是否是最优雅的解决方案,但它确实有效。