0

I want to edit HTML of "Url key" field in product editing form in Magento 2 admin area appending some additional HTML to it. Magento 2.2.9.

I tried editing method UrlKeyRenderer::getElementHtml() but this method doesn't seem to be called when I open the product editing page, because if I change what the method returns or even if I just throw a LocalizedException at the beginning of the method, nothing is changed on the product editing page.

Cleaning page cache with bin/magento cache:flush doesn't help.

How do I change the field's HTML?

This is the field I want to edit:

enter image description here

  • what kind of HTML you want to attach with it? – Hassan Ali Shahzad Nov 3 at 18:10
  • @HassanAliShahzad Why does it matter? A link. – jojman Nov 3 at 19:17
  • Do you want to edit this: prntscr.com/pt6mxn ?? – Els den Iep Nov 6 at 11:14
  • @ElsdenIep Yup, added this image to the post – jojman Nov 7 at 14:28
  • please show us your code – Philipp Sander Nov 7 at 14:34
1
+50

You can override html template that assigned for URL Key field by below method

app/code/Vendor/Module/etc/adminhtml/di.xml

Create modifier pool to modify product admin form

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\Pool">
        <arguments>
            <argument name="modifiers" xsi:type="array">
                <item name="customhtml" xsi:type="array">
                    <item name="class" xsi:type="string">Vendor\Module\Ui\DataProvider\Product\Form\Modifier\CustomHtml</item>
                    <item name="sortOrder" xsi:type="number">100</item>
                </item>
            </argument>
        </arguments>
    </virtualType>
</config>

app/code/Vendor/Module/Ui/DataProvider/Product/Form/Modifier/CustomHtml.php

Add your custom component for url key

<?php
namespace Vendor\Module\Ui\DataProvider\Product\Form\Modifier;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
use Magento\Framework\Stdlib\ArrayManager;

/**
 * Data provider for customhtml
 */
class CustomHtml extends AbstractModifier
{

    const XML_PATH_SEO_SAVE_HISTORY = 'catalog/seo/save_rewrites_history';

    /**
     * @var ArrayManager
     */
    protected $arrayManager;

    /**
     * @param ArrayManager $arrayManager
     */
    public function __construct(
        ArrayManager $arrayManager
    ) {
        $this->arrayManager = $arrayManager;
    }

    public function modifyMeta(array $meta)
    {

        $meta = $this->addCustomHtml($meta);
        return $meta;
    }

    /**
     * {@inheritdoc}
     */
    public function modifyData(array $data)
    {
        return $data;
    }

    private function addCustomHtml(array $meta)
    {
        $urlPath = $this->arrayManager->findPath(
            ProductAttributeInterface::CODE_SEO_FIELD_URL_KEY,
            $meta,
            null,
            'children'
        );
        if ($urlPath) {
            $containerPath = $this->arrayManager->slicePath($urlPath, 0, -2);
            $meta = $this->arrayManager->merge($containerPath, $meta, [
                'arguments' => [
                    'data' => [
                        'config' => [
                            'component' => 'Vendor_Module/js/form/components/group',
                        ],
                    ],
                ],
            ]);
        }

        return $meta;
    }
}

app/code/Vendor/Module/view/adminhtml/web/js/form/components/group.js

Add your custom template in your component

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

/**
 * @api
 */
define([
    'underscore',
    'uiCollection'
], function (_, Collection) {
    'use strict';

    return Collection.extend({
        defaults: {
            visible: true,
            label: '',
            showLabel: true,
            required: false,
            template: 'ui/group/group',//Modify this for fieldset
            fieldTemplate: 'Vendor_Module/form/field',//Modify this for field
            breakLine: true,
            validateWholeGroup: false,
            additionalClasses: {}
        },

        /**
         * Extends this with defaults and config.
         * Then calls initObservable, iniListenes and extractData methods.
         */
        initialize: function () {
            this._super()
                ._setClasses();

            return this;
        },

        /**
         * Calls initObservable of parent class.
         * Defines observable properties of instance.
         *
         * @return {Object} - reference to instance
         */
        initObservable: function () {
            this._super()
                .observe('visible')
                .observe({
                    required: !!+this.required
                });

            return this;
        },

        /**
         * Extends 'additionalClasses' object.
         *
         * @returns {Group} Chainable.
         */
        _setClasses: function () {
            var additional = this.additionalClasses,
                classes;

            if (_.isString(additional)) {
                additional = this.additionalClasses.split(' ');
                classes = this.additionalClasses = {};

                additional.forEach(function (name) {
                    classes[name] = true;
                }, this);
            }

            _.extend(this.additionalClasses, {
                'admin__control-grouped': !this.breakLine,
                'admin__control-fields': this.breakLine,
                required:   this.required,
                _error:     this.error,
                _disabled:  this.disabled
            });

            return this;
        },

        /**
         * Defines if group has only one element.
         * @return {Boolean}
         */
        isSingle: function () {
            return this.elems.getLength() === 1;
        },

        /**
         * Defines if group has multiple elements.
         * @return {Boolean}
         */
        isMultiple: function () {
            return this.elems.getLength() > 1;
        },

        /**
         * Returns an array of child components previews.
         *
         * @returns {Array}
         */
        getPreview: function () {
            return this.elems.map('getPreview');
        }
    });
});

app/code/Vendor/Module/view/adminhtml/web/template/form/field.html

You can add your html here

<!--
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<div class="admin__field"
     visible="visible"
     css="$data.additionalClasses"
     attr="'data-index': index">
    <div class="admin__field-label" visible="$data.labelVisible">
        <label if="$data.label"  attr="for: uid">
            <span translate="label" attr="'data-config-scope': $data.scopeLabel" />
        </label>
    </div>
    <div class="admin__field-control"
         css="'_with-tooltip': $data.tooltip, '_with-reset': $data.showFallbackReset && $data.isDifferedFromDefault">
        <render args="elementTmpl" ifnot="hasAddons()"/>

        <div class="admin__control-addon" if="hasAddons()">
            <render args="elementTmpl"/>

            <label class="admin__addon-prefix" if="$data.addbefore" attr="for: uid">
                <span text="addbefore"/>
            </label>
            <label class="admin__addon-suffix" if="$data.addafter" attr="for: uid">
                <span text="addafter"/>
            </label>
        </div>

        <render args="tooltipTpl" if="$data.tooltip"/>

        <render args="fallbackResetTpl" if="$data.showFallbackReset && $data.isDifferedFromDefault"/>

        <label class="admin__field-error" if="error" attr="for: uid" text="error"/>

        <div class="admin__field-note" if="$data.notice" attr="id: noticeId">
            <span translate="notice"/>
        </div>

        <div class="admin__additional-info" if="$data.additionalInfo" html="$data.additionalInfo"></div>

        <render args="$data.service.template" if="$data.hasService()"/>
    </div>
</div>
0

Why do you want to edit that in such a complicated way? I am not sure what you want to accomplish but anyway, here are some tips.

Please let me know if any of this helped you out.

  • You did not understand the problem. The accepted answer solves it – jojman Nov 11 at 21:57
  • You are welcome. – Els den Iep Nov 13 at 8:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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