Search code examples
magento2magento2.2

Magento 2.2 - Append Attribute Name To Product Name (H1)


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?


Solution

  • 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" />