2013-04-30 20 views
2

在布局文件中定义的默认页面title可以扩展(PREPEND/APPEND)或替换(SET),使用特定于当前视图的标题。如何处理Zend Framework 2应用程序中的元描述/关键字?

这种行为我也期待HeadMeta视图助手。现在我找不到任何适当的方式来“扩展”我在布局文件中定义的默认值descrition/keywords

代替它,我可以append(...)/appendName(...)(与之相似,以添加样式或脚本文件,HeadLinkHeadScript)添加进一步meta标签。但它对descritionkeywordsmeta标签没有任何意义。

是否有推荐的方法来处理这个问题?如何处理description/keywordsmeta标签?

回答

4

这里是一个快速&脏workaroud,我目前使用(用于清洁的解决方案,而不是一个丑陋的解决方法的框架,需要改变):

HeadMeta视图助手

<?php 
namespace MyNamespace\View\Helper; 

use stdClass; 
use Zend\View; 
use Zend\View\Exception; 
use Zend\View\Helper\HeadMeta as ZendHeadMeta; 
use Zend\View\Helper\Placeholder\Container\AbstractContainer; 

class HeadMeta extends ZendHeadMeta { 

    const DELIMITER = ' - '; 

    /** 
    * @see \Zend\View\Helper\HeadMeta::__invoke() 
    */ 
    public function __invoke($content = null, $keyValue = null, $keyType = 'name', $modifiers = array(), $placement = AbstractContainer::APPEND) { 
     parent::__invoke($content, $keyValue, $keyType, $modifiers, $placement); 
     return $this; 
    } 

    /** 
    * @see \Zend\View\Helper\HeadMeta::append() 
    */ 
    public function append($value) { 
     if ($value->name == 'description') { 
      $this->updateDescription($value, AbstractContainer::APPEND); 
     } else if ($value->name == 'keywords') { 
      $this->updateKeywords($value, AbstractContainer::APPEND); 
     } else { 
      parent::append($value); 
     } 
    } 

    /** 
    * @see \Zend\View\Helper\HeadMeta::prepend() 
    */ 
    public function prepend($value) { 
     if ($value->name == 'description') { 
      $this->updateDescription($value, AbstractContainer::PREPEND); 
     } else if ($value->name == 'keywords') { 
      $this->updateKeywords($value, AbstractContainer::PREPEND); 
     } else { 
      parent::prepend($value); 
     } 
    } 

    // Not working correctly! 
    // Can cause a 
    // Fatal error: Maximum function nesting level of '100' reached, aborting! 
    /** 
    * @see \Zend\View\Helper\HeadMeta::set() 
    */ 
    public function set($value) { 
     if ($value->name == 'description') { 
      $this->updateDescription($value, AbstractContainer::SET); 
     } else if ($value->name == 'keywords') { 
      $this->updateKeywords($value, AbstractContainer::SET); 
     } else { 
      parent::set($value); 
     } 
    } 

    /** 
    * If a description meta already exsists, extends it with $value->content, 
    * else creates a new desctiprion meta. 
    * @param \stdClass $value 
    * @param string $position 
    */ 
    public function updateDescription(\stdClass $value, $position = AbstractContainer::SET) { 
     $descriptionExists = false; 
     foreach ($this->getContainer() as $item) { 
      if ($this->isDescription($item)) { 
       switch ($position) { 
        case AbstractContainer::APPEND: 
         $descriptionString = implode(static::DELIMITER, array($item->content, $value->content)); 
         break; 
        case AbstractContainer::PREPEND: 
         $descriptionString = implode(static::DELIMITER, array($value->content, $item->content)); 
         break; 
        case AbstractContainer::SET: 
        default: 
         $descriptionString = $value->content; 
         break; 
       } 
       $item->content = $descriptionString; 
       $descriptionExists = true; 
      } 
     } 
     if (!$descriptionExists) { 
      switch ($position) { 
       case AbstractContainer::APPEND: 
        parent::append($value); 
        break; 
       case AbstractContainer::PREPEND: 
        parent::prepend($value); 
        break; 
       case AbstractContainer::SET: 
       default: 
        parent::set($value); 
        break; 
      } 
     } 
    } 

