{"id":13158,"date":"2021-02-04T12:31:32","date_gmt":"2021-02-04T12:31:32","guid":{"rendered":"https:\/\/www.mageworx.com\/blog\/?p=13158"},"modified":"2021-10-25T09:51:12","modified_gmt":"2021-10-25T09:51:12","slug":"magento-2-add-custom-field-to-product-option-templates","status":"publish","type":"post","link":"https:\/\/www.mageworx.com\/blog\/add-custom-field-to-apo-option-templates","title":{"rendered":"Magento 2: Add Custom Field to Product Option Templates"},"content":{"rendered":"\n<!-- SEO Ultimate (http:\/\/www.seodesignsolutions.com\/wordpress-seo\/) - Code Inserter module -->\n<!-- Google Tag Manager (noscript) -->\r\n<noscript><iframe src=\"https:\/\/www.googletagmanager.com\/ns.html?id=GTM-5DTCW7B8\"\r\nheight=\"0\" width=\"0\" style=\"display:none;visibility:hidden\"><\/iframe><\/noscript>\r\n<!-- End Google Tag Manager (noscript) -->\n<!-- \/SEO Ultimate -->\n\n<span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>\n<p>The Advanced Product Options extension allows you to deal not only with options on product pages but to create various option templates and mass-assign them to specific products.<br><\/p>\n\n\n\n<p>This article provides you with step-by-step guidelines on adding custom fields Magento for options and option templates in compliance with the <a href=\"https:\/\/www.mageworx.com\/magento-2-advanced-product-options-suite.html\">Advanced Product Options<\/a> (APO) best practices and standards.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">What are Advanced Custom Fields?<\/h2>\n\n\n\n<p>The Advanced Product Options extension was built to offer versatile possibilities. However, as every business is different and distinct, customization can be required to complement one-off objectives. This is especially the case when mass-assigning option templates and the added advanced product fields to your offerings.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Step-by-Step Guidelines<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Before We Begin<\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Read the article about how to add a new field in custom option, Magento. It\u2019s available <a href=\"https:\/\/www.mageworx.com\/blog\/how-to-add-custom-field-to-advanced-product-options-extension\" target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\" (opens in a new tab)\">here<\/a>.<\/li><\/ul>\n\n\n\n<p>We will use and modify the example from the mentioned blog post, where we added a Magento 2 custom field to APO.<\/p>\n\n\n<p><a href=\"https:\/\/www.mageworx.com\/blog\/native-magento-product-options-vs-mageworx-product-options\"><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-13122 aligncenter\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/2_Magento-2-Native-Product-Options-vs.-Mageworx-Advanced-Product-Options.png\" alt=\"Magento product options\" width=\"690\" height=\"190\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/2_Magento-2-Native-Product-Options-vs.-Mageworx-Advanced-Product-Options.png 690w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/2_Magento-2-Native-Product-Options-vs.-Mageworx-Advanced-Product-Options-600x165.png 600w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/2_Magento-2-Native-Product-Options-vs.-Mageworx-Advanced-Product-Options-250x69.png 250w\" sizes=\"auto, (max-width: 690px) 100vw, 690px\" \/><\/a><\/p>\n\n\n<h3 class=\"wp-block-heading\">Step #1. Class Rewrite<\/h3>\n\n\n\n<p>Tables that are created for templates store all the necessary attributes as the core Magento tables.<\/p>\n\n\n\n<p>When we Magento add a custom field to product option or attribute for an option or its values, it\u2019s also required to add this advanced custom field to templates right off. Unless you don\u2019t intend to use it in the templates.&nbsp;<\/p>\n\n\n\n<p>For this purpose, we created the custom `app\/code\/MageWorx\/OptionBase\/Model\/Installer.php` installer in our main Option_Base module.<\/p>\n\n\n\n<p>This installer helps you to Magento add fields for options, option values, and templates more conveniently.<\/p>\n\n\n\n<p>Unlike in the previous example where we created a schema of the required field in <code>app\/code\/VendorName\/OptionGtin\/Setup\/InstallSchema.php<\/code>, we will need to rewrite this class and add a connection to our custom installer:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\nnamespace VendorName\\OptionGtin\\Setup;\n\nuse Magento\\Framework\\Setup\\InstallSchemaInterface;\nuse Magento\\Framework\\Setup\\ModuleContextInterface;\nuse Magento\\Framework\\Setup\\SchemaSetupInterface;\n\n\/**\n * @codeCoverageIgnore\n *\/\nclass InstallSchema implements InstallSchemaInterface\n{\n    \/**\n     * @var \\MageWorx\\OptionBase\\Model\\Installer\n     *\/\n    protected $optionBaseInstaller;\n\n    \/**\n     * @param \\MageWorx\\OptionBase\\Model\\Installer $optionBaseInstaller\n     *\/\n    public function __construct(\n        \\MageWorx\\OptionBase\\Model\\Installer $optionBaseInstaller\n    ) {\n        $this-&gt;optionBaseInstaller = $optionBaseInstaller;\n    }\n\n    \/**\n     * {@inheritdoc}\n     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)\n     *\/\n    public function install(SchemaSetupInterface $setup, ModuleContextInterface $context)\n    {\n        $installer = $setup;\n        $installer-&gt;startSetup();\n\n        $this-&gt;optionBaseInstaller-&gt;install();\n\n        $installer-&gt;endSetup();\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step # 2. Dependency Injection Rewrite<\/h3>\n\n\n\n<p>Next, let\u2019s rewrite `dependency injection` and change `app\/code\/VendorName\/OptionGtin\/etc\/di.xml` by adding our custom installer:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\"?&gt;\n&lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:ObjectManager\/etc\/config.xsd\"&gt;\n    &lt;!-- Data --&gt;\n    &lt;type name=\"MageWorx\\OptionBase\\Model\\Product\\Option\\Attributes\"&gt;\n        &lt;arguments&gt;\n            &lt;argument name=\"data\" xsi:type=\"array\"&gt;\n                &lt;item name=\"gtin\" xsi:type=\"object\"&gt;VendorName\\OptionGtin\\Model\\Attribute\\Option\\Gtin&lt;\/item&gt;\n            &lt;\/argument&gt;\n        &lt;\/arguments&gt;\n    &lt;\/type&gt;\n    &lt;!-- Installation --&gt;\n    &lt;type name=\"MageWorx\\OptionBase\\Model\\Installer\"&gt;\n        &lt;arguments&gt;\n            &lt;argument name=\"installSchema\" xsi:type=\"array\"&gt;\n                &lt;item name=\"option_gtin_install_schema_data\" xsi:type=\"object\"&gt;VendorName\\OptionGtin\\Model\\InstallSchema&lt;\/item&gt;\n            &lt;\/argument&gt;\n        &lt;\/arguments&gt;\n    &lt;\/type&gt;\n&lt;\/config&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step #3. New Class Creation<\/h3>\n\n\n\n<p>It\u2019s time to create a class that contains schemas of the required fields that used to be located in `app\/code\/VendorName\/OptionGtin\/Setup\/InstallSchema.php`.<\/p>\n\n\n\n<p>Create the `app\/code\/VendorName\/OptionGtin\/Model\/InstallSchema.php` class with the following code:<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\nnamespace VendorName\\OptionGtin\\Model;\n\nuse Magento\\Framework\\DB\\Ddl\\Table;\n\nclass InstallSchema implements \\MageWorx\\OptionBase\\Api\\InstallSchemaInterface\n{\n    \/**\n     * Get module table prefix\n     *\n     * @return string\n     *\/\n    public function getModuleTablePrefix()\n    {\n        return '';\n    }\n\n    \/**\n     * Retrieve module fields data array\n     *\n     * @return array\n     *\/\n    public function getData()\n    {\n        $dataArray = &#91;\n            &#91;\n                'table_name' =&gt; 'catalog_product_option',\n                'field_name' =&gt; 'gtin',\n                'params'     =&gt; &#91;\n                    'type'     =&gt; Table::TYPE_INTEGER,\n                    'unsigned' =&gt; true,\n                    'nullable' =&gt; false,\n                    'comment'  =&gt; 'Option gtin',\n                ]\n            ],\n\n        ];\n\n        return $dataArray;\n    }\n\n    \/**\n     * Retrieve module indexes data array\n     *\n     * @return array\n     *\/\n    public function getIndexes()\n    {\n        return &#91;];\n    }\n\n    \/**\n     * Retrieve module foreign keys data array\n     *\n     * @return array\n     *\/\n    public function getForeignKeys()\n    {\n        return &#91;];\n    }\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step #4. Version Increase<\/h3>\n\n\n\n<p>As we already have the installed OptionGtin module with the `gtin` field in the `catalog_product_option` table, it\u2019s required to create its one class and increase the version of the extension.<\/p>\n\n\n\n<p>We need the version increase to run the installation once again and finish the `gtin` field installation to the required templates\u2019 table.<\/p>\n\n\n\n<p>`app\/code\/VendorName\/OptionGtin\/Setup\/UpgradeSchema.php`<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?php\nnamespace VendorName\\OptionGtin\\Setup;\n\nuse Magento\\Framework\\Setup\\UpgradeSchemaInterface;\nuse Magento\\Framework\\Setup\\ModuleContextInterface;\nuse Magento\\Framework\\Setup\\SchemaSetupInterface;\nuse MageWorx\\OptionFeatures\\Model\\OptionDescription;\nuse MageWorx\\OptionFeatures\\Model\\OptionTypeDescription;\nuse MageWorx\\OptionFeatures\\Model\\Image;\nuse MageWorx\\OptionFeatures\\Model\\OptionTypeIsDefault;\n\nclass UpgradeSchema implements UpgradeSchemaInterface\n{\n    \/**\n     * @var \\MageWorx\\OptionBase\\Model\\Installer\n     *\/\n    protected $optionBaseInstaller;\n\n    \/**\n     * @var SchemaSetupInterface\n     *\/\n    protected $setup;\n\n    \/**\n     * UpgradeSchema constructor.\n     *\n     * @param \\MageWorx\\OptionBase\\Model\\Installer $optionBaseInstaller\n     *\/\n    public function __construct(\n        \\MageWorx\\OptionBase\\Model\\Installer $optionBaseInstaller\n    ) {\n        $this-&gt;optionBaseInstaller = $optionBaseInstaller;\n    }\n\n    \/**\n     * {@inheritdoc}\n     *\/\n    public function upgrade(SchemaSetupInterface $setup, ModuleContextInterface $context)\n    {\n        $this-&gt;setup = $setup;\n\n        $this-&gt;optionBaseInstaller-&gt;install();\n\n    }\n\n}<\/code><\/pre>\n\n\n\n<p>Now, increase the version of the module:<\/p>\n\n\n\n<p>`app\/code\/VendorName\/OptionGtin\/etc\/module.xml`<br><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;?xml version=\"1.0\"?&gt;\n\n&lt;config xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"urn:magento:framework:Module\/etc\/module.xsd\"&gt;\n    &lt;module name=\"VendorName_OptionGtin\" setup_version=\"1.0.1\"&gt;\n        &lt;sequence&gt;\n            &lt;module name=\"Magento_Catalog\"\/&gt;\n            &lt;module name=\"MageWorx_OptionBase\"\/&gt;\n            &lt;module name=\"MageWorx_OptionFeatures\"\/&gt;\n        &lt;\/sequence&gt;\n    &lt;\/module&gt;\n&lt;\/config&gt;<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Step #5. Finale<\/h3>\n\n\n\n<p>All the hard work is over. The only thing left is to run the `bin\/magento setup:upgrade` installation command and check that our field is written in the corresponding templates\u2019 table.<br><\/p>\n\n\n\n<p>In our case, it\u2019s the `mageworx_optiontemplates_group_option` table.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1792\" height=\"501\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7.png\" alt=\"add advance custom field to template\" class=\"wp-image-13176\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7.png 1792w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-600x168.png 600w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-1200x335.png 1200w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-768x215.png 768w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-250x70.png 250w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-696x195.png 696w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-1068x299.png 1068w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/download-7-1502x420.png 1502w\" sizes=\"auto, (max-width: 1792px) 100vw, 1792px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Recap<\/h2>\n\n\n\n<p>We hope that you find our series of articles dedicated to increasing the Advanced Product Options customizability useful.<br><\/p>\n\n\n\n<p>Now, you know how to add a custom field to the template and make the best use of the <a href=\"https:\/\/www.mageworx.com\/blog\/custom-product-options-templates-in-magento-2\/\">product option templates<\/a> in Magento 2.<br><\/p>\n\n\n\n<p>If you are missing specific customization possibilities in the Advanced Product Options extension, please submit a request at <a href=\"mailto:support@mageworx.com\">support@mageworx.com<\/a>. We will do our best to help you out!<br><\/p>\n\n\n<p><a href=\"https:\/\/www.mageworx.com\/magento-2-advanced-product-options-suite.html\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-13116 size-full\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/button.png\" alt=\"magento 2 dependent custom options\" width=\"690\" height=\"99\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/button.png 690w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/button-600x86.png 600w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/01\/button-250x36.png 250w\" sizes=\"auto, (max-width: 690px) 100vw, 690px\" \/><\/a><\/p>\n<p>\u00a0<\/p>\n\n<p><a href=\"https:\/\/calendly.com\/kate-volchock\/demo\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-15059 size-full\" src=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/live-demo-1.png\" alt=\"Book a Live Demo with Mageworx\" width=\"690\" height=\"260\" srcset=\"https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/live-demo-1.png 690w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/live-demo-1-600x226.png 600w, https:\/\/www.mageworx.com\/blog\/wp-content\/uploads\/2021\/02\/live-demo-1-250x94.png 250w\" sizes=\"auto, (max-width: 690px) 100vw, 690px\" \/><\/a><\/p>\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p><span class=\"span-reading-time rt-reading-time\" style=\"display: block;\"><span class=\"rt-label rt-prefix\">Reading Time: <\/span> <span class=\"rt-time\"> 3<\/span> <span class=\"rt-label rt-postfix\">minutes<\/span><\/span>The Advanced Product Options extension allows you to deal not only with options on product pages but to create various option templates and mass-assign them to specific products. This article provides you with step-by-step guidelines on adding custom fields Magento for options and option templates in compliance with the Advanced Product Options (APO) best practices [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":13166,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[255,425,426],"tags":[379,436],"class_list":{"0":"post-13158","1":"post","2":"type-post","3":"status-publish","4":"format-standard","5":"has-post-thumbnail","7":"category-magento-2","8":"category-magento-how-tos","9":"category-extensions-tips-and-tricks","10":"tag-apo","11":"tag-developer-diaries"},"_links":{"self":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/13158","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/comments?post=13158"}],"version-history":[{"count":16,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/13158\/revisions"}],"predecessor-version":[{"id":15061,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/posts\/13158\/revisions\/15061"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media\/13166"}],"wp:attachment":[{"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/media?parent=13158"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/categories?post=13158"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.mageworx.com\/blog\/wp-json\/wp\/v2\/tags?post=13158"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}