Best practice to place meta tags, links and styles in zend framework?

3.6k Views Asked by At

I have project-range meta tags that are need to be set. I've put them in protected method _initMeta in Bootstrap class. Are there any better options? What if I would like different set of this data for another languages?

protected function _initMeta(){
    $this->bootstrap('view');
    $view = $this->getResource('view');
    $view->doctype('XHTML1_STRICT');

    $view->headTitle()->headTitle('Foo title');

    $view->headMeta()->appendName('keywords','foo');

    $view->headMeta()->appendHttpEquiv('Content-Type', 'text/html; charset=UTF-8')
            ->appendHttpEquiv('Content-Language', 'any');

    $view->headLink()->appendStylesheet('/foo.css')->headLink(array('rel' => 'favicon',
                              'href' => '/favicon.ico'),
                              'PREPEND');
}
3

There are 3 best solutions below

0
On BEST ANSWER

I use config for basic (bootstrap) data as:

application.ini

resources.view.meta.name.Viewport                       = "width=device-width, initial-scale=1.0"
resources.view.meta.name.MobileOptimized                    = "width"
resources.view.meta.name.HandheldFriendly                   = "true"
resources.view.meta.name.Keywords                       = "basic,keywords"
...
; format resources.view.headStyle.{MEDIA}.nfile = 
resources.view.headStyle.all.1.href                 = "/css/basic.css"
resources.view.headStyle.all.1.conditionalStylesheet            = 
resources.view.headStyle.all.1.extras.title             = "Basic style"
resources.view.headStyle.all.1.extras.charset               = "utf-8"

resources.view.headStyle.all.2.href                 = "/css/ie.css"
resources.view.headStyle.all.2.conditionalStylesheet            = "IE"
resources.view.headStyle.all.2.extras.title             = "Internet Explorer style"
resources.view.headStyle.all.2.extras.charset               = "utf-8"
; print media example
resources.view.headStyle.print.1.href                   = "/css/print.css"
...
; format resources.view.headLink.{REL} = 
resources.view.headLink.humans.href                     = "/humans.txt"
resources.view.headLink.humans.type                     = "text/plain"
; ___ will be replaced by space, __ by point (or set another nest separator)
resources.view.headLink.shortcut___icon.href                = "/favicon.png"
resources.view.headLink.shortcut___icon.type                = "image/png"
...

At this point, maybe you have some special data. For example in:

project1.ini

project.headLink.author.href                = "https://plus.google.com/XXXXX?rel=author"
project.headLink.image_src.href                     = "/author.jpg"
project.headLink.image_src.type                     = "image/jpg"

And finally, you mix all in your

Bootstrap.php

(example for *_initHeadLink()*):

// $options = your app options (basic)
// $projectOptions = your project options (special)
// $assets_url = your assets url

if ( is_array($headStyle = $options['headStyle']) ) {
    foreach ( $headStyle as $media => $value ) {
        foreach ( $value as $style ) {
            extract($style);
            $this->view->headLink()->appendStylesheet($assets_url . $href, $media, 
                            $conditionalStylesheet, $extras);
        }
    }
}

$headLinks      = array();

if ( isset($options['headLink']) ) 
    $headLinks      = $options['headLink'];

if ( isset($projectOptions['headLink']) ) 
    $headLinks      = array_merge($headLinks, (array) $projectOptions['headLink']);

// *array key, is the value for rel
foreach ( $headLinks as $rel => $value ) {
    $rel            = str_replace(array('___', '__'), array(' ', '.'), $rel);
    $this->view->headLink()->headLink(array_merge(array('rel' => $rel), (array) $value));
}

Then, you can override these data from your Controller: setName, set...

I hope it helps ;)

0
On

You have several ways of achieving this. First and foremost, make sure the moment you define the metadata you already know what language will be loaded for the current request. Sometimes this may not be easy to determine at bootstrap time.

Having said this, besides the bootstrap, you can set the metadata on a:

  • Front Controller Plugin class (using for example the dispatchLoopStartup() or predispatch() methods).
  • Action Helper class (using for example the init() or preDispatch() methods).

At those points of execution you probably already determined the language to use, and can set the metadata accordingly. You can always change the metadata afterwards in your action controllers for specific cases in your application, so you're never really stuck if you previously specified metadata.

In my own work, I have this setup:

  1. Front Controller Plugin, dispatchLoopStartup() method: determine language to load, giving priority to a "lang" GET parameter in the request object, then browser language, then default site language. I also use this to determine if the request is a normal request or an ajax request; if it's the former case, I register an action helper, see next...
  2. Action Helper, preDispatch() method: load metadata depending on language and other stuff, load Layout and widgets, etc.
  3. Action controller, someAction() method: if necessary, change some of the previously set metadata, for example headTitle(), which can depend on the effectively loaded content.

This arrangement makes sense to me, maybe it can help your approach?

0
On

The bootstrap is way to early for my projects. I add them in my controller/actions

$keywords = 'php,zend,framework';
$this->view->headMeta($keywords,'keywords','name',array(),'SET');
... etc.

Actually very late almost at the end. At this point I would also know about language and other things.