Creating a Custom Product Attributes Tab in Magento 2

By default, the Magento product page includes a tab of product data called “Additional Details.” This data is taken from any Product Attributes in the…
  • Elliot Toman
  • Customer Success Manager
  • May 9, 2018 Estimated reading time: 8 minutes

By default, the Magento product page includes a tab of product data called “Additional Details.” This data is taken from any Product Attributes in the product’s assigned Attribute Set that are filled in.

These attributes are displayed as tabular data in the order to which they are assigned to their Attribute Set. Attribute sets can be organized into Groups (such as the Product Details folder seen in the above example), but this has no effect on the Additional Info tab. What if you want a tab that displays Product Attributes, but with more control? For example, the ability to choose which attributes to display, how to group them, and what markup should be used to contain them?
This tutorial will take you step-by-step through the process of replacing the default Additional Info tab with a customized version in which every element is under your control, using simple development techniques. It is probably not the only method of solving the problem, but this process was straightforward and worked for us. This article assumes that you have a basic understanding of Magento’s dashboard and have access to its file structure via SSH or SFTP.
This tutorial will teach you how to:

  1. Create a Product Attribute
  2. Call a Product Attribute inside a PHTML template
  3. Remove Magento’s standard Product Attributes tab and replace it with your own

Step 1: Define and Create the Attributes

Before we begin development, we will want to know exactly what Attributes will be displayed in our new tab. For this tutorial, let’s assume that we want all products to display attributes like this:

Tech Specs
Measurements 2 x 2 x 0.33
Weight 0.05
Inner Diameter 0.25
Teeth 16

 

Usage Parameters
Tensile Strength 0.018
Interlock Standard
Placement Protocol Inverted
Compatibility Jefferies/Bussard

 

The only default Attribute in this set is “Weight,” so we’ll need to create the rest in the Magento Admin » Stores » Attributes » Product.  Then select Add New Attribute to get started.

The Attributes can have any properties you want, but be sure to pay attention to the Attribute Codes, because you’ll use them in the next step. The Attribute Codes can always be viewed in the first column Product Attributes grid.

Next, we’ll need to create a template that loads and displays the attributes.

Step 2: The Attributes Template

Create a new file in the following location of Magento’s file structure:

/app/design/frontend/[Vendor]/[yourtheme]/Magento_Catalog/templates/product/view

The directory names in [brackets] should be replaced with the vendor name and theme ID that you are using. If any of these directories do not exist in your theme yet, go ahead and create them. You can name the template file anything you want as long as it uses the .phtml extension.  In this demo, we’ll use default.phtml.

The template file should contain the following code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

/**
 * Product additional attributes template
 *
 * @var $block \Magento\Catalog\Block\Product\View\Details
 */
?>
<?php
    $_helper = $this->helper('Magento\Catalog\Helper\Output');
    $_product = $block->getProduct();

    /* Demo Attributes */
    $att_measurements = $_product->getAttributeText('demo_measurements');
    $weight = $_product->getData('weight');
    $att_inner_diameter = $_product->getAttributeText('demo_inner_diameter');
    $att_teeth = $_product->getAttributeText('demo_teeth');
    $att_tensile_strength = $_product->getAttributeText('demo_tensile_strength');
    $att_interlock = $_product->getAttributeText('demo_interlock');
    $att_placement_protocol = $_product->getAttributeText('demo_placement_protocol');
    $att_compatibility = $_product->getAttributeText('demo_compatibility');

?>



