This is driving me nuts, I created a module with a helper:
namespace MyNamespace\MyModule\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
protected $registry;
public function __construct
(
\Magento\Framework\Registry $registry,
\Magento\Eav\Api\AttributeSetRepositoryInterface $attributeSet
) {
$this->registry = $registry;
$this->attributeSet = $attributeSet;
}
public function getTitle()
{
$this->product = $this->registry->registry('product');
$product_name = $this->product->getName();
$attributeSetRepository = $this->attributeSet->get($this->product->getAttributeSetId());
if ($attributeSetRepository->getAttributeSetName() == "Default Engine Component"){
$engine = $this->product->getAttributeText('engine_select');
if (!is_array($engine)){
return "$engine $product_name";
}
}
return $product_name;
}
}
...and this works as it should. Then I added the following to:
/app/design/frontend/vendor/theme/Magento_Catalog/layout/catalog_product_view.xml
<referenceBlock name="page.main.title">
<action method="setPageTitle">
<argument name="title" xsi:type="helper" helper="MyNamespace\MyModule\Helper\Data::getTitle"></argument>
</action>
</referenceBlock>
...but it changes nothing on the product page. I know it's getting called as I can echo out the vars and they show at the top of the page, but it seems that the XML isn't doing what I hoped it would.
Anyone got any ideas?
So, tried multiple variations of achieving what I wanted but in the end, I created a template under Magento_Catalog/templates/product
(in my theme), which was based of the magento-theme title.phtml
and then modified the page.main.title
block in the catalog_product_view
layout file.
The template code may look a bit odd (getAttribute
and then getAttributeText
) but there's no error handling for getAttributeText
and with getAttribute
, if an attribute has multiple values, it's returned in a string, not an array like getAttributeText
. It would have been nicer if I could have made sure the value was always present by checking which attribute set was being used but although getAttributeSetId
is part of the product model, it's not available in the product/view
interceptor and tbh, I've given up on trying to figure out how all that works!
Anyway, this has taken far more hours than I'd care to admit to figure out so here's the code, hope it helps someone!
Template:
<?php
$product = $block->getProduct();
$product_name = $product->getName();
$attr_exists = $product->getResource()->getAttribute('attr_code');
$title = $product_name;
$cssClass = $block->getCssClass() ? ' ' . $block->getCssClass() : '';
if ($attr_exists){
$attr_name = $product->getAttributeText('attr_code');
if (!is_array($attr_name)){
$title = "$attr_name $product_name";
}
}
?>
<?php if ($title): ?>
<div class="page-title-wrapper<?= /* @escapeNotVerified */ $cssClass ?>">
<h1 class="page-title"
<?php if ($block->getId()): ?> id="<?= /* @escapeNotVerified */ $block->getId() ?>" <?php endif; ?>
<?php if ($block->getAddBaseAttributeAria()): ?>
aria-labelledby="<?= /* @escapeNotVerified */ $block->getAddBaseAttributeAria() ?>"
<?php endif; ?>>
<?= /* @escapeNotVerified */ $title ?>
</h1>
<?= $block->getChildHtml() ?>
</div>
<?php endif; ?>
Layout:
<block name="page.main.title" class="Magento\Catalog\Block\Product\View" template="Magento_Catalog::product/product-h1.phtml" />