Question

How to remove 255 characters limit from meta keywords field in product in admin while saving or updating existing ?

enter image description here

enter image description here

Was it helpful?

Solution

After some debugging I found out that all inputs have 255 length limit and they all have the same template. The limit is set by the html template itself (kinda hard-coded). The file path is:

vendor/magento/module-ui/view/base/web/templates/form/element/input.html

So we have to override it into a custom adminhtml theme.

Before you start, please replace the "Vendor" and "Theme" with your "Vendor" and "Module" names

If you do not have one:

Create the following files:

app/design/adminhtml/Vendor/Theme/composer.json

{
"name": "<vendor>/<theme>",
"description": "N/A",
"require": {
    "php": "~5.5.0|~5.6.0|~7.0.0",
    "magento/theme-adminhtml-backend": "*",
            "magento/framework": "100.0.*"
},
"type": "magento2-theme",
"version": "1.0.0",
"license": [

],
"autoload": {
    "files": [
        "registration.php"
    ]
}

}

app/design/adminhtml/Vendor/Theme/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::THEME,
    'adminhtml/<Vendor>/<Theme>',
    __DIR__
);

app/design/adminhtml/Vendor/Theme/theme.xml

<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Theme</title>
    <parent>Magento/backend</parent>
</theme>

These are the theme files.

Now we have to create a custom module to make this work:

app/code/Vendor/Theme/registration.php

<?php

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Vendor_Theme',
    __DIR__
);

app/code/Vendor/Theme/composer.json

{
    "name": "vendor/theme",
    "description": "",
    "require": {
        "php": "~5.5.0|~5.6.0|~7.0.0",

        "magento/magento-composer-installer": "*"
    },
    "suggest": {

    },
    "type": "magento2-module",
    "version": "0.1.0",
    "license": [

    ],
    "autoload": {
        "files": [
            "registration.php"
        ],
        "psr-4": {
            "Vendor\\Theme\\": ""
        }
    },
    "extra": {
        "map": [
            [
                "*",
                "Vendor/Theme"
            ]
        ]
    }
}

app/code/Vendor/Theme/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Vendor_Theme" setup_version="0.1.0">
    </module>
</config>

app/code/Vendor/Theme/etc/di.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Theme\Model\View\Design">
        <arguments>
            <argument name="themes" xsi:type="array">
                <item name="adminhtml" xsi:type="string">Vendor/Theme</item>
            </argument>
        </arguments>
    </type>
</config>

Now we have a custom adminhtml(backend) theme that overrides the Magento_Backend theme.

Here comes the magic:

The input template file for ui components is:

vendor/magento/module-ui/view/base/web/templates/form/element/input.html

We copy it in a relative path in our custom theme:

app/design/adminhtml/Vendor/Theme/Magento_Catalog/web/form/element/input.html

We modify the content into:

<!--Overrides: vendor/magento/module-ui/view/base/web/templates/form/element/input.html -->
<!-- ko if: inputName == "product[meta_keyword]" -->
<input class="admin__control-text" type="text"
       data-bind="
        event: {change: userChanges},
        value: value,
        hasFocus: focused,
        valueUpdate: valueUpdate,
        attr: {
            name: inputName,
            placeholder: placeholder,
            'aria-describedby': noticeId,
            id: uid,
            disabled: disabled
    }"/>
<!--/ko-->
<!-- ko ifnot: inputName == "product[meta_keyword]" -->
<input class="admin__control-text" type="text"
       data-bind="
        event: {change: userChanges},
        value: value,
        hasFocus: focused,
        valueUpdate: valueUpdate,
        attr: {
            name: inputName,
            placeholder: placeholder,
            'aria-describedby': noticeId,
            id: uid,
            disabled: disabled,
            maxlength: 255
    }"/>
<!-- /ko -->

As you can see here, we tell to knockoutjs to render the input without the maxlength condition only when the input name is "product[meta_keyword]" (thats our input we want) else, we render the input normally to not do something we don't want to.

Now, we have to make our template override the Magento_Ui template file:

As we see in the Magento_Ui requirejs_config.js of base,

vendor/magento/module-ui/view/base/requirejs-config.js

There is a namespace for the template paths of the ui components:

....
paths: {
    'ui/template': 'Magento_Ui/templates'
},
....

That means all the templates paths that are from "Magento_Ui/templates" are replaced with "ui/template".

So, we create our requirejs_config.js:

app/design/adminhtml/Vendor/Theme/Magento_Catalog/requirejs-config.js

var config = {
    map: {
        "*": {
            "ui/template/form/element/input": "Magento_Catalog/form/element/input"
        }
    }
};

Now clear the cache, clear the static files (or deploy them) and refresh the page, and you should see something like this:

template override inspection

This works for 2.3.1, and it should work for the lower versions

Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top