Hello I have a situation in HeadMeta where I would like to test if a meta tag exists and then insert a value the same, for example:
layout.phtml
:
$this->headMeta()->setName('description', 'description website default');
product.phtml
:
$this->headMeta()->setName('description', 'description product');
I would like something like:
layout.phtml
:
if (! $this->headMeta()->existsName('description')) {
$this->headMeta()->setName('description', 'description website default');
}
This is because product.phtml
is processed before layout.phtml
therefore the “description” meta tag of product.phtml
is replaced by that of layout.phtml
.
Is there already a way to do this?
Quick Tip
You should activate the IDE auto-completion in your templates. Add the following lines to your .phtml
files:
<?php
/**
* @var Laminas\View\Renderer\PhpRenderer $this
*/
?>
Then the existing methods are displayed.
I thought about proposing a modification in HeadMeta:
/**
* Retrieve object instance; optionally add meta tag
*
* @param string $content
* @param string $keyValue
* @param string $keyType
* @param array $modifiers
* @param string $placement
* @return HeadMeta
*/
public function __invoke(
$content = null,
$keyValue = null,
$keyType = 'name',
$modifiers = [],
$placement = Placeholder\Container\AbstractContainer::APPEND
) {
if ((null !== $content) && (null !== $keyValue)) {
$item = $this->createData($keyType, $keyValue, $content, $modifiers);
$action = strtolower($placement);
switch ($action) {
case 'append':
case 'prepend':
case 'set':
case 'exists':
$this->$action($item);
break;
default:
$this->append($item);
break;
}
}
return $this;
}
/**
* Overload method access
*
* @param string $method
* @param array $args
* @throws Exception\BadMethodCallException
* @return HeadMeta
*/
public function __call($method, $args)
{
if (preg_match(
'/^(?P<action>set|(pre|ap)pend|offsetSet|exists)(?P<type>Name|HttpEquiv|Property|Itemprop)$/',
$method,
$matches
)) {
$action = $matches['action'];
$type = $this->normalizeType($matches['type']);
$argc = count($args);
$index = null;
if ('exists' == $action ) {
$item = $this->createData($type, $args[0], '', []);
return $this->exists($item);
}
if ('offsetSet' == $action ) {
if (0 < $argc) {
$index = array_shift($args);
--$argc;
}
}
if (2 > $argc) {
throw new Exception\BadMethodCallException(
'Too few arguments provided; requires key value, and content'
);
}
if (3 > $argc) {
$args[] = [];
}
$item = $this->createData($type, $args[0], $args[1], $args[2]);
if ('offsetSet' == $action) {
return $this->offsetSet($index, $item);
}
$this->$action($item);
return $this;
}
return parent::__call($method, $args);
}
/**
* Exists
*
* @param stdClass $value
* @throws Exception\InvalidArgumentException
* @return View\Helper\Placeholder\Container\AbstractContainer
*/
public function exists($value)
{
if (! $this->isValid($value)) {
throw new Exception\InvalidArgumentException('Invalid value passed to checks exists');
}
$container = $this->getContainer();
foreach ($container->getArrayCopy() as $index => $item) {
if ($item->type == $value->type && $item->{$item->type} == $value->{$value->type}) {
return true;
}
}
return false;
}
In this way we started to have the “exists” method, this can be extended to other similar classes like HeadScript, HeadStyle and HeadLink.