Getting enriched product data onto Adobe Commerce product pages
How enriched product attributes move from Adobe Commerce's EAV model to the PDP: layout XML, block/template binding, schema markup, and validation.

Enriching a product's data is only half the job — a spec, use-case, or identifier only earns its keep once it's actually rendered on the product detail page (PDP) where a buyer or an AI crawler can read it. Adobe Commerce stores that data in a flexible attribute model, but getting a given attribute from the database onto the page involves a specific chain: attribute configuration, attribute set assignment, layout XML, and a block/template pair. This guide walks through that chain end to end, with a concrete example and a validation checklist.
Where the data actually lives
Adobe Commerce stores product data using an EAV (Entity-Attribute-Value) model. Every product attribute — color, material, weight_capacity, a custom use_case field you've enriched — is defined once in Stores > Attributes > Product and then assigned to one or more Attribute Sets, which is what makes the attribute appear on a given product's edit form and, ultimately, available to render.
When you create or edit an attribute, the Storefront Properties section is what determines whether it can reach the PDP at all:
- Visible on Catalog Pages on Storefront — the main switch; without this set to Yes, the attribute never renders on the frontend regardless of any template work.
- Used in Product Listing — controls availability on category/listing pages (and in the REST/GraphQL product-listing payload).
- Used for Sorting in Product Listing — lets shoppers sort listings by the attribute; unrelated to PDP rendering but easy to confuse with it.
A separate Add to Column Options checkbox lives in the Advanced Attribute Properties section of the same attribute form, not in Storefront Properties. It only adds the attribute as a column in the admin product grid and has no effect on the storefront.
This is the first fork in the road: if you just need the enriched value to show up somewhere reasonable, flipping "Visible on Catalog Pages on Storefront" to Yes is often enough — Adobe Commerce's default Magento\Catalog\Block\Product\View\Attributes block (template Magento_Catalog::product/view/attributes.phtml) loops through every attribute in the product's assigned attribute set with that flag enabled and renders it as a row in the PDP's "More Information" tab (often called "Additional Information" in older guides — same tab). No code required.
When the default tab isn't enough
The "More Information" tab is a fine catch-all, but it's not where you want your best enriched content — a differentiating spec, a compliance certification, a compatibility note — buried below the fold in a collapsed accordion. Placing an attribute in the main product info column (next to price, under the short description, near the add-to-cart button) requires customizing layout XML.
The relevant handle is catalog_product_view.xml, loaded on every PDP. A theme-level override lives at:
app/design/frontend/<Vendor>/<theme>/Magento_Catalog/layout/catalog_product_view.xml
Inside it, you declare a block bound to a template, and pass the attribute code as an argument so the block knows which value to pull:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="product.info.main">
<block class="Magento\Catalog\Block\Product\View\Description"
name="product.info.use_case"
template="Magento_Catalog::product/view/attribute.phtml"
after="product.info.price">
<arguments>
<argument name="at_call" xsi:type="string">getUseCase</argument>
<argument name="at_code" xsi:type="string">use_case</argument>
<argument name="css_class" xsi:type="string">use-case</argument>
<argument name="at_label" xsi:type="string">default</argument>
<argument name="add_attribute" xsi:type="string">itemprop="use_case"</argument>
</arguments>
</block>
</referenceContainer>
</body>
</page>
A few things worth noting about this pattern:
at_callis the getter Adobe Commerce invokes on the product model (getUseCase()for ause_caseattribute code, following the standard EAV magic-getter convention).templatemust be namespaced (Module::path) so Commerce resolves it from the module'sview/frontend/templates/directory, or your theme's override of it.add_attributelets you inject arbitrary HTML attributes — includingitemprop, which is how you tie a custom field into schema.org microdata for structured-data purposes.product.info.mainis a layout container, not a block, in Adobe Commerce's defaultcatalog_product_view.xml— reference it withreferenceContainer, notreferenceBlock(usingreferenceBlockagainst a container name is a common copy-paste mistake, and it silently fails to place anything). Combined withafter="product.info.price", this puts the new block above the fold, next to price, rather than in the tab.at_labelset todefaulttells the template to pull the attribute's configured storefront label instead of a hardcoded string, so it stays in sync with whatever the attribute is named in Stores > Attributes > Product.
How the block hands data to the HTML
The block class (PHP) and the .phtml template are strictly separated: the block resolves and formats data, the template only echoes it. Layout XML arguments become properties accessible in the template through $block->getData('argument_name') or the magic accessor $block->getArgumentName(). This separation is why you rarely need to touch PHP for a straightforward attribute placement — the generic attribute.phtml template already knows how to read at_call, at_code, css_class, at_label, and add_attribute, and emits markup along these lines:
<div class="product attribute use-case">
<strong class="type">Ideal use case</strong>
<div class="value" itemprop="use_case">Marine-grade fastener for wet, high-vibration environments</div>
</div>
Out of the box, Adobe Commerce's Luma theme wraps the PDP in itemscope itemtype="http://schema.org/Product" and adds itemprop="name" on the title, itemprop="image" on the main image, and itemprop="sku" on the SKU block — but that default microdata stops there. Luma does not ship a complete itemprop="offers"/schema.org/Offer block for price and availability, which is a well-documented reason default product pages often fail Google's rich-results checks without extra template work or a structured-data extension. Any enriched attribute you add with an itemprop, as above, at least extends the Product-level microdata that does exist rather than starting a disconnected graph — useful for AI agents parsing the page for structured facts even where full Offer markup is still missing.
How to validate
- Reindex and clear cache first. Attribute value changes are served through the Product EAV indexer (
catalog_product_attribute); layout/template changes go through the page and block HTML cache. After any change, run:
If indexers run on schedule (recommended for production), a stale cron run — not your code — is the most common reason a change "isn't showing."bin/magento indexer:reindex catalog_product_attribute bin/magento cache:flush - Compare view-source to the rendered DOM. Because standard Adobe Commerce PDPs (Luma-based, non-headless) are server-rendered,
curl -s https://yourstore.com/your-product.htmlshould return the same attribute markup you see in the browser's rendered DOM. If curl shows the value but the rendered page doesn't, suspect a full-page-cache (Varnish/Fastly) entry serving stale HTML rather than an indexing problem; if the rendered DOM shows it but curl doesn't, suspect client-side JS injection instead of server-side rendering. - Grep for the marker you added:
curl -s https://yourstore.com/your-product.html | grep -A2 'itemprop="use_case"' - Run Google's Rich Results Test on the live URL to confirm whatever Product-level microdata does exist parses cleanly with your new
itempropfolded in, and to see what's missing — on a default Luma theme, expect it to flag absent Offer/price/availability markup regardless of your change; that's a separate, pre-existing gap, not something your attribute placement caused. - Redeploy static view files in production mode (
bin/magento setup:static-content:deploy -f) if CSS/JS tied to your layout change isn't showing, and clearvar/cacheandvar/page_cacheif a new.phtmlfile or block still doesn't render — production mode is stricter about picking up filesystem changes than developer mode.
Verified as of July 2026 against Adobe Commerce/Magento Open Source frontend and catalog documentation; menu paths and indexer names are for current Commerce/Open Source releases and can shift slightly by version, so confirm against your instance's admin before shipping.
This whole chain assumes the attribute value is already correct, current, and worth showing — which is the part Anglera is built for. Anglera keeps attributes like the use_case field above enriched and current in your PIM or directly in Commerce, so the layout and template work described here has accurate, complete data to render rather than a blank field or a stale one.
