zend-framework2 - 如何处理 Zend Framework 2 应用程序中的元描述/关键字?

标签 zend-framework2 keyword meta-tags head

布局文件中定义的默认页面title可以扩展(PREPEND/APPEND)或替换(SET) 带有特定于当前 View 的标题。

我也一直期待 HeadMeta 会出现这种行为查看助手。现在我找不到任何合适的方法来“扩展”我在布局文件中定义的默认 descrition/keywords

我可以使用 append(...)/appendName(...) 添加进一步的 meta 标签(类似使用 HeadLinkHeadScript 添加样式或脚本文件)。但它对 descritionkeywords meta 标签没有意​​义。

是否有推荐的方法来处理此问题?如何处理description/keywords meta标签?

最佳答案

这是我目前正在使用的一个快速但肮脏的解决方法(为了获得一个干净的解决方案而不是一个丑陋的解决方法,需要在框架中进行更改):

HeadMeta View 助手

<?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');
?>

关于zend-framework2 - 如何处理 Zend Framework 2 应用程序中的元描述/关键字?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16300614/

相关文章:

meta-tags - 文章 :publisher meta tag cannot be parsed as profile

mysql - 如何创建基于多个唯一键的转换后的 Doctrine 2 实体

php - zf2.如何处理循环 cli 脚本中 mysql 连接的超时?

用于访问类变量的 Python 关键字

c++ - 除了允许 const 函数修改变量之外, 'mutable' 关键字是否还有其他用途?

asp.net - 自动生成的 visual studio &lt;meta&gt; 标签有什么用吗

sms - Android 和 iOS 上的 Open Graph SMS 丰富消息

php - 有没有办法在本地覆盖 ZF2 application.config.php 指令?

php - 在 Zend Framework 2 中创建下拉列表

bash - 如何将 "="等号定义为 Bash 别名?