    /** 
    * If a keywords meta already exsists, extends it with $value->content, 
    * else creates a new keywords meta. 
    * @param \stdClass $value 
    * @param string $position 
    */ 
    public function updateKeywords(\stdClass $value, $position = AbstractContainer::SET) { 
     $keywordsExists = false; 
     foreach ($this->getContainer() as $item) { 
      if ($this->isKeywords($item)) { 
       switch ($position) { 
         case AbstractContainer::APPEND: 
          $keywordsString = implode(', ', array($item->content, $value->content)); 
          break; 
         case AbstractContainer::PREPEND: 
          $keywordsString = implode(', ', array($value->content, $item->content)); 
          break; 
         case AbstractContainer::SET: 
         default: 
          $keywordsString = $value->content; 
          break; 
       } 
       $item->content = $keywordsString; 
       $keywordsExists = true; 
      } 
     } 
     if (!$keywordsExists) { 
      parent::append($value); 
     } 
    } 

    /** 
    * @return description meta text 
    */ 
    public function getDescription() { 
     $description = null; 
     foreach ($this->getContainer() as $item) { 
      if ($this->isKeywords($item)) { 
       $description = $item->content; 
       break; 
      } 
     } 
     return $description; 
    } 

    /** 
    * @return keywords meta text 
    */ 
    public function getKeywords() { 
     $keywords = null; 
     foreach ($this->getContainer() as $item) { 
      if ($this->isKeywords($item)) { 
       $keywords = $item->content; 
       break; 
      } 
     } 
     return $keywords; 
    } 

    /** 
    * Checks, whether the input $item is an approproate object for $this->container 
    * and wheter it's a description object (its name is "description") 
    * @param stdClass $item 
    * @throws Exception\InvalidArgumentException 
    * @return boolean 
    */ 
    public function isDescription(stdClass $item) { 
     if (!in_array($item->type, $this->typeKeys)) { 
      throw new Exception\InvalidArgumentException(sprintf(
       'Invalid type "%s" provided for meta', 
       $item->type 
      )); 
     } 
     return $item->name == 'description'; 
    } 

    /** 
    * Checks, whether the input $item is an approproate object for $this->container 
    * and wheter it's a keywords object (its name is "keywords") 
    * @param stdClass $item 
    * @throws Exception\InvalidArgumentException 
    * @return boolean 
    */ 
    public function isKeywords(stdClass $item) { 
     if (!in_array($item->type, $this->typeKeys)) { 
      throw new Exception\InvalidArgumentException(sprintf(
       'Invalid type "%s" provided for meta', 
       $item->type 
      )); 
     } 
     return $item->name == 'keywords'; 
    } 

} 

/module/Application/view/layout/layout.phtml

<?php 
$this->headMeta()->appendName(
    'description', 
    $this->translate('default description') 
); 
$this->headMeta()->appendName(
    'keywords', 
    implode(', ', array(
     $this->translate('default keyword 1'), 
     $this->translate('default keyword 2'), 
     $this->translate('default keyword 3'), 
    )) 
); 
echo $this->headMeta(); 
?> 

视图脚本

<?php 
$this->headMeta()->setName('keywords', implode(
    ', ', 
    array(
     $this->translate('view specific keyword 1'), 
     $this->translate('view specific keyword 2'), 
     $this->translate('view specific keyword 3'), 
    ) 
)); 
$this->headMeta()->setName('description', 'view specific description'); 
?> 
+1

你的解决方案的工作魅力,但请加一点需要注意的是帮手,应正确连接到模块。例如下面一行应该存在于module.config.php''view_helpers'=> array('invokables'=> array('headMeta'=>'\ YourModule \ View \ Helper \ HeadMeta')' – zeliboba 2014-11-29 17:55:58

+0

让它工作!我添加了@zeliboba评论(带有一个完整的括号;)但是却得到了错误:_PHP致命错误:带有消息'Zend \\ View \\ HelperPluginManager :: createFromInvokable:未捕获的异常'Zend \\ ServiceManager \\ Exception \\ ServiceNotFoundException'无法通过可调用类“MyModule \\ View \\ Helper \\ HeadMeta”获取“headmeta(alias:headMeta)”;类不存在'__ - 通过使用_./bin/为模块生成新的类图解决了问题classmap_generator.php_ – 2015-10-21 07:30:17

1

链接到这里我的答案:How to change meta tags in zend framework layout

下面是我工作。在布局文件中,您必须确保元标记被回显。它在阶段是空的,但你会标记元标记将被输出的位置。这种方法唯一的缺点是,似乎没有一种方法来获得默认的元标记,因此您必须在每个视图文件中添加元标记。

在布局文件

<?php echo $this->headMeta(); ?> 

在视图一个.phtml文件

$this->headMeta("test description text", "description"); 
+0

问题是如何替换先前定义的元标记。在你的例子中,先前定义的meta不存在 - 所以你给出了无关的答案。 – zeliboba 2014-11-29 17:49:08

相关问题