Jetpack SEO: Content tab, per-post schema, and Content coverage card#49351
Jetpack SEO: Content tab, per-post schema, and Content coverage card#49351angelablake wants to merge 11 commits into
Conversation
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Jetpack plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
Code Coverage SummaryCoverage changed in 2 files.
2 files are newly checked for coverage.
Full summary · PHP report · JS report If appropriate, add one of these labels to override the failing coverage check:
Covered by non-unit tests
|
c9d4d60 to
a482cb0
Compare
805cb9a to
4fe2052
Compare
- Jetpack_SEO_Posts: register jetpack_seo_schema_type meta (show_in_rest with an enum schema so core REST rejects unknown types — must-fix #12), plus get_post_schema_type() and a single factual get_post_seo_coverage() helper (presence/state only, no scoring) shared by the columns + Overview card. Per-post types scoped to none/Article/FAQ (LocalBusiness/Organization/HowTo deferred to the Expanded Schema project, JETPACK-1701). - Schema_Builder (package): front-end JSON-LD on wp_head for Article + FAQ (FAQ parsed from core/details; emits nothing if absent). Must-fix #8 (drop JSON_UNESCAPED_SLASHES) and #9 (cap Article description with wp_trim_words). - Initializer: wire Schema_Builder::init() in (front-end emission). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Admin columns (class-jetpack-seo-admin-columns.php, wired in seo-tools.php): factual Schema / Meta description / Search columns on public post lists, via the shared Jetpack_SEO_Posts::get_post_seo_coverage() helper. No traffic-light scoring and no React-island preview (display-only). - Block editor: new schema-panel.js (Default/Article/FAQ SelectControl) reusing the existing withSeoHelper HOC; wired SeoSchemaPanel into the existing SEO panel's three placements (sidebar, document settings, pre-publish). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Content tab (?tab=content): DataViews list of posts/pages backed by core /wp/v2/posts + registered SEO meta (no package REST controller). Factual columns (schema type, meta-description set, search visibility) + an Edit SEO modal that writes core post meta, with a live SERP preview. Adds @wordpress/dataviews, @wordpress/core-data, @wordpress/html-entities. - Content SEO coverage card on the Overview: factual per-metric DonutMeter rings (custom description, schema type) + literal counts, noindex as a plain count. No composite score / grading. Backed by a content_coverage aggregate in get_overview_data() via script-data (count helpers in the Initializer). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…SEO_Posts get_content_coverage() referenced Jetpack_SEO_Posts:: constants, but the package Initializer has no `use Jetpack_SEO_Posts;` import (only Jetpack_SEO_Utils), so in this namespace it resolved to a non-existent Automattic\\Jetpack\\SEO\\Jetpack_SEO_Posts and fataled on every SEO-page load. php -l/phpcs can't see it; phan would have (the guarded Utils calls carry @phan-suppress; mine didn't). Fix: mirror the three meta keys as local package constants (they're stable strings) so coverage counting doesn't depend on the plugin class at all. Also hardened Schema_Builder::emit() to guard on Jetpack_SEO_Posts + added the matching @phan-suppress annotations. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Same namespace-resolution fatal as the previous fix, one line further down the same call chain: `new WP_Query` in this namespaced file (no use import, no leading backslash) resolved to Automattic\\Jetpack\\SEO\\WP_Query and fataled the SEO page. Qualified to \WP_Query. Audited every class reference in the package's namespaced files — all others are use-imported or same-namespace. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1. Overview layout: move the Content SEO card out of the 2-up grid into a full-width row beneath Site visibility + Site verification. 2. Content edits reflect on the Overview card without a reload: coverage counts lifted to the app root, nudged optimistically (per-metric delta) when a post's SEO is saved on the Content tab. 3. Edit SEO row action now has a pencil icon (more discoverable than a label- only hover action). 4. Drop the 'hidden from search' count from the coverage card; add a Search visibility filter (Visible/Hidden) to the Content tab instead — most content is visible by default, so it's a filter, not a headline stat. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4fe2052 to
c385898
Compare
- changelog: Type 'added' → 'enhancement' (Changelogger validity) - class-schema-builder.php: cast post_author to int for get_the_author_meta() (Phan PhanTypeMismatchArgument) - use-seo-posts.ts: fetch merged posts+pages client-side (up to 100 each); expose draft/pending/private statuses; drop pagination args - content/index.tsx: use filterSortAndPaginate for client-side filter/sort/paginate; fix ButtonTrigger icon (wrap pencil in <Icon>); restore getValue for type/schema/description/visibility filter fields Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Restrict Content tab to published posts only (drop draft/pending/future/private). Unpublished content has no SEO impact, and showing it created a count mismatch with the Overview coverage card. - Replace the hover-only DataViews primary action with a rendered 'editAction' column: an EditButton component (useCallback-stable onClick) that is always visible, so users don't need to hover to discover the edit affordance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Content tab (PR #4) is now in place; remove the "lands in follow-up PR" note and document the tab, its data access pattern (core REST + registered post meta), and the JSON-LD emission. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lary The seo package uses keep-a-changelog types (added/changed/fixed/…) and the jetpack plugin uses the Jetpack set (enhancement/bugfix/compat/…). The two Type values were swapped, failing the Changelogger validity check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Part 4 of the 8-PR Jetpack SEO product split (originally by @keoshi; driven here by @angelablake). Linear: JETPACK-1680. Targets trunk (PRs #2 and #3 are merged).
Adds per-post SEO + a Content tab to the SEO admin page. Re-implemented on the wp-build + script-data foundation from #2/#3 — no package REST controller, reuses core endpoints + post meta + script-data.
Proposed changes
?tab=content): a DataViews list of published posts and pages backed by core/wp/v2/posts+/wp/v2/pagesand registered SEO post meta. Factual columns — schema type, meta-description set, search visibility — with client-side filters; no SEO "score". An Edit SEO modal edits the post's SEO meta (custom title, description, schema type, noindex) via core post meta (no write endpoint) with a live SERP preview.content_coverageaggregate in script-data (get_content_coverage()inInitializer). No composite grade.jetpack_seo_schema_typemeta, enum-validated): a Schema type control (Default / Article / FAQ) in the block-editor SEO panel, reusing the existingwithSeoHelperHOC.Schema_Builder): Article + FAQ structured data onwp_headfor published posts with the matching schema type set.edit.phpcolumns (Schema / Meta description / Search) on public post-list tables, via one sharedJetpack_SEO_Posts::get_post_seo_coverage()helper.Product decisions
Must-fixes from the #48154 review
#12 (enum-validated schema type), #8 (no
JSON_UNESCAPED_SLASHES), #9 (wp_trim_wordson Article description), and removing the dead LocalBusiness/Organization writers are all addressed. #13/#14 are voided by dropping the score.Related product discussion/links
Screenshots
SEO.Content.tab.walkthrough.mp4
Testing instructions
Requires the
seo-toolsJetpack module active and — until the feature flag is removed in JETPACK-1702 — the filterrsm_jetpack_seoreturning true (add a mu-plugin:add_filter( 'rsm_jetpack_seo', '__return_true' );).Content tab (
wp-admin/admin.php?page=jetpack-seo&tab=content):Overview (
wp-admin/admin.php?page=jetpack-seo):6. Confirm the Content SEO card shows correct counts for posts with a custom description set and schema type set.
7. Edit a post's description via the modal and confirm the ring/count updates immediately.
Block editor:
8. Open any post in Gutenberg; expand the SEO panel in the sidebar. Confirm the Schema type selector (Default / Article / FAQ) appears and saves.
Post list tables (
wp-admin/edit.php,wp-admin/edit.php?post_type=page):9. Confirm Schema, Meta description, and Search columns appear and reflect each post's current SEO state.
Front-end JSON-LD:
10. Set a published post's schema type to Article or FAQ; view-source on the front end and confirm the corresponding JSON-LD block appears in
<head>.Does this pull request change what data or activity we track or use?
No. This PR adds no Tracks events and reads no new user data beyond what the existing
seo-toolsmodule already accesses (post meta, core options).