[PHP]Zend_Router mooie, dynamische urls

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • GWTommy
  • Registratie: Mei 2008
  • Laatst online: 05-08-2023
Ik heb Zend_Router nooit echt gebruikt voor het herschrijven van de standaard ZF urls. Echter wil een klant dat ik me richt op mooie urls, dus doen we dat! Zend_Router is erg interessant en biedt vele mogelijkheden. Zo is het me al gelukt om dit te herschrijven:
/model/1/Model-naam/
/model/1/1/Model-naam/categorie/

Zoals jullie misschien al wel door hebben, gaat het om een overzicht van auto onderdelen die voor iedere categorie weergegeven dienen te worden. Gaat allemaal goed, werkt erg mooi. Echter wil ik voor dit overzicht Zend_Paginator gaan toepassen en verschillende filters (sortering, eventueel later nog meer). Hiervoor wil ik de volgende urls gebruiken:
/model/1/1/Model-naam/categorie/sort/price/
/model/1/1/Model-naam/categorie/sort/price/desc/
/model/1/1/Model-naam/categorie/page/2/
/model/1/1/Model-naam/categorie/sort/price/page/2/
/model/1/1/Model-naam/categorie/sort/price/desc/page/2/
etc, jullie snappen 'm?

Met andere woorden, ik wil het laatste deel, de sortering en paginanummer, dynamisch houden.
Daarvoor had ik het volgende bedacht (klein gokje, kon verder hier niets over vinden):
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
resources.router.routes.modelCategory.route = "model/(\d+)/(\d+)/([\w\-]*)/([\w\-]*)(/sort/([\w\-])(/([\w\-]))?)?(/page/(\d+))?"
resources.router.routes.modelCategory.type = "Zend_Controller_Router_Route_Regex" 
resources.router.routes.modelCategory.defaults.module = "default"
resources.router.routes.modelCategory.defaults.controller = "category"
resources.router.routes.modelCategory.defaults.action = "view"
resources.router.routes.modelCategory.map.1 = "modelId"
resources.router.routes.modelCategory.map.2 = "categoryId"
resources.router.routes.modelCategory.map.3 = "model"
resources.router.routes.modelCategory.map.4 = "category"
resources.router.routes.modelCategory.map.5 = "sort"
resources.router.routes.modelCategory.map.6 = "sortMode"
resources.router.routes.modelCategory.map.7 = "page"
resources.router.routes.modelCategory.reverse = "model/%d/%d/%s/%s/sort/%s/%s/page/%d/"

Dit wil niet werken omdat de assembler niet genoeg argumenten mee krijgt om daadwerkelijk een url te bouwen. Iemand een idee hoe ik dit zo op kan bouwen dat wanneer er in de view met $this->url() een url gemaakt wordt voor modelCategory, er een url wordt gemaakt die alleen wanneer nodig bijvoorbeeld het /page/2/ deel er achter plakt?

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Ga niet aan de gang met regex routes :) Dat is complexer en onnodig in jou geval. De router ondersteunt parameters en wildcards. Hierdoor kan je een deel statisch houden, een deel via parameters vullen en het laatste deel als wildcard gebruiken. Parameters van de wildcard komen als /key/value voor in de url.

