Shell extraction ignores a third capture device document (tablet), so no shared header/footer parts are extracted
I maintainer di solito rispondono entro 1 giorno
Nessuno ha ancora preso questa issue.
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 74/100
Direzione di ricerca
Start with ShellExtraction::isResponsiveVariantClass() and CaptureEvidence::DEVICE_DOCUMENT; the issue identifies both the recognition rule and the capture contract to follow. Add a contract test based on tests/contract/capture-variant-plain-page-shell.php that includes desktop, mobile, and tablet documents across three routes. Done means shared header and footer parts include the tablet variant, pages have no inline header or footer, and no shell_retained_* diagnostic appears; check the three existing contracts named in the issue too.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
A third capture device document disables shared header/footer extraction
Data Liberation now emits an additional device document for dual routes (data-blocks-engine-capture-tablet-document, alongside the desktop and mobile documents) through the existing capture contract: CaptureEvidence::DEVICE_DOCUMENT allows any profile id ([a-z][a-z0-9_-]{0,63}). Shell extraction recognizes only the two hardcoded document classes:
// ShellExtraction::isResponsiveVariantClass()
return in_array($class, array(CaptureEvidence::DESKTOP_DOCUMENT_CLASS, CaptureEvidence::MOBILE_DOCUMENT_CLASS), true)
|| 1 === preg_match('/^site-document-variant-[a-z][a-z0-9_-]{0,31}$/', $class);
So the tablet copy of each landmark has no responsive variant class, scopedVariantLandmarks() returns null for every route, absorbResponsiveVariantLandmarks() returns false, and both areas end in wordpress_site_plan_shell_retained_incomplete ("shell candidates do not establish a dominant semantic cluster"). Every page keeps its own inline header and footer instead of binding shared template parts.
Observed
A 4fires.org (Wix) import with SSI 1.33.366 / DLA 0.33.136: 41 pages, all with desktop + mobile + tablet documents, produced no parts/ and the two shell_retained_incomplete diagnostics. Probing the materialized pages: on every route the desktop and mobile SITE_HEADER / SITE_FOOTER landmarks resolve to their variant classes and the SITE_HEADER--data-blocks-engine-capture-tablet copy resolves to null.
Reduced reproduction (trunk 15317e2)
Three routes, identical chrome, block markup injected per route the way tests/contract/capture-variant-plain-page-shell.php does. The only difference between the two runs is the third document class:
desktop+mobile parts=["footer","header"] pages-with-inline-header=0 retained=[]
desktop+mobile+tablet parts=["footer"] pages-with-inline-header=3 retained=["wordpress_site_plan_shell_retained_incomplete footer","wordpress_site_plan_shell_retained_incomplete header"]
Repro script
declare(strict_types=1);
require getenv('BE') . '/php-transformer/vendor/autoload.php';
use Automattic\BlocksEngine\PhpTransformer\ArtifactCompiler\ArtifactCompiler;
use Automattic\BlocksEngine\PhpTransformer\Contract\CaptureEvidence;
use Automattic\BlocksEngine\PhpTransformer\WordPressSitePlan\WordPressSitePlan;
// Three routes, each captured as three device documents: desktop, mobile, and
// an additional profile (tablet) declared through the same capture contract.
$tablet = 'data-blocks-engine-capture-tablet-document';
$navigation = '<!-- wp:navigation {"overlayMenu":"never"} --><!-- wp:navigation-link {"label":"Home","url":"/","kind":"custom"} /--><!-- wp:navigation-link {"label":"About","url":"/about/","kind":"custom"} /--><!-- /wp:navigation -->';
$header = static fn(string $class): string => '<!-- wp:group {"className":"' . $class . '","tagName":"header"} --><header class="wp-block-group ' . $class . '"><!-- wp:paragraph --><p><a href="/">Four Fires</a></p><!-- /wp:paragraph -->' . $navigation . '</header><!-- /wp:group -->';
$footer = static fn(string $class): string => '<!-- wp:group {"className":"' . $class . '","tagName":"footer"} --><footer class="wp-block-group ' . $class . '"><!-- wp:paragraph --><p>Four Fires Ministries</p><!-- /wp:paragraph --></footer><!-- /wp:group -->';
$main = static fn(string $title): string => '<!-- wp:group {"tagName":"main"} --><main class="wp-block-group"><!-- wp:heading --><h2 class="wp-block-heading">' . $title . '</h2><!-- /wp:heading --></main><!-- /wp:group -->';
$document = static fn(string $class, string $suffix, string $title): string => '<!-- wp:group {"className":"' . $class . '"} --><div class="wp-block-group ' . $class . '">' . $header('site-header' . $suffix) . $main($title) . $footer('site-footer' . $suffix) . '</div><!-- /wp:group -->';
$capture = static fn(string $title, array $classes): string => implode('', array_map(static fn(string $class, int $i): string => $document($class, 0 === $i ? '' : ' compact', $title), $classes, array_keys($classes)));
foreach (array('desktop+mobile' => array(CaptureEvidence::DESKTOP_DOCUMENT_CLASS, CaptureEvidence::MOBILE_DOCUMENT_CLASS), 'desktop+mobile+tablet' => array(CaptureEvidence::DESKTOP_DOCUMENT_CLASS, CaptureEvidence::MOBILE_DOCUMENT_CLASS, $tablet)) as $label => $classes) {
$result = (new ArtifactCompiler())->compile(array('entrypoint' => 'index.html', 'files' => array(
'index.html' => '<main><h1>Home</h1></main>',
'about/index.html' => '<main><h1>About</h1></main>',
'contact/index.html' => '<main><h1>Contact</h1></main>',
)))->toArray();
foreach ($result['source_reports']['compiled_site']['pages'] as &$page) $page['block_markup'] = $capture(ucfirst(basename(dirname('/' . $page['source_path'])) ?: 'Home'), $classes);
unset($page);
$plan = (new WordPressSitePlan())->fromResult($result);
$areas = array_column($plan['template_parts'], 'area');
$retained = array_values(array_filter(array_map(static fn(array $d): string => ($d['code'] ?? '') . ' ' . ($d['area'] ?? ''), $plan['diagnostics']), static fn(string $c): bool => str_contains($c, 'shell_retained')));
$inline = count(array_filter($plan['pages'], static fn(array $p): bool => str_contains((string) $p['canonical_block_markup'], 'site-header')));
echo str_pad($label, 24), 'parts=', json_encode($areas), ' pages-with-inline-header=', $inline, ' retained=', json_encode($retained), "\n";
if (str_contains($label, 'tablet')) {
$header = array_values(array_filter($plan['template_parts'], static fn(array $p): bool => 'header' === $p['area']))[0]['canonical_block_markup'] ?? '';
echo ' tablet document in shared header part: ', var_export(str_contains($header, $tablet), true), "\n";
}
}
Expected
Any capture device document class (data-blocks-engine-capture-<profile>-document, profile per the DEVICE_DOCUMENT grammar) is a responsive document variant for shell extraction, the same as desktop and mobile. With three documents the routes bind one shared header part and one shared footer part that render all three variants, and no page keeps an inline copy, matching the two-document result.
Acceptance
- A contract test (three routes × desktop/mobile/tablet documents) fails on trunk and passes on the fix: shared
headerandfooterparts exist, each holds the tablet variant, no page retainssite-header/site-footer, and noshell_retained_*diagnostic is emitted. - The existing two-document contracts (
capture-variant-plain-page-shell.php,unlabeled-capture-device-shell.php,viewport-hidden-document-variants.php) still pass. - Recognition derives from the capture contract (one helper on
CaptureEvidencefor "is a device document class") rather than adding a third hardcoded constant.
AI disclosure: filed by Franklin (Claude Opus via Pi/Roadie). Root cause found by probing the 4fires import's materialized pages with ShellExtraction on trunk; the reduced repro was run on trunk.
- Lingua principale
- PHP
- Stelle
- 25
- Fork
- 3
- Merge medio
- 3h 25m
- PR unite (30g)
- 935
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di Automattic/blocks-engine
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
Automattic/blocks-engine#4621 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
Automattic/blocks-engine#775 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
Automattic/blocks-engine#4637 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 48/100
Automattic/blocks-engine#4630 ·
I maintainer di solito rispondono entro 1 giorno
-
Navigation overflow trigger chevron renders below the label instead of inlineForse già presa @chubes4 l’ha presa oggi. Aperta
Difficoltà 3/5 1-2 giorni Idoneità per principianti 35/100
Automattic/blocks-engine#4629 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di Automattic/blocks-engine
Issue simili
-
sync-en
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
sync-en
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
I maintainer di solito rispondono entro 1 giorno
-
Перевод устарел
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
YunoHost-Apps/snappymail_ynh#205 ·
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 77/100
Automattic/static-site-importer#2653 ·
I maintainer di solito rispondono entro 1 giorno