'append multiple html meta tags to head with a for loop
i'm currently working on a shopware plugin, where I add some meta data to the html tag head. I use twig to extend a template and add some some code to it. I trigger an event which passes the array of meta entities mykn_metaFields to my twig-template. In my twig-template I loop over mykn_metaFields and apply the values of these entities to meta-tag attributes.
Twig code:
{% sw_extends '@Storefront/storefront/layout/meta.html.twig' %}
{% block layout_head_meta_tags %}
{{parent()}}
{{dump()}}
{% if page.mykn_metaFields.total > 0 %}
{% for metaField in page.mykn_metaFields.entities.elements %}
{% if metaField.active == true %}
<meta name="{{metaField.name}}" content="{{metaField.value}}">
{{dump(metaField)}}
{% endif %}
{% endfor %}
{% endif %}
{% endblock %}
expected html Output:
<html>
<head>
...
<meta name="foo" content="foo">
<meta name="bar" content="bar">
</head>
<body>
...
</body>
</html>
returned html Output:
<html>
<head>
...
</head>
<body>
<meta name="foo" content="foo">
<meta name="bar" content="bar">
...
</body>
</html>
Question: Why doesn't it append the meta tags to the head?
This is how i pass the variable mykn_metaFields:
<?php declare(strict_types=1);
namespace MyPluginRoot\Subscriber\Storefront\Page;
use Shopware\Storefront\Page\GenericPageLoadedEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
class PageLoadedSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $metaFieldRepository;
public function __construct(EntityRepositoryInterface $metaFieldRepository)
{
$this->metaFieldRepository = $metaFieldRepository;
}
public static function getSubscribedEvents(): array
{
return [
GenericPageLoadedEvent::class => 'addMetaToHead'
];
}
public function addMetaToHead(GenericPageLoadedEvent $event): void
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true));
$metaFields = $this->metaFieldRepository->search($criteria, $event->getContext());
$array = ['mykn_metaFields' => $metaFields];
$event->getPage()->assign($array);
}
}```
EDIT
I solved this problem by removing dump() in my twig-template. I guess shopware renders it as something like a pre-tag which puts it in the body.
Solution 1:[1]
I assume that page.mykn_metaFields is a EntitySearchResult in that case you should be able to loop directly over that SearchResult, no need to access the internal elements property and also no need to check the total beforehand.
this would already simplify your twig template:
{% sw_extends '@Storefront/storefront/layout/meta.html.twig' %}
{% block layout_head_meta_tags %}
{{parent()}}
{{dump()}}
{% for metaField in page.mykn_metaFields %}
{% if metaField.active == true %}
<meta name="{{metaField.name}}" content="{{metaField.value}}">
{{dump(metaField)}}
{% endif %}
{% endfor %}
{% endblock %}
Additionally i would filter the inactive metaFields already on the backend side, where you load your own entity and add it to the page object.
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('active', true);
$result = $metaFieldRepository->search($criteria, $context);
That way you can get rid of the active check in the template, and the template is greatly simplified:
{% sw_extends '@Storefront/storefront/layout/meta.html.twig' %}
{% block layout_head_meta_tags %}
{{parent()}}
{{dump()}}
{% for metaField in page.mykn_metaFields %}
<meta name="{{metaField.name}}" content="{{metaField.value}}">
{{dump(metaField)}}
{% endfor %}
{% endblock %}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | j_elfering |