Voorbeeld:
/model/:category/:model/:modelSlug/:categorySlug/*

Parameters beginnen met een :, de wildcard is *.

Als je de route vult met category=1, model=1, modelSlug=model-naam, category-slug=categorie krijg je deze:
/model/1/1/model-naam/categorie

Met een sort = price:
/model/1/1/model-naam/categorie/sort/price

Met een page = 2:
/model/1/1/model-naam/categorie/page/2

Met een page = 2 en een sort = price:
/model/1/1/model-naam/categorie/page/2/sort/price

Met een page = 2 en een sort = price en een direction = desc:
/model/1/1/model-naam/categorie/page/2/sort/price/direction/desc


Zo kan je volgens mij alles vullen wat je nodig hebt.

Acties:
  • 0 Henk 'm!

  • GWTommy
  • Registratie: Mei 2008
  • Laatst online: 05-08-2023
Kijk!!! Waarom staat dit niet in de docs (of waarom heb ik dit niet gezien)?

Dit is inderdaad een heel stuk minder complex. Echter rest mij de vraag nog, als dit mogelijk is, waarom bestaat Route_Regex dan nog? Dat is in mijn ogen nergens meer voor nodig..

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
GWTommy schreef op donderdag 17 mei 2012 @ 12:09:
Kijk!!! Waarom staat dit niet in de docs (of waarom heb ik dit niet gezien)?
Het is de standard route: http://framework.zend.com...er.router.routes.standard :)
Dit is inderdaad een heel stuk minder complex. Echter rest mij de vraag nog, als dit mogelijk is, waarom bestaat Route_Regex dan nog? Dat is in mijn ogen nergens meer voor nodig..
Regex is ook meestal onnodig. Het kan handig zijn, als je complexe gevallen hebt of veel controle wilt. Van de manual:
This route offers more power and flexibility over the others, but at a slight cost of complexity. At the same time, it should be faster than the standard Route.
Een nadeel is dat regex lastig te begrijpen is en dus te onderhouden. Als je net als een regex een constraint wilt op een route part (bijvoorbeeld :model moet een digit zijn) kan je ook variables array gebruiken: http://framework.zend.com...ard.variable-requirements

Acties:
  • 0 Henk 'm!

  • GWTommy
  • Registratie: Mei 2008
  • Laatst online: 05-08-2023
Mithras, enorm bedankt. Het werkt echt fantastisch!

Nou ben ik in mijn view bezig. Ik wil dat de huidige url wordt gepakt (dus met de parameters die voor de wildcard zijn ingevuld, welke wat ook mogen zijn) en dat er urls worden gemaakt waarbij een extra parameter is ingevuld of wanneer de parameter al in ingevuld bij de huidige url deze wordt overschreven. Voor sommige urls kan zelfs een parameter die bij de huidige url wel is ingevuld, weggelaten worden (bijvoorbeeld voor de link naar pagina 1, terwijl iemand op pagina 2 is, dan kan de hele page parameter weggelaten worden). Het liefst werk ik wel met de url view helper, als dat mogelijk is voor zo iets 'gecompliceerds'.

Volgens mij heb ik het nou enorm vaag omschreven..

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Met de view helper kan je gewoon extra parameters toevoegen, die uiteindelijk ook in je url er extra bijkomen. Voor het overschrijven kan je de nieuwe waarde ook meegeven (de oude weglaten) en dat gaat gewoon goed. Voor het verwijderen heb je twee opties: de eerste is de specifieke waarde op null zetten, de view helper haalt dan de parameter weg. De andere optie is te resetten (zie de docs). Alle parameters zijn dan terug naar de standaard waarde (voor de :param parameters) of verdwijnen helemaal (voor de wildcard). Je moet dus de afweging maken of je meer moet weghalen (dan moet je resetten) of wilt houden (dan moet je de rest op null zetten). Zie de docs van de helper voor meer info.

Acties:
  • 0 Henk 'm!

  • GWTommy
  • Registratie: Mei 2008
  • Laatst online: 05-08-2023
Het blijft leuk, alle functies uitvinden.
Ik heb het nou zo gedaan, het bleek veel makkelijker dan ik had gedacht:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<ul class="sortable-field nicebuttons">
<?php foreach (array('title', 'price') as $field) if ($this->selectedField == $field): ?>
  <li><?= $this->t($field) ?></li>
<?php else: ?>
  <li><a href="<?= $this->url(array('sort' => (($field == 'title') ? NULL : $field)), NULL, false) ?>"><?= $this->t($field) ?></a></li>
<?php endif; ?>
</ul>
<ul class="sortable-mode nicebuttons">
<?php if ($this->mode == 'asc'): ?>
  <li><?= $this->t('ascending') ?></li>
  <li><a href="<?= $this->url(array('mode' => 'desc'), NULL, false) ?>"><?= $this->t('descending') ?></a></li>
<?php else: ?>
  <li><a href="<?= $this->url(array('mode' => NULL), NULL, false) ?>"><?= $this->t('ascending') ?></a></li>
  <li><?= $this->t('descending') ?></li>
<?php endif; ?>
</ul>
<ul class="sortable-displayItems nicebuttons">
<?php foreach (array(30, 50, 100) as $displayItems) if ($this->displayItems == $displayItems): ?>
  <li><?= $displayItems; ?></li>
<?php else: ?>
  <li><a href="<?= $this->url(array('displayItems' => (($displayItems == 30) ? NULL : $displayItems)), NULL, false) ?>"><?= $displayItems; ?></a></li>
<?php endif; ?>
</ul>
Pagina: 1