<section id="product-details-tab">


    <h3 class="table-caption"><?= /* @escapeNotVerified */ __('Tech Specs') ?></h3>
    <table class="attributes-table" id="tech-specs">
        <tbody>
            <tr>
                <th class="col label" scope="row">Make</th>
                <td class="col data"><?php if( $att_measurements != '' ) { echo $att_measurements; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
            <tr>
                <th class="col label" scope="row">Weight</th>
                <td class="col data"><?php if( $weight != '' ) { echo $weight; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
            <tr>
                <th class="col label" scope="row">Inner Diameter</th>
                <td class="col data"><?php if( $att_inner_diameter != '' ) { echo $att_inner_diameter; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
            <tr>
                <th class="col label" scope="row">Teeth</th>
                <td class="col data"><?php if( $att_teeth != '' ) { echo $att_teeth; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
        </tbody>
    </table>



    <h3 class="table-caption"><?= /* @escapeNotVerified */ __('Usage Parameters') ?></h3>
    <table class="attributes-table" id="usage-parameters">
        <tbody>
            <tr>
                <th class="col label" scope="row">Tensile Strength</th>
                <td class="col data"><?php if( $att_tensile_strength != '' ) { echo $att_tensile_strength; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
            <tr>
                <th class="col label" scope="row">Interlock</th>
                <td class="col data"><?php if( $att_interlock != '' ) { echo $att_interlock; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
            <tr>
                <th class="col label" scope="row">Placement Protocol</th>
                <td class="col data"><?php if( $att_placement_protocol != '' ) { echo $att_placement_protocol; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
            <tr>
                <th class="col label" scope="row">Compatability</th>
                <td class="col data"><?php if( $att_compatibility != '' ) { echo $att_compatibility; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?></td>
            </tr>
        </tbody>
    </table>

</section>

 

Here’s the code that you might want to customize for calling the attributes:


$att_measurements = $_product->getAttributeText(‘demo_measurements‘);

$att_measurements is the function that is used to reference the attribute later in the template. demo_measurements is the Attribute ID itself.

This is the code for how the attributes will be displayed in the tab:

<?php if( $att_measurements != '' ) { echo $att_measurements; } else { echo '<span class="no-attribute-value">N/A</span>'; } ?>

 

This tells Magento to output the Attribute value if it exists, and if not, to output “N/A” instead.

If you know a little bit about HTML or PHP, you’ll know that there are lots of other options for displaying the attribute values. For example, you could use a different conditional statement to only display an attribute if it has a value and to ignore it otherwise.

Now that the custom template has been created, we’ll need to tell Magento to display this Attributes tab instead of its regular one.

Step 3: The Layout File

In your code editor, open:
/app/design/frontend/Vendor/yourtheme/Magento_Catalog/layout/catalog_product_view.xml

catalog_product_view.xml is the layout file that Magento uses to determine how the product page is structured. If it doesn’t already exist in your theme, copy the file from its parent theme.

The first thing we’ll do is remove the standard Product Attributes tab by adding this code:

<!-- Remove default Attributes tab -->
<referenceBlock name="product.attributes" remove="true" />

 

Technically, you can skip that step; the standard tab and your custom tab can exist side-by-side without a problem. For the sake of our example, however, we only want to see the custom tab.

Now, we’ll add the code that includes our new template in the product detail tabs:

<!-- Add Product Details Tab -->
            <block class="Magento\Catalog\Block\Product\View\Description" name="details" template="Magento_Catalog::product/view/details.phtml" group="detailed_info" before="-">
                <arguments>
                <argument name="at_call" xsi:type="string">getDetails</argument>
                <argument name="at_code" xsi:type="string">details</argument>
                <argument name="css_class" xsi:type="string">details</argument>
                <argument name="title" translate="true" xsi:type="string">Product Details</argument>
                </arguments>
            </block>

 

Note that if you’ve used a different name for the template than details.phtml, that will need to be reflected in the code block.

That’s it! Once you’ve cleared Magento’s cache, you should see the standard Product Attributes tab replaced with your custom tab that includes exactly the Attributes you want and none that you don’t.

Step 4: Test and Customize

The point of this exercise is customization, so of course you’ll want to use this as a launching board for your own ideas. From here, you can:

  • Include your own Product Attributes by replacing the template functions.
  • Customize the display method of the attributes by customizing the template’s HTML markup.
  • Customize the style of the tab by updating your stylesheets.

As mentioned at the beginning of the article, this method is probably not the only way of meeting this challenge. Try it out, let us know how it works, and feel free to share in the comments if you have ideas for improving this solution. Good luck!

Related Services