Add render-time video SEO schema for block templates, parts, and patterns - #2031
Conversation
…erns Add render-time video SEO schema for block templates, parts, and patterns VideoObject JSON-LD was only emitted for godam/video blocks in a post's own content. Videos placed in block-theme templates, template parts, synced patterns, or on non-singular views (front page/archives) produced no schema. Collect such videos via the render_block filter and output them in wp_footer, deduplicating against the cached wp_head output.
🔍 WordPress Plugin Check Report
📊 Report
|
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
0 |
missing_composer_json_file | The "/vendor" directory using composer exists, but "composer.json" file is missing. |
📁 readme.txt (2 warnings)
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
0 |
mismatched_plugin_name | Plugin name "GoDAM - Organize WordPress Media Library & File Manager with Unlimited Folders for Images, Videos & more" is different from the name declared in plugin header "GoDAM". |
0 |
trademarked_term | The plugin name includes a restricted term. Your chosen plugin name - "GoDAM - Organize WordPress Media Library & File Manager with Unlimited Folders for Images, Videos & more" - contains the restricted term "wordpress" which cannot be used at all in your plugin name. |
📁 assets/build/blocks/godam-gallery-v2/render.php (2 warnings)
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
15 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound | Global variables defined by a theme/plugin should start with the theme/plugin prefix. Found: "$inner_block_video_ids". |
23 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedVariableFound | Global variables defined by a theme/plugin should start with the theme/plugin prefix. Found: "$inner_block_video_ids". |
📁 tests/bootstrap.php (7 warnings)
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
28 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "wp_strip_all_tags". |
48 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "wp_prepare_attachment_for_js". |
63 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "get_post_meta". |
77 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "get_post_mime_type". |
88 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "wp_get_attachment_url". |
99 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "get_the_title". |
111 |
WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound | Functions declared in the global namespace by a theme/plugin should start with the theme/plugin prefix. Found: "date_i18n". |
📁 assets/build/css/main.css (1 warning)
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
0 |
EnqueuedStylesScope | This style is being loaded in all contexts. |
📁 assets/src/libs/analytics.min.js (5 warnings)
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
0 |
EnqueuedScriptsScope | This script is being loaded in all frontend contexts. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880 (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880/2026/07/22/hello-world/ (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880/sample-page/ (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880/demo-attachment-post/ (with handle analytics-library) is loaded in the footer. Consider a defer or async script loading strategy instead. |
📁 assets/build/js/main.min.js (5 warnings)
| 📍 Line | 🔖 Check | 💬 Message |
|---|---|---|
0 |
EnqueuedScriptsScope | This script is being loaded in all frontend contexts. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880 (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880/2026/07/22/hello-world/ (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880/sample-page/ (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead. |
0 |
NonBlockingScripts.NoStrategy | This script on http://localhost:8880/demo-attachment-post/ (with handle rtgodam-script) is loaded in the footer. Consider a defer or async script loading strategy instead. |
🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Adds render-time VideoObject JSON-LD generation so videos placed in block-theme templates/parts/patterns (and non-singular views) get SEO schema output, while de-duplicating against the existing cached wp_head output.
Changes:
- Track emitted video identifiers (content URLs, attachment IDs) from the cached
wp_headpath for de-duplication. - Collect
godam/videoblocks at render time viarender_block, and emit collected JSON-LD inwp_footer. - Refactor per-video schema building into a shared helper to keep both paths consistent and apply the same filters.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Code reviewWhat this PR doesExtends video The approach:
Overall this is a clean, well-documented refactor. The shared builder, the two-phase collect/flush split, and deferring cross-path de-dup to Correctness
Conventions
Tests
Performance
Security
VerdictSolid, low-risk change that fills a genuine SEO gap for block themes. Nothing blocking. Recommend: (1) confirm the |
- Prefer attachment_id in render-collection dedupe key - Close double-emit for headline-only entries (no contentUrl/id) - Soften render_block/wp_head ordering comments - Note may be 0 on non-singular render-time views - Tag all new symbols with @SInCE n.e.x.t
Fixes: #2032
This pull request introduces a new mechanism to collect and output VideoObject schema for videos embedded in block-theme templates, template parts, and synced patterns, ensuring that all videos on a page are properly represented in the page's JSON-LD without duplication. The changes add a render-time collection and output process in addition to the existing cached
wp_headschema output, with careful de-duplication between the two paths.Video SEO schema improvements:
Seofor tracking which video content URLs and attachment IDs have already had schema emitted, and for collecting render-time video schema entries ($emitted_content_urls,$emitted_attachment_ids,$render_collected_schemas).render_blockfilter and a newcollect_render_time_video_seomethod to capture video blocks rendered outside the queried post's content (e.g., in templates or patterns). [1] [2]output_render_time_video_seo_schemamethod, hooked towp_footer, to output JSON-LD for videos collected at render time, with de-duplication against videos already emitted inwp_head. [1] [2]build_video_object_schemamethod, ensuring both cached and render-time paths produce identical schema and fire the same filters.is_render_time_seo_contextmethod to precisely determine when render-time schema collection/output should run (i.e., only on front-end HTML page renders, not in admin, REST, or feeds).Screenshots (Self tested using https://validator.schema.org/ tool)
Frontpage template

Normal page with video and sync patterns
