5

Anybody have idea how to add/update "Custom Layout Update" field of category or product in magento version 2.3.4

According to magento standard document,"You can no longer specify an entity-specific layout update with text but instead must create a physical file that contains the layout updates and select it for use."

But there is no option to select physical file on categories or product edit level.

After upgrade version from 2.3.3 to 2.3.4, which categories have "Custom Layout Update" exist now those are with drop down and "Use existing" selected but which does not have custom layout update those are with "No update" on drop down.

so really confused that how we could add new or update existing?

Please help!

1

10 Answers 10

8

For anyone who has similar issue as @RonSayers (https://magento.stackexchange.com/a/311542/5983) - field without any options when using Porto theme (or any porto child themes).

Porto introduces a set of Smartwave modules, and while they are advertising as fully compatible with Magento 2.3 - they're not.

Smartwave_Megamenu is causing the issue as above. To fix, modify app/code/Smartwave/Megamenu/Model/Category/DataProvider.php and add 'custom_layout_update_file' in the design array.

It will show the options then.

8

As of Magento 2.3.4, merchants can select layout updates to be applied to specific Category/Product/CMS Page pages on the frontend. These layout updates are made by creating layout XML files following specific naming conventions.

For Categories:

catalog_category_view_selectable_<Category ID>_<Layout Update Name>.xml

where:

  • Category ID is desired category ID
  • Layout Update Name is what is shown as the option for Custom layout update field of Design section on Category Edit page.

For Products:

catalog_product_view_selectable_<Product SKU>_<Layout Update Name>.xml

where:

  • Product SKU is the desired product’s SKU encoded as a URI. example: “My Product SKU” -> “My%20Product%20SKU”
  • Layout Update Name is what is shown as the option for Custom layout update field of Design section on Product Edit page.

For CMS Pages:

cms_page_view_selectable_<CMS Page Identifier>_<Layout Update Name>.xml

where:

  • CMS Page Identifier is the desired page’s URL Key with “/” symbols replaced with “_”
  • Layout Update Name is what is shown as the option for Custom layout update field of Design section on CMS Page Edit page

These files must be placed in the appropriate folders for layout XML files. They will be available as Custom Layout Update options for Merchants after flushing the cache.

This is a link to the DevDocs: https://devdocs.magento.com/guides/v2.4/frontend-dev-guide/layouts/xml-manage.html#create-cms-pageproductcategory-specific-selectable-layouts

7
5

Create a custom layout file for category:

app/design/frontend/<Vendorname>/<themename>/Magento_Catalog/layout

catalog_category_view_selectable_<Category ID>_<Layout Update Name>.xml

Also check and save theme setting as Global: Admin > Content > Design > Configuration https://prnt.sc/r89ico

1
  • This saved my day. Needed to set theme as the global theme. Finally!
    – Cypher909
    Mar 22, 2021 at 22:29
1

In version 2.3.4 to add classes to the body tag for example, valid for pages::

<script type="text/javascript">
require([
    'jquery'       
], function (jQuery) {
    (function ($) {
        $("body").addClass('yourclass');
    })(jQuery);
});
</script>
1

Any sort of idea why this has been done? I think is pretty bad to not be able to change Layout XML from the admin area anymore. It just makes it not very flexible. And it means that for any change on layout XML it will require a new deployment and a new file to be created. On a big website we could end up with loads of new XML files having to be created manually. Also, sometimes ID's on local environments are not the same as the ID's in staging or production environment. SO ...I am seeing this new update XML way quite useless.

1
  • 1
    The function was removed from Magento to remove the opportunity for Remote Code Execution. Apr 17, 2020 at 7:15
0

I am struggling like @Bram Hammer. I placed the code below into app/design/frontend/Smartwave/porto_child/Magento_Catalog/layout/catalog_category_view_selectable_115_listview.xml and flushed cache. Porto Child is set to global under Content>Design>Configuration.

<body>
    <referenceContainer name="content">
        <referenceBlock name="product_list_toolbar">
            <action method="setData">
                <argument name="key" xsi:type="string">_current_grid_mode</argument>
                <argument name="value" xsi:type="string">list</argument>
            </action>
        </referenceBlock>
    </referenceContainer>
</body>

enter image description here

I still have no options under Catalog>Categories>ID: 115>Design>Custom Layout Update enter image description here

I'm trying to have category 115 default to list view instead of grid view. Hopefully somebody can see what I'm doing wrong.

0

You should create a module and run the patch

<?php

namespace [vendorname]\[modulename]\Setup\Patch\Data;

use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Catalog\Setup\CategorySetup;
use Magento\Catalog\Setup\CategorySetupFactory;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\Category;

/**
 * Add new custom layout related attributes.
 */
class UpdateCustomLayoutAttributes implements DataPatchInterface
{
    /**
     * @var ModuleDataSetupInterface
     */
    private $moduleDataSetup;

    /**
     * @var CategorySetupFactory
     */
    private $categorySetupFactory;

    /**
     * PatchInitial constructor.
     * @param ModuleDataSetupInterface $moduleDataSetup
     * @param CategorySetupFactory $categorySetupFactory
     */
    public function __construct(
        ModuleDataSetupInterface $moduleDataSetup,
        CategorySetupFactory $categorySetupFactory
    ) {
        $this->moduleDataSetup = $moduleDataSetup;
        $this->categorySetupFactory = $categorySetupFactory;
    }

    /**
     * @inheritDoc
     */
    public static function getDependencies()
    {
        return [];
    }

    /**
     * @inheritDoc
     */
    public function getAliases()
    {
        return [];
    }

    /**
     * @inheritDoc
     */
    public function apply()
    {
        /** @var CategorySetup $eavSetup */
        $eavSetup = $this->categorySetupFactory->create(['setup' => $this->moduleDataSetup]);
        $eavSetup->addAttribute(
            Product::ENTITY,
            'custom_layout_update_file',
            [
                'type' => 'varchar',
                'label' => 'Custom Layout Update',
                'input' => 'select',
                'source' => \Magento\Catalog\Model\Product\Attribute\Source\LayoutUpdate::class,
                'required' => false,
                'sort_order' => 51,
                'backend' => \Magento\Catalog\Model\Product\Attribute\Backend\LayoutUpdate::class,
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                'group' => 'Design',
                'is_used_in_grid' => true,
                'is_visible_in_grid' => true,
                'is_filterable_in_grid' => false
            ]
        );

        $eavSetup->addAttribute(
            Category::ENTITY,
            'custom_layout_update_file',
            [
                'type' => 'varchar',
                'label' => 'Custom Layout Update',
                'input' => 'select',
                'source' => \Magento\Catalog\Model\Category\Attribute\Source\LayoutUpdate::class,
                'required' => false,
                'sort_order' => 51,
                'backend' => \Magento\Catalog\Model\Category\Attribute\Backend\LayoutUpdate::class,
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                'group' => 'Custom Design',
                'is_used_in_grid' => true,
                'is_visible_in_grid' => true,
                'is_filterable_in_grid' => false
            ]
        );

        $eavSetup->updateAttribute(
            Product::ENTITY,
            'custom_layout_update',
            'is_visible',
            true
        );

        $eavSetup->updateAttribute(
            Category::ENTITY,
            'custom_layout_update',
            'is_visible',
            true
        );
    }
}


0

It's very annoying if you have existing code in that field, which you might just want to remove, but can't because you can no longer do that from the admin. In that case use the below SQL to track it down and remove it:

For Categories:

SELECT * FROM `catalog_category_entity_text` WHERE attribute_id = (SELECT attribute_id FROM `eav_attribute` WHERE entity_type_id = 3 AND attribute_code = 'custom_layout_update');

For Products:

SELECT * FROM `catalog_product_entity_text` WHERE attribute_id = (SELECT attribute_id FROM `eav_attribute` WHERE entity_type_id = 4 AND attribute_code = 'custom_layout_update');

For completeness, below is an example delete statement (in my case I was trying to delete some noindex,nofollow meta tags which somebody added years ago, so I would replace the string at the end with '%noindex%'):

DELETE FROM `catalog_product_entity_text` WHERE attribute_id = (SELECT attribute_id FROM `eav_attribute` WHERE entity_type_id = 4 AND attribute_code = 'custom_layout_update') AND `value` LIKE '%string which you want to delete%';
0

Here is info on how you could use the database to clone an existing custom layout to another product.

  • You could alter these steps to edit an existing record
  • I'm using select * instead of select entity_id (etc) to see more details about each record


  1. Access the database with host, username, and password from [magento root]/app/etc/env.php:mysql -h database.rds.amazonaws.com -umagento -p magento
  2. Get the entity_id for the product with the existing custom layout: select * from catalog_product_entity where sku = '[insert SKU here]' \G
  3. Get the entity_id for the NEW product that you desire the existing custom layout on: select * from catalog_product_entity where sku = '[insert SKU here]' \G
  4. Get the value_id for the custom layout text: SELECT * FROM 'catalog_product_entity_text' WHERE attribute_id = (SELECT attribute_id FROM 'eav_attribute' WHERE entity_type_id = 4 AND attribute_code = 'custom_layout_update') and entity_id=[insert **entity_id** for the product with the existing custom layout] \G
  5. Exit mysql shell
  6. mysqldump the record that you need: mysqldump -h database.rds.amazonaws.com -umagento -p magento catalog_product_entity_text --skip-add-drop-table --where="value_id=[insert value_id from step #6]" > catalog_product_entity_text.sql
  7. Trim down the dump file to just the INSERT INTO row: nano catalog_product_entity_text.sql
  8. Replace the value_id with NULL
  9. Replace the old entity_id with the new entity_id
  10. Import the new record: mysql -h database.rds.amazonaws.com -umagento -p magento < catalog_product_entity_text.sql

Flush Magento cache and invalidate cloud cache

0

As per "Ron Sayers" post below, I had the same issue with an empty "Custom Layout Update" dropdown in the Category Design tab. I was also getting an error while trying to edit a category.

Custom layout update text cannot be changed, only removed

My problem was, the Data Patch file

vendor/magento/module-catalog/Setup/Patch/Data/UpdateCustomLatoutAttributes.php

did not run correctly when it was first executed by Magento many months ago.

That Data Patch was present in the DB table patch_list, but checking the DB table eav_attribute.attribute_code "custom_layout_update_file" was not in the database at all.

FIX: In the DB table patch_list delete the row relating to that patch, and run that Data Patch file again: php bin/magento setup:upgrade

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.