Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Product-grid detection: facet-drawer heading becomes a product, names absorb whole card text, slugs drop accents

Open
#3,185 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

@chubes4 is already working on this.

Since Oct 21, 2026.

  • #3187 by @chubes4 — open

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Stale
Tech stack
php, wordpress
Domain
backend, data

Research direction

Start with CommerceStructureRecognizer, html_product_grid_fallback, and ArtifactCompiler::runtimeDeclarationsFromFallbacks() named in the issue; trace how the reduced product card and facet drawer become entities. Add the neutral regression fixture to assert the product name, URL-derived transliterated slug, regular and sale prices, and that the drawer adds no product. Done when those assertions pass and the existing commerce fixture corpus stays green.

Written by the indexing model from the issue text.

Description

Summary

On a storefront collection page, product-grid detection (CommerceStructureRecognizer → html_product_grid_fallback → ArtifactCompiler::runtimeDeclarationsFromFallbacks()) produces wrong product entities in three ways. Measured on a 50-route import (100 entities in one generic/products/v1 declaration):

  1. A filter-drawer heading becomes a product. The heading of an off-canvas facet drawer, FILTRAR <span>0 productos</span> ("Filter · 0 products"), is emitted as products named Filtrar 0 productos, Filtrar 15 productos, … (slugs filtrar-0-productos, filtrar-15-productos). It appears on every collection page, so the false product collects one commerce_collection binding per page (42 bindings, about 5.4 MB) and helps trigger #3184.
  2. Product names absorb the whole card's text. Instead of the card title, names take in the badge, the quick-view button label, every price and the installment line, e.g. Sale Feria Vista rápida Bermuda Duni Lino Marrón $120.900 $48.360 6 cuotas sin interés de $8.060 Precio sin impuestos nacionales: …. productNameText() falls through to "the first element carrying a name/title/product token". The first such element is a wrapper whose class contains product, such as the card custom element or product-card--featured-image, so collapsedText() returns the entire card.
  3. Slugs drop accented letters. The $slug closure in runtimeDeclarationsFromFallbacks() replaces every non-[a-z0-9] byte, so Pantalón Fausti Marrón becomes pantal-n-fausti-marr-n instead of pantalon-fausti-marron. (WordPress's sanitize_title() removes accents first; for comparison, the source's own product URL is /products/pantalon-fausti-marron.)

Reduced card (neutral)

<ul class="grid">
  <li class="columns"><product-card class="product-card">
    <figure class="product-card--featured-image">
      <span class="product-card--badges"><span class="badge">Sale</span></span>
      <a href="/products/pantalon-fausti-marron" title="Pantalón Fausti Marrón"><img src="a.jpg" alt="Pantalón Fausti Marrón"></a>
      <quick-view class="product-card-quickview" data-product-handle="pantalon-fausti-marron"><span>Vista rápida</span></quick-view>
    </figure>
    <div class="product-card-info">
      <a href="/products/pantalon-fausti-marron" title="Pantalón Fausti Marrón" class="product-card-title">Pantalón Fausti Marrón</a>
      <span class="price"><del><span class="amount"><span class="money">$120,900</span></span></del>
        <ins><span class="amount"><span class="money">$48,360</span></span></ins></span>
      <span class="cuotas"> · 6 cuotas sin interés de <span class="money">$8,060</span></span>
    </div>
  </product-card></li>
</ul>

Facet drawer on the same page:

<div class="side-panel facet-drawer" id="Facet-Drawer" inert="">
  <div class="side-panel-header"><div>
    <h4>FILTRAR <span class="filter-count"><span class="facets__label">0 productos</span></span></h4>
  </div></div>
  <div class="side-panel-content"><form><select name="sort_by">
    <option value="price-ascending">Precio, menor a mayor</option>
  </select></form></div>
  <div class="side-panel-footer"><a href="/collections/x">Borrar</a><button class="button"><span>Aplicar</span></button></div>
</div>

Expected

  • No product entity comes from a region with no currency-formatted price and no product link. A count such as "0 productos" is not a price.
  • The product name is the card's own title: an itemprop="name", a heading, or the most specific title or name element (for example the title link). It is never a wrapper that also contains the price, badge or controls. The reduced card yields Pantalón Fausti Marrón, regular price 120900, sale price 48360.
  • Slugs transliterate accents (pantalon-fausti-marron), matching WordPress slug behaviour. Where the card links to a product URL, prefer that URL's last path segment.

Regression fixture

A neutral fixture built from the reduced markup above that asserts the extracted products (name, slug, prices) and asserts that the facet drawer contributes none. It fails on trunk and passes with the fix, and the existing commerce fixture corpus stays green.

AI assistance

Investigated and drafted with Claude (Anthropic) via the Pi coding agent, which dumped the composed product declaration from a retained import run and traced the name and slug derivation in Blocks Engine source.

Dominant language
PHP
Stars
22
Forks
2
Avg merge
8h 22m
Merged PRs (30d)
659

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Automattic/blocks-engine

All issues in Automattic/blocks-engine

Similar issues

More PHP issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.