[php/zf]Overloading standaard view helpers

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Ik heb een aantal componenten binnen het Zend Framework waar ik wat aan wil toevoegen. Om het framework niet zelf aan te tasten zou je dit moeten doen door het overloaden van de klassen. Zo wil ik onder andere de HeadTitle, Navigation_Menu, Navigation_Breadcrumbs en Navigation_Sitemap onderdelen veranderen.

Ik heb begrepen dat door het plugin loader systeem dit gewoon mogelijk moet zijn. Ik heb in mijn applicatie al een aantal view helpers staan (View_Helper_HelperNaam) die staan in application/layouts/helpers/. Dit werkt gewoon goed. Ook heb ik een aantal view helpers staan in mijn eigen library folder (MyApp_View_Helper_HelperNaam) en die werken ook allemaal prima.

Helaas werken mijn helpers die ik overload vanuit ZF niet. Als test heb ik deze helper gemaakt:

PHP: application/layouts/views/helpers/HeadTitle.php
1
2
3
4
5
6
7
8
class View_Helper_HeadTitle extends Zend_View_Helper_HeadTitle
{
    public function toString ($indent = null, $locale = null)
    {
        $this->headTitle('Test');
        return parent::toString($indent, $locale);
    }
}


Je zou verwachten dat nu op elke pagina er in de title ook 'Test' bij komt te staan. Maar dat is niet waar. Zie ook deze debug test:

PHP: layout.phtml
1
2
<?= get_class($this->headTitle())?>
//output: Zend_View_Helper_HeadTitle

Experimenteren anderen al met het overloaden van ZF componenten? Lopen die ook tegen deze problemen aan? Ik kom er in ieder geval niet uit :p
En door de 100'en mailtjes per dag op fw-general@lists.zend.com krijg ik ook daar geen antwoord ;(

Acties:
  • 0 Henk 'm!

  • Face_-_LeSS
  • Registratie: September 2004
  • Niet online
Ik zou verwachten (na het bekijken van de ZF documentatie) dat de toString methode helemaal niet aangeroepen wordt voor het tonen van de headTitle. Ik zou verwachten dat daarvoor gewoon de headTitle getter wordt gebruikt...

Ik heb geen verstand van het ZF maar misschien staat de regel:
PHP:
1
$this->headTitle('Test');


beter op zijn plaats in de constructor van je klasse?

Acties:
  • 0 Henk 'm!

  • iH8
  • Registratie: December 2001
  • Laatst online: 17-06-2024

iH8

The default helper path always points to the Zend Framework view helpers, i.e., 'Zend/View/Helper/'. Even if you call setHelperPath() to overwrite the existing paths, this path will be set to ensure the default helpers work.
setHelperPath() misschien? wordt hij wel geinclude?

[ Voor 4% gewijzigd door iH8 op 15-06-2009 11:52 ]

Aunt bunny is coming to get me!


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Face_-_LeSS schreef op maandag 15 juni 2009 @ 11:45:
Ik zou verwachten (na het bekijken van de ZF documentatie) dat de toString methode helemaal niet aangeroepen wordt voor het tonen van de headTitle. Ik zou verwachten dat daarvoor gewoon de headTitle getter wordt gebruikt...

Ik heb geen verstand van het ZF maar misschien staat de regel:
PHP:
1
$this->headTitle('Test');


beter op zijn plaats in de constructor van je klasse?
De View_Helper_HeadTitle extend Zend_View_Helper_HeadTitle en die extend Zend_View_Helper_Placeholder_Container_Standalone. Die heeft de magic methode __toString(). Het enige wat die doet is de toString() aanroepen. Die override ik weer in mijn View_Helper_HeadTitle waardoor het uiteindelijk gewoon moet werken. Dit is ook slechts een test. Andere cases werken ook niet.
iH8 schreef op maandag 15 juni 2009 @ 11:48:
[...]

setHelperPath() misschien? wordt hij wel geinclude?
Omdat ik meerdere helpers heb, gebruik ik addHelperPath(). Hiervoor heb ik in mijn application.ini staan:
code:
1
2
resources.view.helper.0.path                   = APPLICATION_PATH "/layouts/helpers"
resources.view.helper.0.name                   = "View_Helper"

