{"id":131,"date":"2014-04-23T15:24:19","date_gmt":"2014-04-23T15:24:19","guid":{"rendered":"https:\/\/www.dafap.fr\/blog\/?p=131"},"modified":"2014-07-15T08:47:18","modified_gmt":"2014-07-15T08:47:18","slug":"aide-de-vue-dans-les-layouts-de-zendframework-2-exemple","status":"publish","type":"post","link":"https:\/\/www.dafap.fr\/blog\/developpement-php\/aide-de-vue-dans-les-layouts-de-zendframework-2-exemple","title":{"rendered":"Aide de vue dans les layouts de Zendframework 2 : Exemple"},"content":{"rendered":"<h2>Pr\u00e9sentation de l'exemple<\/h2>\n<p>Une aide de vue, ou ViewHelper, sert \u00e0 factoriser des bouts de code pour nos views ou layouts.<\/p>\n<p>L'appel \u00e0 notre aide de vue se fera tr\u00e8s simplement. Prenons par exemple le cas o\u00f9 on a besoin\u00a0de d\u00e9clarer des feuilles de style dont les noms sont contenus dans un tableau :<\/p>\n<pre class=\"lang:php decode:true\" title=\"Utilisation d'aides de vue dans un view ou un layout\">$base_path = $this-&gt;basePath(); \r\necho $this-&gt;getHeadLinks($base_path, $favicon_file = null, $this-&gt;config['css']);<\/pre>\n<p>Dans cet exemple, on utilise deux aides de vue, <em>basePath()<\/em> qui est fournie dans le package <em>Zendframework 2<\/em> et <em>getHeadLinks()<\/em> que je vais d\u00e9velopper ci-dessous.<\/p>\n<p class=\"crayon-line crayon-striped-line\" style=\"color: #000000;\">Pour mon aide de vue je\u00a0passe trois\u00a0param\u00e8tres :<\/p>\n<ul>\n<li><em>$base_path<\/em>\u00a0: la racine du\u00a0service fournie par l'aide de vue de <em>ZendFramework<\/em><\/li>\n<li><em>$favicon_file<\/em>\u00a0: le favicon \u00e0 utiliser pour cette page<\/li>\n<li><em>$config['css'] : le<\/em>\u00a0tableau provenant du <em>config\/module.config.php<\/em><\/li>\n<\/ul>\n<p>Dans <em>config\/module.config.php,<\/em> je d\u00e9cris les feuilles de style \u00e0 charger de la fa\u00e7on suivante :<\/p>\n<pre class=\"lang:default decode:true\" title=\"Structure utilis\u00e9e dans module.config.php\">return array(\r\n&nbsp; &nbsp; ...\r\n    'css' =&gt; array(\r\n        'css\/style.css',\r\n        'css\/nav.css',\r\n        array(\r\n            'href' =&gt; 'css\/ie7.css',\r\n            'media' =&gt; 'screen',\r\n            'conditionalStylesheet' =&gt; 'lt ie7',\r\n            'extras' =&gt; array('id' =&gt; 'dafap',) \r\n        ),\r\n    ),\r\n    ...<\/pre>\n<p>cela devra donner dans le code de la page :<\/p>\n<pre class=\"lang:default decode:true\" title=\"R\u00e9sultat attendu dans la page html\">&lt;!--[if lt ie7]&gt; &lt;link href=\"\/css\/ie7.css\" media=\"screen\" rel=\"stylesheet\" type=\"text\/css\" id=\"dafap\" \/&gt;&lt;![endif]--&gt;\r\n&lt;link href=\"\/css\/nav.css\" media=\"screen\" rel=\"stylesheet\" type=\"text\/css\"&gt;\r\n&lt;link href=\"\/css\/style.css\" media=\"screen\" rel=\"stylesheet\" type=\"text\/css\"&gt;\r\n&lt;link href=\"\/img\/favicon.ico\" rel=\"shortcut icon\" type=\"image\/vnd.microsoft.icon\"&gt;<\/pre>\n<h2>Impl\u00e9mentation de notre aide de vue<\/h2>\n<p>Une aide de vue, ou ViewHelper, est une classe d\u00e9riv\u00e9e de\u00a0<em>Zend\\View\\Helper\\AbstractHelper<\/em>. Pour mon cas, je l'appelerai <em>HeadLinks<\/em> et elle sera plac\u00e9e dans le <em>src<\/em> du module, dossier <em>View\/Helper<\/em> :<\/p>\n<pre class=\"striped:false nums:false lang:default highlight:0 decode:true\" title=\"Emplacement d'un ViewHelper dans le code\">module\r\n  \u2514 MonModule\r\n          \u2514 src\r\n               \u2514 MonModule\r\n                        \u2514 View\r\n                             \u2514 Helper<\/pre>\n<p>Sa m\u00e9thode <em>_invoke()<\/em> retournera le\u00a0r\u00e9sultat en invoquant son nom d\u00e9clar\u00e9 dans <em>module.php<\/em> dans la m\u00e9thode <em>getViewHelperConfig()<\/em>.<\/p>\n<pre class=\"lang:default decode:true\" title=\"D\u00e9claration du ViewHelper dans la classe Module\">public function getViewHelperConfig()\r\n{\r\n    return array(\r\n        'invokables' => array(\r\n            'getHeadLinks' => __NAMESPACE__ .'\\View\\Helper\\HeadLinks',\r\n        ),\r\n    );\r\n}<\/pre>\n<p>Dans\u00a0mon aide de vue, j'ai besoin d'utiliser l'aide de vue <em>headLink<\/em> de <em>Zendframework<\/em>. Or, je ne peux pas utiliser l'alias <em>headLink<\/em> qui n'est pas <em>invokable<\/em>. Je vais donc utiliser la classe directement.<\/p>\n<pre class=\"lang:default decode:true\" title=\"Code de mon ViewHelper\">namespace MonModule\\View\\Helper;\r\nuse Zend\\View\\Helper\\AbstractHelper;\r\nuse Zend\\View\\Helper\\HeadLink;\r\n\r\nclass HeadLinks extends AbstractHelper\r\n{\r\n   public function __invoke($base_path, $favicon_file = null, $cssFilesArray = array())\r\n   {\r\n     $headLink = new HeadLink();\r\n     if (! is_null($favicon_file) &amp;&amp; is_string($favicon_file)) {\r\n         $headLink = $headLink(array(\r\n             'rel' =&gt; 'shortcut icon',\r\n             'type' =&gt; 'image\/vnd.microsoft.icon',\r\n             'href' =&gt; $this-&gt;concatPath($base_path, $favicon_file)\r\n         ));\r\n     } else {\r\n         $headLink = $headLink();\r\n     }\r\n     foreach ($cssFilesArray as $css_file) {\r\n         if (is_string($css_file)) {\r\n             $headLink = $headLink-&gt;prependStylesheet($this-&gt;concatPath($base_path, $css_file));\r\n         } elseif (is_array($css_file)) {\r\n             $href = $this-&gt;getParam('href', $css_file);\r\n             $media = $this-&gt;getParam('media', $css_file);\r\n             $conditionalStylesheet = $this-&gt;getParam('conditionalStylesheet', $css_file);\r\n             $extras = $this-&gt;getParam('extras', $css_file);\r\n             if (!is_null($href)) {\r\n                 $headLink = $headLink-&gt;prependStylesheet($this-&gt;concatPath($base_path, $href), $media, $conditionalStylesheet, $extras);\r\n             }\r\n         } else {\r\n             throw new \\Exception('Erreur de structure pour la d\u00e9finition des fichiers css.');\r\n         }\r\n     }\r\n     return $headLink;\r\n   }\r\n   private function getParam($nom, $tableau)\r\n   {\r\n       if (array_key_exists($nom, $tableau)) {\r\n           return $tableau[$nom];\r\n       } else {\r\n           return null;\r\n       }\r\n   }\r\n   private function concatPath($base_path, $file = null)\r\n   {\r\n       if (! is_null($file)) {\r\n           $file = '\/' . ltrim($file, '\/');\r\n       }\r\n       $base_path = rtrim(str_replace('\\\\', '\/', $base_path), '\/');\r\n       return $base_path . $file;\r\n   }\r\n}<\/pre>\n<h2>Utilisation de mon aide de vue dans un layout<\/h2>\n<p>Pour utiliser mon aide de vue dans un layout, je dois disposer d'une variable <em>$this-&gt;config<\/em> qui contient notamment la cl\u00e9 <em>'css'<\/em> donnant la structure \u00e0 monter (en fait, je passe \u00e9galement dans ce tableau tous les \u00e9l\u00e9ments constitutifs du layout comme les composants du header, du footer, etc.).<\/p>\n<h3>Comment passer une variable \u00e0 un layout ?<\/h3>\n<h4>Premi\u00e8re fa\u00e7on : depuis un contr\u00f4leur<\/h4>\n<p>Dans un contr\u00f4leur, on a acc\u00e8s au layout par la m\u00e9thode <em>layout()<\/em>. On cr\u00e9e donc les variables directement :<\/p>\n<pre class=\"lang:default decode:true\" title=\"Affectation d'une variable dans le layout depuis un contr\u00f4leur\">$this-&gt;layout()-&gt;ma_variable = $valeur;<\/pre>\n<p>En particulier pour mon cas, je trouverai la valeur de ma variable de configuration de la fa\u00e7on suivante :<\/p>\n<pre class=\"lang:default decode:true\" title=\"Dans mon contr\u00f4leur, pour cet exemple\">$sm = $this-&gt;getServiceLocator();\r\n$config = $sm-&gt;get('config');\r\n$this-&gt;layout()-&gt;config = $config['layout'];<\/pre>\n<h4>Deuxi\u00e8me fa\u00e7on : depuis la classe Module<\/h4>\n<p>Etant donn\u00e9 que la configuration est disponible dans\u00a0la classe Module, on peut\u00a0cr\u00e9er la variable depuis la m\u00e9thode <em>onBootstrap()<\/em> de cette classe :<\/p>\n<pre class=\"lang:default decode:true\" title=\"Affectation d'une variable dans le layout depuis la classe Module\"> public function onBootstrap(MvcEvent $e)\r\n {\r\n     $eventManager = $e-&gt;getApplication()-&gt;getEventManager();\r\n     $config = $this-&gt;getApplication()-&gt;getServiceManager()-&gt;get('config');\r\n     $config_layout = $config['layout'];\r\n     $eventManager-&gt;attach(MvcEvent::EVENT_RENDER, function($e) use ($config_layout) {\r\n         $e-&gt;getViewModel()-&gt;setVariable('config', $config_layout);\r\n   });\r\n   $moduleRouteListener = new ModuleRouteListener();\r\n   $moduleRouteListener-&gt;attach($eventManager);\r\n }<\/pre>\n<h4>Troisi\u00e8me fa\u00e7on : en d\u00e9rivant la classe\u00a0<em>Module<\/em> de <em>ZfcBase\\Module\\AbstractModule<\/em><\/h4>\n<p>On devra alors restructurer le fichier module.config.php de la fa\u00e7on suivante :<\/p>\n<pre class=\"lang:default decode:true\" title=\"Structure particuli\u00e8re dans module.config.php pour utiliser ZfcBase::getOptions()\">return array(\r\n    'MonModule' =&gt; array(\r\n        'layout' =&gt; array(\r\n            'css' =&gt; array(\r\n                'css\/style.css',\r\n                'css\/nav.css',\r\n                array(\r\n                    'href' =&gt; 'css\/ie7.css',\r\n                    'media' =&gt; 'screen',\r\n                    'conditionalStylesheet' =&gt; 'lt ie7',\r\n                    'extras' =&gt; array('id' =&gt; 'dafap',)\r\n                ),\r\n            ),\r\n            ...\r\n        ),\r\n    ),\r\n    ...\r\n);<\/pre>\n<p>Ainsi, on pourra utiliser dans le module la m\u00e9thode <em>getOptions()\u00a0<\/em>:<\/p>\n<pre class=\"lang:default decode:true\" title=\"Affectation d'une variable dans un module d\u00e9riv\u00e9 de ZfcBase\">namespace MonModule;\r\nuse ZfcBase\\Module\\AbstractModule;\r\nclass Module extends AbstractModule\r\n{\r\n public function onBootstrap(MvcEvent $e)\r\n {\r\n     $eventManager = $e-&gt;getApplication()-&gt;getEventManager();\r\n     $config_layout = $this-&gt;getOptions('layout');\r\n     $eventManager-&gt;attach(MvcEvent::EVENT_RENDER, function($e) use ($config_layout) {\r\n         $e-&gt;getViewModel()-&gt;setVariable('config', $config_layout);\r\n   });\r\n   $moduleRouteListener = new ModuleRouteListener();\r\n   $moduleRouteListener-&gt;attach($eventManager);\r\n }\r\n public function getDir()\r\n {\r\n     return __DIR__;\r\n }\r\n public function getNamespace()\r\n {\r\n     return __NAMESPACE__;\r\n }\r\n}<\/pre>\n<p>Cela va permettre d'utiliser une configuration particuli\u00e8re pour chaque module de l'application. Mais \u00e7a, ce sera l'objet d'un prochain article.<\/p>\n<p>Voir aussi un article complet sur <a title=\"Cr\u00e9ation d'un ViewHelper dans ZF2\" href=\"http:\/\/aromatix.fr\/?p=552\" target=\"_blank\">la cr\u00e9ation d'un ViewHelper dans ZF2<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Pr\u00e9sentation de l&rsquo;exemple Une aide de vue, ou ViewHelper, sert \u00e0 factoriser des bouts de code pour nos views ou layouts. L&rsquo;appel \u00e0 notre aide de vue se fera tr\u00e8s simplement. Prenons par exemple le cas o\u00f9 on a besoin\u00a0de d\u00e9clarer des feuilles de style dont les noms sont contenus dans un tableau : $base_path [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[9,15],"tags":[28,29,27,23],"class_list":["post-131","post","type-post","status-publish","format-standard","hentry","category-developpement-php","category-zendframework2","tag-headlink","tag-layout","tag-viewhelper","tag-zf2"],"_links":{"self":[{"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/posts\/131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/comments?post=131"}],"version-history":[{"count":9,"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/posts\/131\/revisions"}],"predecessor-version":[{"id":171,"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/posts\/131\/revisions\/171"}],"wp:attachment":[{"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/media?parent=131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/categories?post=131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dafap.fr\/blog\/wp-json\/wp\/v2\/tags?post=131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}