[Symfony2] Hoe maak ik gebruik van een nested repeater i.c.m. twig (Opgelost)
Martijn2008 - 01/04/2013 21:35
PHP beginner
Hallo allemaal,
Ik heb een controller aangemaakt met de naam overzicht. Het is de bedoeling dat de controller een overzicht gaat tonen van categorieën en pagina's.
Een pagina hoort altijd bij 1 categorie en een categorie heeft 0 of meerdere pagina's in zich.
Het overzicht moet er visueel als volgt uitzien:
Categorie 1
- Pagina 1
- Pagina 4
- Pagina 5
Categorie 2
- Pagina 2
- Pagina 3
Categorie 3
- Pagina 6
Met ASP.net webforms kun je gebruik maken van een nested repeater om dit probleem op te lossen, echter met Symfony2 in combinatie met Twig template engine heb ik geen idee hoe ik dit aan moet pakken.
Iemand een idee voor een goede aanpak?
Alvast bedankt.
Martijn
12 antwoorden
Gesponsorde links
Joost - 01/04/2013 21:54 (laatste wijziging 01/04/2013 21:54)
PHP expert
Ik heb geen verstand van Twig of Symfony maar ik neem aan dat zoiets toch wel moet kunnen:
<ul id="navigation">
{% for item in categories %}
<strong>{{ item.name }}</strong>
{% for it in categories.pages %}
{{ it.name }}
{% endfor %}
{% endfor %}
</ul>
<ul id="navigation">
{% for item in categories %}
<strong>{{ item.name }}</strong>
{% for it in categories.pages %}
{{ it.name }}
{% endfor %}
{% endfor %}
</ul>
Bedankt door: Martijn2008
Martijn2008 - 01/04/2013 21:59
PHP beginner
Ik denk dat je gelijk hebt. Hoe zal de code in de controller er dan uit komen te zien?
Ik heb te doen met twee objecten: Categorie en Pagina.
WouterJ - 01/04/2013 22:34 (laatste wijziging 01/04/2013 22:38)
HTML gevorderde
Goed, je hebt hoop ik een OneToMany relatie tussen Categorie en Pagina?
Dan maak je een PageRepository met een nieuwe method:
// src/Martijn/PageBundle/Entity/PageRepository.php
// ...
class PageRepository extends BaseRepository
{
public function findAllSortedByCategory()
{
$results = $this->getEntityManager()
->createQuery('SELECT ... ORDER BY category')
->getResult();
$pages = array();
foreach ($results as $result) {
$cat = $result->getCategory()->getName();
if (!isset($pages[$cat])) {
$pages[$cat] = array();
}
$pages[$cat][] = $result;
}
return $pages;
}
}
// src/Martijn/PageBundle/Entity/PageRepository.php
// ...
class PageRepository extends BaseRepository
{
public function findAllSortedByCategory( )
{
$results = $this -> getEntityManager ( )
-> createQuery ( 'SELECT ... ORDER BY category' )
-> getResult ( ) ;
foreach ( $results as $result ) {
$cat = $result -> getCategory ( ) -> getName ( ) ;
if ( ! isset ( $pages [ $cat ] ) ) { }
$pages [ $cat ] [ ] = $result ;
}
return $pages ;
}
}
Dan kun je nu de resultaten tonen:
// src/Martijn/PageBundle/Controller/PageController.php
// ...
class PageController extends Controller
{
public function listAction()
{
$repo = $this->getRepository('MartijnPageBundle:Page');
$pages = $repo->findAllSortedByCategory();
return $this->render('MartijnPageBundle:Page:list.html.twig', array(
'pages' => $pages,
));
}
}
// src/Martijn/PageBundle/Controller/PageController.php
// ...
class PageController extends Controller
{
public function listAction( )
{
$repo = $this -> getRepository ( 'MartijnPageBundle:Page' ) ;
$pages = $repo -> findAllSortedByCategory ( ) ;
return $this -> render ( 'MartijnPageBundle:Page:list.html.twig' , array ( 'pages' => $pages ,
) ) ;
}
}
{# src/Martijn/PageBundle/Resources/view/Page/list.html.twig #}
<ul class="page-list">
{% for pages, category in categories -%}
<li><strong>{{ category }}</strong>
<ul>
{% for page in pages -%}
<li><a href={{ page.url }}>{{ page }}</a></li>
{%- endfor %}
</ul>
{%- endfor %}
</ul>
{# src/Martijn/PageBundle/Resources/view/Page/list.html.twig #}
<ul class="page-list">
{% for pages, category in categories -%}
<li><strong>{{ category }}</strong>
<ul>
{% for page in pages -%}
<li><a href={{ page.url }}>{{ page }}</a></li>
{%- endfor %}
</ul>
{%- endfor %}
</ul>
Bedankt door: Martijn2008
Martijn2008 - 01/04/2013 23:15
PHP beginner
Is dit voldoende of moet ik de puntjes vervangen door wat magic??
->createQuery('SELECT ... ORDER BY category')
-> createQuery ( 'SELECT ... ORDER BY category' )
Btw, een categorie heeft ook een kleur, hoe zit dat?
Martijn2008 - 02/04/2013 13:37
PHP beginner
Haha, ik heb op de link die je stuurde een toverdrankje gevonden. In combinatie met je uitleg heb ik nu "de basis" werkend, good job, thanx.
Als ik nou ook nog de categorie kleur erbij wil pakken, dus de categorienaam en kleur. Hoe zit dat in elkaar?
Ik heb nu deze aanpassing daarvoor gemaakt.
foreach ($results as $result) {
$cat = $result->getCategory(); // Verwijderd: ->getName();
if (!isset($pages[$cat])) {
$pages[$cat] = array();
}
$pages[$cat][] = $result;
}
foreach ( $results as $result ) {
$cat = $result -> getCategory ( ) ; // Verwijderd: ->getName();
if ( ! isset ( $pages [ $cat ] ) ) { }
$pages [ $cat ] [ ] = $result ;
}
Dat levert deze foutmelding op:
Warning: Illegal offset type in isset or empty in ....
Warning
: Illegal offset type in
isset or
empty in
....
WouterJ - 02/04/2013 15:11
HTML gevorderde
wat bevat $cat nu? Want nu doe je op regel 3 $pages[$cat], dan moet $cat natuurlijk wel een string zijn!
Martijn2008 - 02/04/2013 15:34 (laatste wijziging 03/04/2013 12:22)
PHP beginner
Category is ook een repository/entity/table. Het bevat verschillende properties: id, name, colour, created_at en ip. Totaal zijn er dus 2 objecten met diverse properties:
- Category: id, name, colour, created_at en ip
- Page: id, title, post, created_at en ip
Ik heb geen idee hoe je dat doet..
WouterJ - 03/04/2013 14:08
HTML gevorderde
- wat doet IP in page en category?
- hoe zijn category en page aan elkaar gelinkt? (zoals ik al zei, heb je een ManyToOne relatie?)
- wat denk je dat er gebeurd als je een object als index in een array gebruikt?
Martijn2008 - 03/04/2013 14:21
PHP beginner
Nice. Ik zal het toelichten. IP wil ik niet expliciet iets mee gaan doen, is meer voor het gemak, mocht er ooit eens iets aan de hand zijn dan kan ik misschien daar iets mee... die hoeft dus niet in de template te worden getoond.
De ralatie ziet er visueel als volgt uit:
[Page] ---(0..N)--- hoort bij ---(1..1)--- [Category]
Een pagina hoort altijd bij 1 categorie en een categorie heeft 0 of meerdere pagina's in zich.
Een object als index gebruiken? Dat gaat toch niet werken, in de index van een object wordt een string of integer verwacht, als ik je post van 02/04/2013 15:11 goed begrijp??
WouterJ - 04/04/2013 23:34
HTML gevorderde
Citaat:
Een object als index gebruiken? Dat gaat toch niet werken, in de index van een object wordt een string of integer verwacht, als ik je post van 02/04/2013 15:11 goed begrijp??
Exact, en kijk nu eens wat jij in je code als index gebruikt?
Martijn2008 - 04/04/2013 23:39
PHP beginner
Een object. Ik heb de code aangepast, maar dit vind Symfony ook niet leuk
public function findAllSortedByCategory()
{
$results = $this->getEntityManager()
->createQuery('SELECT d FROM AcmeCmsBundle:Pages d ORDER BY d.fkCategoryid ASC')
->getResult();
$item = array();
foreach ($results as $result) {
$cat = $result->getFkCategoryid();
$name = $cat->getName();
if (!isset($item[$name])) {
$item[$name] = $cat;
$item[$name]['pages'] = $result;
}
$item[$name]['pages'] = $result;
}
return $item;
}
public function findAllSortedByCategory( )
{
$results = $this -> getEntityManager ( )
-> createQuery ( 'SELECT d FROM AcmeCmsBundle:Pages d ORDER BY d.fkCategoryid ASC' )
-> getResult ( ) ;
foreach ( $results as $result ) {
$cat = $result -> getFkCategoryid ( ) ;
$name = $cat -> getName ( ) ;
if ( ! isset ( $item [ $name ] ) ) { $item [ $name ] = $cat ;
$item [ $name ] [ 'pages' ] = $result ;
}
$item [ $name ] [ 'pages' ] = $result ;
}
return $item ;
}
Gesponsorde links
Je moet ingelogd zijn om een reactie te kunnen posten.