Ook heb ik een View Resource die het stukje code kent:
PHP:
1
2
3
4
5
if (isset($options->helper)) {
    foreach ($options->helper as $helper) {
        $this->_view->addHelperPath($helper['path'], $helper['name']);
    }
}
Omdat allerlei andere helpers wel werken, ga ik er vanuit dat dit allemaal goed functioneert. Een nogal vreemde situatie dus: het werkt wel, maar niet altijd :s

PS: sowieso wel bedankt voor het meedenken, dat wordt zeker gewaardeerd :)

/edit: Ik heb de resource herschreven, zodat het eerste item in de helpers array een setHelperPath() doet in plaats van een addHelperPath(), om mogelijke oude paden van ZF te overschrijven. Dit zorgt echter niet voor de oplossing

[ Voor 8% gewijzigd door mithras op 15-06-2009 12:38 ]


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Oké, ik heb het uiteindelijk opgelost. Na minstens een maand klooien, de mailing list bekogelen met mails en hier op GoT posten :p
offtopic:
En omdat het de oplossing is, doe ik maar een nieuwe post. Dat zal voor latere users die de oplossing zoeken wat makkelijk zijn denk ik.

Er zaten bij mij twee problemen (en die zijn uiteindelijk best verschillend!)
  1. De HeadTitle helper wilde niet werken
  2. Alle navigatie helpers wilde niet werken
De eerste was een gevalletje PEBKAC. In mijn view resource deed ik éérst iets met de HeadTitle helper en daarna voegde ik het pad toe van mijn custom helpers. Omdat voor performance redenen de helpers worden opgeslagen, kan je dus nooit een custom view helper krijgen als je eerst de default helper gebruikt |:(

De tweede is echt een probleem bij het ZF. Mochten wat ontwikkelaars hier ooit iets aan de breadcrumbs, sitemap of menu helper willen veranderen, je moet nogal wat copy/paste doen :'(

De Zend_View_Helper_Navigation voegt een extra pad toe (Zend/View/Helper/Navigation namelijk) om de helpers te kunnen vinden. Daar gaat het mis, omdat dat pad het laatst toegevoegd is en daardoor ook het eerst vindbaar (LIFO).
Ergo: maak je eigen MyApp_View_Helper_Navigation, definieer je eigen const NS en kopieer de hele methode findHelper() van de Zend Navigation Helper. Hierdoor definieer jij als laatste jouw pad en zijn jouw helpers als eerste vindbaar. Dus:
PHP:
1
2
3
4
5
6
7
8
9
10
<?php
class MyApp_View_Helper_Navigation extends Zend_View_Helper_Navigation
{
    const NS = 'MyApp_View_Helper_Navigation';

    public function findHelper($proxy, $strict = true)
    {
        //Hier de inhoud van Zend_View_Helper_Navigation::findHelpers();
    }
}
En vervolgens is je MyApp_View_Helper_Navigation_Menu prima vindbaar 8)7

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Waarom moet je die functie kopieren? Die erft hij toch mooi over van z'n parent?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
class A {
  const foo = 'bar';

  protected function _getFoo()
  {
    return self::foo;
  }
}

class B extends A {
  const foo = 'baz';
  
  public function __toString()
  {
    return parent::_getFoo();
  }
}

class C extends A {
  const foo = 'bat';

  public function __toString()
  {
    return $this->_getFoo();
  }

  protected function _getFoo()
  {
    return self::foo;
  }
}

$b = new B;
$c = new C;

echo $b . PHP_EOL . $c;
?>

Resultaat:
bar
bat
Hierdoor kan ik (afaik) niet alleen de CONST definiëren, maar moet ik ook de hele functie (hier die _getFoo() ) overwriten. Wanneer het een protected $ns (hier dus protected $foo) was geweest, bestond het hele probleem niet (of in ieder geval, was het minder erg).

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Snake schreef op maandag 15 juni 2009 @ 15:31:
Waarom moet je die functie kopieren? Die erft hij toch mooi over van z'n parent?
Dan moet je nog wel even expliciet de parent aanroepen.

Acties:
  • 0 Henk 'm!

  • Freeaqingme
  • Registratie: April 2006
  • Laatst online: 19-09 20:56
Is dit in principe geen bug in de navigatie viewhelpers?

No trees were harmed in creating this message. However, a large number of electrons were terribly inconvenienced.

Pagina: 1