From df3e5dc3f2f5ec791b7bfdb16a0136fbaaa4b31e Mon Sep 17 00:00:00 2001 From: Thijs van der heijden Date: Mon, 2 Feb 2026 12:04:27 +0100 Subject: [PATCH 1/4] Documentation for the schema aggregator --- .../schema/schema-aggregator/api-reference.md | 281 ++++++ .../schema/schema-aggregator/filters.md | 808 ++++++++++++++++++ .../schema/schema-aggregator/overview.md | 157 ++++ docs/overview.md | 1 + sidebars.js | 14 + 5 files changed, 1261 insertions(+) create mode 100644 docs/features/schema/schema-aggregator/api-reference.md create mode 100644 docs/features/schema/schema-aggregator/filters.md create mode 100644 docs/features/schema/schema-aggregator/overview.md diff --git a/docs/features/schema/schema-aggregator/api-reference.md b/docs/features/schema/schema-aggregator/api-reference.md new file mode 100644 index 00000000..50976070 --- /dev/null +++ b/docs/features/schema/schema-aggregator/api-reference.md @@ -0,0 +1,281 @@ +--- +id: api-reference +title: "Schema Aggregator: API Reference" +sidebar_label: API Reference +description: REST API endpoints and CLI commands for the Schema Aggregator feature. +--- + +This document provides a complete reference for the Schema Aggregator REST API endpoints and CLI commands. + +## REST API Endpoints + +### Get Schema for Post Type (JSON-L) + +Retrieve aggregated schema pieces for a specific post type in JSON-L format. + +**Endpoint:** +``` +GET /wp-json/yoast/v1/schema-aggregator/get-schema/{post_type}[/{page}] +``` + +**Parameters:** + +| Parameter | Type | Required | Default | Description | +|-----------|------|----------|---------|-------------| +| `post_type` | string | Yes | - | The post type to aggregate (e.g., `post`, `page`, `product`) | +| `page` | integer | No | 1 | Page number for pagination | +| `debug` | boolean | No | false | Disables cache when set to true (add `?debug=1` to URL) | + +**Pagination:** + +- Standard post types: 1000 items per page +- Big schema post types (e.g., `product`): 100 items per page + +You can customize pagination using filters: +- `wpseo_schema_aggregator_per_page`: Default items per page (1000) +- `wpseo_schema_aggregator_per_page_big`: Items per page for big schema post types (100) +- `wpseo_schema_aggregator_big_schema_post_types`: Define which post types use big pagination (default: `['product']`) + +**Response Format:** + +```json lines +{ + "@context": "https://schema.org", + "@type": "Article", + "@id": "https://example.com/hello-world/#article", + "headline": "Hello World", + "description": "A brief description of the article", + "articleBody": "The full article content...", + "keywords": ["hello", "world"], + "datePublished": "2024-01-15T10:30:00+00:00", + "dateModified": "2024-01-20T14:45:00+00:00", + "author": { + "@id": "https://example.com/#/schema/person/1" + }, + "publisher": { + "@id": "https://example.com/#organization" + } + +} +``` + +**Cache Headers:** + +Responses include cache control headers with a 5-minute (300 seconds) cache duration: + +``` +Cache-Control: max-age=300 +``` + +**Example Request (cURL):** + +```bash +# Get first page of posts +curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post + +# Get second page +curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post/2 + +# Debug mode (bypass cache) +curl "https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post?debug=1" +``` + +--- + +### Get XML Schema Map + +Retrieve an XML sitemap of all available schema endpoints. + +**Endpoint:** +``` +GET /wp-json/yoast/v1/schema-aggregator/get-xml +``` + +**Parameters:** + +None. + +**Response Format:** + +```xml + + + + https://exampple.com/wp-json/yoast/v1/schema-aggregator/get-schema/page + 2026-01-01T14:03:56Z + daily + 0.8 + + + https://exampple.com/wp-json/yoast/v1/schema-aggregator/get-schema/post + 2026-01-01T14:03:56Z + daily + 0.8 + + +``` + + +**Cache Headers:** + +Responses include cache control headers matching the dynamic TTL strategy: +- Small sites (< 100 posts): 24 hours +- Medium sites (100-1000 posts): 12 hours +- Large sites (> 1000 posts): 6 hours + +**robots.txt Integration:** + +The schema map is automatically referenced in your site's `robots.txt`: + +``` +Sitemap: https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml +``` + +**Example Request:** + +```bash +curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml +``` + +**Customizing Post Types:** + +By default, the schema map includes all public post types. You can customize this using the `wpseo_schema_aggregator_post_types` filter: + +```php +add_filter( 'wpseo_schema_aggregator_post_types', 'customize_schema_post_types' ); + +/** + * Customize which post types appear in schema aggregator. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/api-reference/#get-schema-map-xml + * + * @param array $post_types Array of post type names. + * + * @return array Modified array of post type names. + */ +function customize_schema_post_types( $post_types ) { + // Only include posts and pages. + return [ 'post', 'page' ]; +} +``` + +--- + +## CLI Commands + +### Aggregate Site Schema + +Retrieve aggregated schema for a post type via WP-CLI. + +**Command:** +```bash +wp yoast aggregate_site_schema [--page=] +``` + +**Arguments:** + +| Argument | Type | Required | Default | Description | +|----------|------|----------|---------|-------------| +| `` | string | Yes | - | The post type to aggregate | +| `--page` | integer | No | 1 | Page number for pagination | + +**Output Format:** + +JSON-LD output is printed to stdout. + +**Example Usage:** + +```bash +# Get first page of posts +wp yoast aggregate_site_schema post + +# Get second page of products +wp yoast aggregate_site_schema product --page=2 +``` +--- + +### Clear Schema Cache + +Invalidate cached schema data for all or specific post types. + +**Command:** +```bash +wp yoast clear_schema_aggregator_cache [] +``` + +**Arguments:** + +| Argument | Type | Required | Default | Description | +|----------|------|----------|---------|-------------| +| `` | string | No | - | Optional post type to clear cache for | + +**Example Usage:** + +```bash +# Clear all schema caches +wp yoast clear_schema_aggregator_cache + +# Clear cache for posts only +wp yoast clear_schema_aggregator_cache post + +# Clear cache for products only +wp yoast clear_schema_aggregator_cache product +``` + + + +## Filtering and Enhancement + +### What Gets Filtered Out + +By default, the Schema Aggregator removes schema pieces in the following categories: + +- **Actions**: Potential actions (e.g., `SearchAction`, `ReadAction`) +- **Enumerations**: Type definitions (e.g., `ItemAvailability`, `OfferItemCondition`) +- **Meta**: Schema.org metadata (e.g., `DataType`, `Class`) +- **Website**: Site structure elements (e.g., `WebSite`, `WebPage` when not the main entity) + +This filtering reduces noise and focuses on meaningful content entities. + +**Customize filtering:** + +### What Gets Enhanced + +The Schema Aggregator enhances certain schema types with additional data: + +#### Article Enhancement + +Articles (and subtypes like `BlogPosting`, `NewsArticle`) are enhanced with: + +1. **articleBody**: Full post content (configurable max length, default: 5000 characters) +2. **description**: Post excerpt (configurable max length, default: 320 characters) +3. **keywords**: Post tags as keyword array + +**Configuration:** + +```php +// Adjust article body length. +add_filter( 'wpseo_article_enhance_config_max_article_body_length', function() { + return 10000; // Increase to 10,000 characters. +} ); + +// Adjust description length. +add_filter( 'wpseo_article_enhance_config_max_description_length', function() { + return 500; // Increase to 500 characters. +} ); + +// Disable article body enhancement. +add_filter( 'wpseo_article_enhance_config_add_article_body', '__return_false' ); + +// Disable description enhancement. +add_filter( 'wpseo_article_enhance_config_add_description', '__return_false' ); + +// Disable keywords enhancement. +add_filter( 'wpseo_article_enhance_config_add_keywords', '__return_false' ); +``` + +## See Also + +- [Overview](overview.md): Introduction to Schema Aggregator +- [Schema.org documentation](https://schema.org/) +- [JSON-LD specification](https://json-ld.org/) diff --git a/docs/features/schema/schema-aggregator/filters.md b/docs/features/schema/schema-aggregator/filters.md new file mode 100644 index 00000000..341e4ecc --- /dev/null +++ b/docs/features/schema/schema-aggregator/filters.md @@ -0,0 +1,808 @@ +--- +id: filters +title: "Schema Aggregator: Filters" +sidebar_label: Filters +description: WordPress filters to customize the Schema Aggregator feature behavior and output. +--- + +The Schema Aggregator provides 18 WordPress filters that allow you to customize its behavior, from cache configuration to content enhancement. This document provides a complete reference with practical examples for each filter. + +## Quick Reference + +| Filter | Category | Purpose | +|--------|----------|---------| +| [`wpseo_schema_aggregator_post_types`](#post-type-configuration) | Post Types | Control which post types to aggregate | +| [`wpseo_schema_aggregator_per_page`](#pagination-configuration) | Pagination | Set default items per page (1000) | +| [`wpseo_schema_aggregator_per_page_big`](#pagination-configuration) | Pagination | Set items per page for big schema post types (100) | +| [`wpseo_schema_aggregator_big_schema_post_types`](#pagination-configuration) | Pagination | Define which post types have large schema | +| [`wpseo_schema_aggregator_cache_enabled`](#cache-configuration) | Cache | Enable/disable caching | +| [`wpseo_schema_aggregator_cache_ttl`](#cache-configuration) | Cache | Set cache duration (dynamic by default) | +| [`wpseo_schema_aggregator_schemamap_changefreq`](#schema-map-configuration) | Schema Map | Set XML sitemap update frequency | +| [`wpseo_schema_aggregator_schemamap_priority`](#schema-map-configuration) | Schema Map | Set XML sitemap priority | +| [`wpseo_schema_aggregator_filtering_strategy`](#filtering-strategy) | Filtering | Implement custom filtering logic | +| [`wpseo_schema_aggregator_elements_context_map`](#elements-context-map) | Context Map | Override complete context map | +| [`wpseo_schema_aggregator_elements_context_map_{context}`](#wpseo_schema_aggregator_elements_context_map_context) | Context Map | Customize elements for specific context | +| [`wpseo_article_enhance_config_{key}`](#article-enhancement-configuration) | Article Enhancement | Configure article enhancement settings | +| [`wpseo_article_enhance_{enhancement}`](#article-enhancement-toggles) | Article Enhancement | Toggle specific article enhancements | +| [`wpseo_article_enhance_body_when_excerpt_exists`](#article-body-with-excerpt) | Article Enhancement | Include body when excerpt exists | +| [`wpseo_article_enhance_article_body_fallback`](#article-body-fallback) | Article Enhancement | Include body when no excerpt | +| [`wpseo_person_enhance_config_{key}`](#person-enhancement-configuration) | Person Enhancement | Configure person enhancement settings | +| [`wpseo_person_enhance_{enhancement}`](#person-enhancement-toggles) | Person Enhancement | Toggle specific person enhancements | +| [`wpseo_disable_robots_schemamap`](#robotstxt-integration) | Robots.txt | Disable schema map in robots.txt | + +## Post Type Configuration + +### wpseo_schema_aggregator_post_types + +Control which post types are included in the schema aggregation. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$post_types` | array | Array of post type names to aggregate | + +**Default Value:** All public post types + +**Example: Include Only Specific Post Types** + +```php +add_filter( 'wpseo_schema_aggregator_post_types', 'limit_aggregated_post_types' ); + +/** + * Limit schema aggregation to posts and pages only. + * + * This is useful when you have custom post types that don't need + * structured data or when you want to improve performance. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_post_types + * + * @param array $post_types Array of post type names. + * + * @return array Modified array of post type names. + */ +function limit_aggregated_post_types( $post_types ) { + // Only aggregate posts and pages. + return [ 'post', 'page' ]; +} +``` + +**Example: Exclude Specific Post Types** + +```php +add_filter( 'wpseo_schema_aggregator_post_types', 'exclude_custom_post_types' ); + +/** + * Exclude internal post types from schema aggregation. + * + * Remove post types that are used for internal purposes and + * should not appear in structured data output. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_post_types + * + * @param array $post_types Array of post type names. + * + * @return array Modified array of post type names. + */ +function exclude_custom_post_types( $post_types ) { + // Remove internal post types. + $excluded = [ 'acf-field', 'acf-field-group', 'custom_css' ]; + + return array_diff( $post_types, $excluded ); +} +``` + +## Pagination Configuration + +The Schema Aggregator uses different pagination limits based on the size of schema pieces. Some post types (like WooCommerce products) generate large schema objects and need smaller page sizes. + +### wpseo_schema_aggregator_per_page + +Set the default number of items per page for schema aggregation. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$per_page` | int | Number of items per page | + +**Default Value:** 1000 + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_per_page', 'custom_default_per_page' ); + +/** + * Reduce default items per page for better performance. + * + * Lower pagination can help with memory limits on shared hosting + * or when dealing with post types that have moderate schema sizes. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_per_page + * + * @param int $per_page Number of items per page. + * + * @return int Modified number of items per page. + */ +function custom_default_per_page( $per_page ) { + return 500; // Reduce from 1000 to 500. +} +``` + +### wpseo_schema_aggregator_per_page_big + +Set the number of items per page for post types with large schema pieces. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$per_page_big` | int | Number of items per page for big schema post types | + +**Default Value:** 100 + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_per_page_big', 'custom_big_per_page' ); + +/** + * Adjust pagination for post types with large schema. + * + * Increase or decrease based on your server's memory limits + * and the actual size of your schema pieces. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_per_page_big + * + * @param int $per_page_big Number of items per page for big schema. + * + * @return int Modified number of items per page. + */ +function custom_big_per_page( $per_page_big ) { + return 50; // Reduce from 100 to 50 for very large schemas. +} +``` + +### wpseo_schema_aggregator_big_schema_post_types + +Define which post types should use the "big schema" pagination limit. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$big_schema_post_types` | array | Array of post type names with large schema pieces | + +**Default Value:** `[ 'product' ]` + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_big_schema_post_types', 'add_big_schema_post_types' ); + +/** + * Mark custom post types as having large schema pieces. + * + * Post types with extensive custom fields, galleries, or complex + * relationships should use the lower pagination limit. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_big_schema_post_types + * + * @param array $big_schema_post_types Array of post type names. + * + * @return array Modified array of post type names. + */ +function add_big_schema_post_types( $big_schema_post_types ) { + // Add custom post types with large schemas. + $big_schema_post_types[] = 'property'; // Real estate listings. + $big_schema_post_types[] = 'event'; // Events with extensive details. + + return $big_schema_post_types; +} +``` + +## Cache Configuration + +The Schema Aggregator implements intelligent caching to balance performance and freshness. Cache automatically clears when posts are updated. + +### wpseo_schema_aggregator_cache_enabled + +Enable or disable the cache system entirely. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$enabled` | bool | Whether caching is enabled | + +**Default Value:** `true` + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_cache_enabled', 'disable_schema_cache_in_dev' ); + +/** + * Disable caching in development environment. + * + * This ensures you always see fresh data during development + * without needing to manually clear the cache. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_cache_enabled + * + * @param bool $enabled Whether caching is enabled. + * + * @return bool Modified cache enabled status. + */ +function disable_schema_cache_in_dev( $enabled ) { + // Disable cache in local/staging environments. + if ( defined( 'WP_ENV' ) && in_array( WP_ENV, [ 'development', 'staging' ], true ) ) { + return false; + } + + return $enabled; +} +``` + +### wpseo_schema_aggregator_cache_ttl + +Set the cache time-to-live (TTL) in seconds. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$ttl` | int | Cache duration in seconds | +| `$post_type` | string | The post type being cached | +| `$post_count` | int | Number of posts for this post type | + +**Default Value:** Dynamic based on site size: +- Small sites (< 100 posts): 86400 seconds (24 hours) +- Medium sites (100-1000 posts): 43200 seconds (12 hours) +- Large sites (> 1000 posts): 21600 seconds (6 hours) + +**Example: Fixed TTL** + +```php +add_filter( 'wpseo_schema_aggregator_cache_ttl', 'custom_cache_ttl' ); + +/** + * Set a fixed cache duration for all post types. + * + * Use this when you want consistent cache behavior regardless + * of site size or post type. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_cache_ttl + * + * @param int $ttl Cache duration in seconds. + * @param string $post_type Post type being cached. + * @param int $post_count Number of posts. + * + * @return int Modified cache duration. + */ +function custom_cache_ttl( $ttl, $post_type, $post_count ) { + // Cache for 1 hour (3600 seconds) regardless of size. + return 3600; +} +``` + +**Example: Post Type Specific TTL** + +```php +add_filter( 'wpseo_schema_aggregator_cache_ttl', 'post_type_specific_ttl', 10, 3 ); + +/** + * Set different cache durations for different post types. + * + * Frequently updated content gets shorter cache times, + * while static content can be cached longer. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_cache_ttl + * + * @param int $ttl Cache duration in seconds. + * @param string $post_type Post type being cached. + * @param int $post_count Number of posts. + * + * @return int Modified cache duration. + */ +function post_type_specific_ttl( $ttl, $post_type, $post_count ) { + $custom_ttls = [ + 'post' => 1800, // 30 minutes for frequently updated posts. + 'page' => 86400, // 24 hours for static pages. + 'product' => 3600, // 1 hour for product catalog. + ]; + + return $custom_ttls[ $post_type ] ?? $ttl; +} +``` + +## Schema Map Configuration + +The schema map is an XML sitemap that lists all available schema endpoints. It's automatically referenced in your site's `robots.txt`. + +### wpseo_schema_aggregator_schemamap_changefreq + +Set the change frequency for schema map entries. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$changefreq` | string | Change frequency (always, hourly, daily, weekly, monthly, yearly, never) | + +**Default Value:** `'daily'` + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_schemamap_changefreq', 'custom_schemamap_changefreq' ); + +/** + * Set schema map change frequency to weekly. + * + * Use this to indicate how often search engines should check + * for updated schema data. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_schemamap_changefreq + * + * @param string $changefreq Change frequency value. + * + * @return string Modified change frequency. + */ +function custom_schemamap_changefreq( $changefreq ) { + return 'weekly'; // Change from daily to weekly. +} +``` + +### wpseo_schema_aggregator_schemamap_priority + +Set the priority value for schema map entries. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$priority` | float | Priority value between 0.0 and 1.0 | + +**Default Value:** `0.8` + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_schemamap_priority', 'custom_schemamap_priority' ); + +/** + * Increase schema map priority to indicate importance. + * + * Higher priority suggests to search engines that this content + * is important relative to other URLs on your site. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_schemamap_priority + * + * @param float $priority Priority value (0.0 to 1.0). + * + * @return float Modified priority value. + */ +function custom_schemamap_priority( $priority ) { + return 1.0; // Maximum priority. +} +``` + +## Filtering Strategy + +The filtering strategy determines which schema pieces are included or excluded from aggregation. By default, the aggregator filters out Actions, Enumerations, Meta types, and Website elements. + +### wpseo_schema_aggregator_filtering_strategy + +Implement a custom filtering strategy by providing your own strategy class. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$strategy` | object\|null | Custom filtering strategy instance | + +**Default Value:** `null` (uses default strategy) + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_filtering_strategy', 'custom_filtering_strategy' ); + +/** + * Implement custom schema filtering logic. + * + * Use this to create advanced filtering rules beyond the default + * context-based filtering. Your strategy class should implement + * the filtering logic in its filter() method. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_filtering_strategy + * + * @param object|null $strategy Custom filtering strategy instance. + * + * @return object Custom filtering strategy. + */ +function custom_filtering_strategy( $strategy ) { + // Return custom strategy that only includes Article types. + return new class { + /** + * Filter schema pieces to only include Articles. + * + * @param array $schema_piece Schema piece to filter. + * + * @return bool Whether to include this schema piece. + */ + public function filter( $schema_piece ) { + // Only include Article types and their subtypes. + $article_types = [ 'Article', 'BlogPosting', 'NewsArticle', 'ScholarlyArticle' ]; + + if ( isset( $schema_piece['@type'] ) ) { + $type = $schema_piece['@type']; + + // Handle array of types. + if ( is_array( $type ) ) { + return ! empty( array_intersect( $type, $article_types ) ); + } + + return in_array( $type, $article_types, true ); + } + + return false; + } + }; +} +``` + +## Elements Context Map + +The context map categorizes schema.org types into contexts like Content, Commerce, Entity, etc. This is used by the default filtering strategy. + +### wpseo_schema_aggregator_elements_context_map + +Override the complete elements context map. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$context_map` | array | Complete mapping of schema types to contexts | + +**Default Value:** Comprehensive map of 1000+ schema.org types + +**Example:** + +```php +add_filter( 'wpseo_schema_aggregator_elements_context_map', 'custom_context_map' ); + +/** + * Provide a completely custom context map. + * + * This replaces the entire default mapping. Use this when you need + * complete control over which types belong to which contexts. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_elements_context_map + * + * @param array $context_map Complete context map. + * + * @return array Custom context map. + */ +function custom_context_map( $context_map ) { + // Define a simplified context map. + return [ + 'content' => [ + 'Article', + 'BlogPosting', + 'NewsArticle', + ], + 'commerce' => [ + 'Product', + 'Offer', + ], + 'entity' => [ + 'Person', + 'Organization', + ], + ]; +} +``` + +### wpseo_schema_aggregator_elements_context_map_\{context\} + +Modify elements for a specific context. Available contexts: `content`, `commerce`, `entity`, `event`, `data`, `medical`, `action`, `enumeration`, `meta`, `website`. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$elements` | array | Array of schema types in this context | + +**Example: Add Custom Types to Content Context** + +```php +add_filter( 'wpseo_schema_aggregator_elements_context_map_content', 'add_custom_content_types' ); + +/** + * Add custom schema types to the content context. + * + * This is useful when you have custom schema types that should + * be treated as content entities. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_elements_context_map_context + * + * @param array $elements Schema types in the content context. + * + * @return array Modified array of schema types. + */ +function add_custom_content_types( $elements ) { + // Add custom types to content context. + $elements[] = 'Recipe'; + $elements[] = 'HowTo'; + $elements[] = 'FAQPage'; + + return $elements; +} +``` + +**Example: Remove Types from Action Context** + +```php +add_filter( 'wpseo_schema_aggregator_elements_context_map_action', 'remove_action_types' ); + +/** + * Remove specific action types from the action context. + * + * This can help further refine which actions are filtered out. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_elements_context_map_context + * + * @param array $elements Schema types in the action context. + * + * @return array Modified array of schema types. + */ +function remove_action_types( $elements ) { + // Remove SearchAction from action context. + // This means it won't be filtered out anymore. + return array_diff( $elements, [ 'SearchAction' ] ); +} +``` + +## Article Enhancement + +Articles and their subtypes (BlogPosting, NewsArticle, etc.) can be enhanced with additional properties like `articleBody`, `description`, and `keywords`. + +### Article Enhancement Configuration + +Use the `wpseo_article_enhance_config_{key}` filter pattern to configure enhancement behavior. Available keys: + +- `max_article_body_length` - Maximum length for articleBody (default: 5000) +- `max_description_length` - Maximum length for description (default: 320) +- `add_article_body` - Whether to add articleBody (default: true) +- `add_description` - Whether to add description (default: true) +- `add_keywords` - Whether to add keywords (default: true) + +**Example: Adjust Maximum Lengths** + +```php +add_filter( 'wpseo_article_enhance_config_max_article_body_length', 'custom_article_body_length' ); + +/** + * Increase maximum article body length. + * + * Useful for long-form content where you want to include + * more of the article text in the schema. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#article-enhancement-configuration + * + * @param int $max_length Maximum length in characters. + * + * @return int Modified maximum length. + */ +function custom_article_body_length( $max_length ) { + return 10000; // Increase from 5000 to 10000 characters. +} +``` + +```php +add_filter( 'wpseo_article_enhance_config_max_description_length', 'custom_description_length' ); + +/** + * Adjust maximum description length. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#article-enhancement-configuration + * + * @param int $max_length Maximum length in characters. + * + * @return int Modified maximum length. + */ +function custom_description_length( $max_length ) { + return 500; // Increase from 320 to 500 characters. +} +``` + +**Example: Disable Specific Enhancements** + +```php +add_filter( 'wpseo_article_enhance_config_add_article_body', '__return_false' ); +``` + +### Article Enhancement Toggles + +Use the `wpseo_article_enhance_{enhancement}` filter pattern to enable or disable enhancements dynamically. Available enhancements match the configuration keys: `article_body`, `description`, `keywords`. + +**Example: Conditional Article Body** + +```php +add_filter( 'wpseo_article_enhance_article_body', 'conditional_article_body', 10, 2 ); + +/** + * Only include article body for certain post types. + * + * This allows fine-grained control over which content types + * receive full body enhancement. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#article-enhancement-toggles + * + * @param bool $enabled Whether enhancement is enabled. + * @param array $schema_piece The schema piece being enhanced. + * + * @return bool Modified enabled status. + */ +function conditional_article_body( $enabled, $schema_piece ) { + // Only add article body for blog posts, not news articles. + if ( isset( $schema_piece['@type'] ) && $schema_piece['@type'] === 'NewsArticle' ) { + return false; + } + + return $enabled; +} +``` + +### Article Body with Excerpt + +Control whether to include article body when an excerpt already exists. + +**Filter:** `wpseo_article_enhance_body_when_excerpt_exists` + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$include_body` | bool | Whether to include body when excerpt exists | +| `$schema_piece` | array | The schema piece being enhanced | + +**Default Value:** `false` + +**Example:** + +```php +add_filter( 'wpseo_article_enhance_body_when_excerpt_exists', '__return_true'); +``` + +### Article Body Fallback + +Control whether to include article body when no excerpt exists. + +**Filter:** `wpseo_article_enhance_article_body_fallback` + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$use_fallback` | bool | Whether to use body as fallback | +| `$schema_piece` | array | The schema piece being enhanced | + +**Default Value:** `true` + +**Example:** + +```php +add_filter( 'wpseo_article_enhance_article_body_fallback', '__return_false' ); +``` + +## Person Enhancement + +Person schema pieces can be enhanced with additional properties based on WordPress user data. + +### Person Enhancement Configuration + +Use the `wpseo_person_enhance_config_{key}` filter pattern to configure person enhancement. The exact available keys depend on your implementation. + +**Example:** + +```php +add_filter( 'wpseo_person_enhance_config_include_social_profiles', '__return_true' ); +``` + +### Person Enhancement Toggles + +Use the `wpseo_person_enhance_\{enhancement\}` filter pattern to enable or disable specific person enhancements dynamically. + +**Example:** + +```php +add_filter( 'wpseo_person_enhance_bio', 'conditional_person_bio', 10, 2 ); + +/** + * Only include person bio for authors with posts. + * + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#person-enhancement-toggles + * + * @param bool $enabled Whether enhancement is enabled. + * @param array $schema_piece The schema piece being enhanced. + * + * @return bool Modified enabled status. + */ +function conditional_person_bio( $enabled, $schema_piece ) { + // Extract user ID from schema piece if available. + if ( isset( $schema_piece['@id'] ) ) { + // Parse user ID from the @id. + preg_match( '/person\/(\d+)/', $schema_piece['@id'], $matches ); + + if ( ! empty( $matches[1] ) ) { + $user_id = (int) $matches[1]; + $post_count = count_user_posts( $user_id ); + + // Only include bio if user has published posts. + return $post_count > 0; + } + } + + return $enabled; +} +``` + +## Robots.txt Integration + +By default, the schema map is automatically referenced in your site's `robots.txt` file. You can disable this integration if needed. + +### wpseo_disable_robots_schemamap + +Disable the schema map reference in robots.txt. + +**Parameters:** + +| Parameter | Type | Description | +|-----------|------|-------------| +| `$disable` | bool | Whether to disable robots.txt integration | + +**Default Value:** `false` + +**Example:** + +```php +add_filter( 'wpseo_disable_robots_schemamap', '__return_true' ); +``` + +### Development Environment Configuration + +Disable caching and adjust settings for easier development: + +```php +/** + * Schema Aggregator configuration for development. + */ + +// Disable caching in development. +add_filter( 'wpseo_schema_aggregator_cache_enabled', function( $enabled ) { + return defined( 'WP_DEBUG' ) && WP_DEBUG ? false : $enabled; +} ); + +// Smaller pagination for faster testing. +add_filter( 'wpseo_schema_aggregator_per_page', function() { + return defined( 'WP_DEBUG' ) && WP_DEBUG ? 10 : 1000; +} ); + +// Don't add schema map to robots.txt in development. +add_filter( 'wpseo_disable_robots_schemamap', function() { + return defined( 'WP_DEBUG' ) && WP_DEBUG; +} ); +``` + +## Related Documentation + +- [Schema Aggregator Overview](overview.md) - Introduction and key features +- [API Reference](api-reference.md) - REST API endpoints and CLI commands +- [Schema.org Documentation](https://schema.org/) - Schema types reference +- [JSON-LD Specification](https://json-ld.org/) - Format specification +- [Yoast Schema API](../api.md) - Main Schema output API diff --git a/docs/features/schema/schema-aggregator/overview.md b/docs/features/schema/schema-aggregator/overview.md new file mode 100644 index 00000000..47a091c5 --- /dev/null +++ b/docs/features/schema/schema-aggregator/overview.md @@ -0,0 +1,157 @@ +--- +id: overview +title: "Schema Aggregator: Overview" +sidebar_label: Overview +description: An introduction to the Schema Aggregator feature in Yoast SEO. +--- + +The Schema Aggregator is a powerful feature in Yoast SEO that collects and serves structured data (schema.org markup) for all content across your WordPress site. + +### What gets aggregated + +By default, the Schema Aggregator processes: + +- All **public post types** (posts, pages, custom post types) + +You can customize which post types are included using the `wpseo_schema_aggregator_post_types` filter. + +### Schema types + +The aggregator handles over 1000 schema.org types, categorized into 9 contexts: + +- **Content**: Articles, blog posts, creative works +- **Commerce**: Products, offers, orders +- **Entity**: Organizations, persons, places +- **Event**: Events, schedules +- **Data**: Datasets, statistical information +- **Medical**: Medical conditions, therapies +- **Action**: Potential actions (filtered by default) +- **Enumeration**: Type definitions (filtered by default) +- **Meta**: Schema.org metadata (filtered by default) +- **Website**: Site structure elements (filtered by default) + +## Key features + +### REST API endpoints + +Access aggregated schema through clean REST endpoints: + +``` +GET /wp-json/yoast/v1/schema-aggregator/get-schema/{post_type}[/{page}] +GET /wp-json/yoast/v1/schema-aggregator/get-xml +``` + +### CLI commands + +Automate schema aggregation with WP-CLI: + +```bash +wp yoast aggregate_site_schema [--page=] +wp yoast clear_schema_aggregator_cache [] +``` + +### Caching + +The Schema Aggregator implements a dynamic caching strategy: + +- **Dynamic TTL**: Cache duration adapts to site size + - Small sites (< 100 posts): 24 hours + - Medium sites (100-1000 posts): 12 hours + - Large sites (> 1000 posts): 6 hours +- **Automatic invalidation**: Cache clears when posts are updated +- **Per-post-type caching**: Each post type has its own cache +- **Debug mode**: Bypass cache with `?debug=1` parameter + +### Schema map (XML sitemap for structured data) + +The schema map provides a XML index of all available schema endpoints: + +```xml + + + + https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post + + + https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/page + + +``` + +The schema map is automatically referenced in your site's `robots.txt`: + +``` +Sitemap: https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml +``` + +### External source support + +The Schema Aggregator seamlessly integrates with: + +- **WooCommerce**: Product schema automatically included +- **Easy Digital Downloads**: Download schema automatically included +- **Custom sources**: Extend with your own external schema repositories + +## Getting started + +### Enable the feature + +The Schema Aggregator is disabled by default in Yoast SEO. If you need to enable it, you can do so programmatically: + +```php +WPSEO_Options::set( 'enable_schema_aggregation_endpoint', true ); +``` +Or by enabling it via the Yoast SEO settings in the WordPress admin. + +### Example aggregated schema in JSON-L format + +Fetch schema for the `post` post type: + +```bash +curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post +``` + +Response: + +```json lines +{ + "@context": "https://schema.org", + "@type": "Article", + "@id": "https://example.com/hello-world/#article", + "headline": "Hello World", + "datePublished": "2026-01-15T10:30:00+00:00", + "author": { + "@id": "https://example.com/#/schema/person/1" + } +} +{ + "@context": "https://schema.org", + + "@type": "Article", + "@id": "https://example.com/your-second-post/#article", + "headline": "The second post", + "datePublished": "2026-01-15T10:30:00+00:00", + "author": { + "@id": "https://example.com/#/schema/person/1" + } +} +``` + +### Clear cache + +Clear all cached schema: + +```bash +wp yoast clear_schema_aggregator_cache +``` + +Clear cache for specific post type: + +```bash +wp yoast clear_schema_aggregator_cache post +``` +## Learn more + +- [Schema.org documentation](https://schema.org/) +- [JSON-LD specification](https://json-ld.org/) +- [Google structured data guidelines](https://developers.google.com/search/docs/appearance/structured-data/intro-structured-data) diff --git a/docs/overview.md b/docs/overview.md index cc5ac380..eb7622b5 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -32,6 +32,7 @@ Learn how our features work, how to customize the outputs, and how best to integ - [Schema.org markup](features/schema/) - [Schema pieces](/features/schema/pieces/) - [Output per plugin](/features/schema/plugins/) + - [Schema aggregator](/features/schema/schema-aggregator/) ## Integrating Want to integrate Yoast SEO into your platform? Check out our documentation on [integrating](/development/integrating.md), and familiarize yourself with all of our features and controls. diff --git a/sidebars.js b/sidebars.js index 94b05661..40d83442 100644 --- a/sidebars.js +++ b/sidebars.js @@ -262,6 +262,20 @@ module.exports = { "features/schema/plugins/yoast-seo-shopify", ], }, + { + type: "category", + label: "Schema Aggregator", + link: { + type: "generated-index", + description: "The Schema Aggregator collects and serves structured data for all content across your WordPress site through REST API endpoints and CLI commands.", + slug: "/features/schema/schema-aggregator", + }, + items: [ + "features/schema/schema-aggregator/overview", + "features/schema/schema-aggregator/api-reference", + "features/schema/schema-aggregator/filters", + ], + }, ], }, { From c16d1f7899bb923a78490075cc6968761fbc2e3c Mon Sep 17 00:00:00 2001 From: Thijs van der heijden Date: Thu, 5 Feb 2026 15:57:51 +0100 Subject: [PATCH 2/4] Update filtering specifications --- docs/features/schema/schema-aggregator/overview.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/features/schema/schema-aggregator/overview.md b/docs/features/schema/schema-aggregator/overview.md index 47a091c5..6bfa4f12 100644 --- a/docs/features/schema/schema-aggregator/overview.md +++ b/docs/features/schema/schema-aggregator/overview.md @@ -17,8 +17,9 @@ You can customize which post types are included using the `wpseo_schema_aggregat ### Schema types -The aggregator handles over 1000 schema.org types, categorized into 9 contexts: +The aggregator handles schema.org types, categorized into 10 contexts: +- **Website**: Site information - **Content**: Articles, blog posts, creative works - **Commerce**: Products, offers, orders - **Entity**: Organizations, persons, places @@ -28,8 +29,9 @@ The aggregator handles over 1000 schema.org types, categorized into 9 contexts: - **Action**: Potential actions (filtered by default) - **Enumeration**: Type definitions (filtered by default) - **Meta**: Schema.org metadata (filtered by default) -- **Website**: Site structure elements (filtered by default) +- **Website Meta**: Site structure elements, breadcrumbs (filtered by default) +The specific schema types that get filtered can be found at the [source](https://github.com/Yoast/wordpress-seo/blob/trunk/src/schema-aggregator/infrastructure/elements-context-map/default-elements-context-map.php). ## Key features ### REST API endpoints From 2dc008814b759b4621a6e67cf78ef17c4e853fdd Mon Sep 17 00:00:00 2001 From: "Paolo L. Scala" Date: Mon, 23 Feb 2026 16:34:34 +0100 Subject: [PATCH 3/4] Update documentation after refactoring --- .../schema/schema-aggregator/api-reference.md | 102 +++++++--- .../schema/schema-aggregator/filters.md | 187 ++++++------------ .../schema/schema-aggregator/overview.md | 15 +- 3 files changed, 141 insertions(+), 163 deletions(-) diff --git a/docs/features/schema/schema-aggregator/api-reference.md b/docs/features/schema/schema-aggregator/api-reference.md index 50976070..97006645 100644 --- a/docs/features/schema/schema-aggregator/api-reference.md +++ b/docs/features/schema/schema-aggregator/api-reference.md @@ -75,9 +75,6 @@ curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post # Get second page curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post/2 - -# Debug mode (bypass cache) -curl "https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post?debug=1" ``` --- @@ -101,13 +98,13 @@ None. - https://exampple.com/wp-json/yoast/v1/schema-aggregator/get-schema/page + https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/page 2026-01-01T14:03:56Z daily 0.8 - https://exampple.com/wp-json/yoast/v1/schema-aggregator/get-schema/post + https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post 2026-01-01T14:03:56Z daily 0.8 @@ -118,10 +115,11 @@ None. **Cache Headers:** -Responses include cache control headers matching the dynamic TTL strategy: -- Small sites (< 100 posts): 24 hours -- Medium sites (100-1000 posts): 12 hours -- Large sites (> 1000 posts): 6 hours +Responses include cache control headers with a 5-minute (300 seconds) cache duration: + +``` +Cache-Control: max-age=300 +``` **robots.txt Integration:** @@ -139,7 +137,7 @@ curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml **Customizing Post Types:** -By default, the schema map includes all public post types. You can customize this using the `wpseo_schema_aggregator_post_types` filter: +By default, the schema map includes all indexable post types. You can customize this using the `wpseo_schema_aggregator_post_types` filter: ```php add_filter( 'wpseo_schema_aggregator_post_types', 'customize_schema_post_types' ); @@ -237,8 +235,6 @@ By default, the Schema Aggregator removes schema pieces in the following categor This filtering reduces noise and focuses on meaningful content entities. -**Customize filtering:** - ### What Gets Enhanced The Schema Aggregator enhances certain schema types with additional data: @@ -247,35 +243,93 @@ The Schema Aggregator enhances certain schema types with additional data: Articles (and subtypes like `BlogPosting`, `NewsArticle`) are enhanced with: -1. **articleBody**: Full post content (configurable max length, default: 5000 characters) -2. **description**: Post excerpt (configurable max length, default: 320 characters) -3. **keywords**: Post tags as keyword array +1. **articleBody**: Full post content (configurable max length, default: 500 characters) +2. **description**: Post excerpt (configurable max length, default: no limit) +3. **keywords**: Post tags as keyword array (optionally includes categories) **Configuration:** ```php // Adjust article body length. -add_filter( 'wpseo_article_enhance_config_max_article_body_length', function() { - return 10000; // Increase to 10,000 characters. +add_filter( 'wpseo_article_enhance_config_article_body_max_length', function() { + return 2000; // Increase to 2,000 characters. } ); -// Adjust description length. -add_filter( 'wpseo_article_enhance_config_max_description_length', function() { - return 500; // Increase to 500 characters. +// Adjust excerpt length. +add_filter( 'wpseo_article_enhance_config_excerpt_max_length', function() { + return 500; // Limit to 500 characters. } ); +// Include categories as keywords. +add_filter( 'wpseo_article_enhance_config_categories_as_keywords', '__return_true' ); + // Disable article body enhancement. -add_filter( 'wpseo_article_enhance_config_add_article_body', '__return_false' ); +add_filter( 'wpseo_article_enhance_article_body', '__return_false' ); -// Disable description enhancement. -add_filter( 'wpseo_article_enhance_config_add_description', '__return_false' ); +// Disable excerpt enhancement. +add_filter( 'wpseo_article_enhance_use_excerpt', '__return_false' ); // Disable keywords enhancement. -add_filter( 'wpseo_article_enhance_config_add_keywords', '__return_false' ); +add_filter( 'wpseo_article_enhance_keywords', '__return_false' ); +``` + +#### Person Enhancement + +Person schema (`@type: Person`) is enhanced with: + +1. **jobTitle**: Retrieved from WordPress user meta (`job_title` field) + +**Configuration:** + +```php +// Disable job title enhancement. +add_filter( 'wpseo_person_enhance_person_job_title', '__return_false' ); +``` + +### Customize Filtering + +The Schema Aggregator uses a **strategy pattern** for filtering. The default strategy categorizes schema pieces using an elements-to-context map and filters out entire categories (Actions, Enumerations, Meta, Website). You can customize filtering at three levels: + +#### Replace the Entire Filtering Strategy + +Implement `Filtering_Strategy_Interface` and register it via the `wpseo_schema_aggregator_filtering_strategy` hook: + +```php +add_filter( 'wpseo_schema_aggregator_filtering_strategy', function( $default_filter ) { + return new My_Custom_Filter(); +} ); +``` + +Your custom class must implement the `filter` method, which receives a `Schema_Piece_Collection` and returns a filtered `Schema_Piece_Collection`. + +#### Modify the Elements-to-Context Map + +The default filtering strategy maps schema types into categories (e.g., `website`, `actions`, `meta`). You can modify this map with two filters: + +```php +// Replace the entire map. +add_filter( 'wpseo_schema_aggregator_elements_context_map', function( $map ) { + $map['my_category'] = [ 'WebPage', 'SomeOtherType' ]; + return $map; +} ); + +// Modify a single category (e.g., add Table to the website category). +add_filter( 'wpseo_schema_aggregator_elements_context_map_website', function( $types ) { + $types[] = 'Table'; + return $types; +} ); ``` +#### Conditional and Property-Level Filtering + +The default strategy also supports fine-grained control through node-level filters: + +- **Node filters** (`{Type}_Schema_Node_Filter`): Conditionally decide whether a schema piece of a given type should be filtered. For example, `WebPage` is only filtered when it represents an `Article`; otherwise it is kept. +- **Property filters** (`{Type}_Schema_Node_Property_Filter`): Remove specific properties from a schema piece rather than filtering the entire piece. + ## See Also - [Overview](overview.md): Introduction to Schema Aggregator +- [Filters](filters.md): Complete filter reference with examples - [Schema.org documentation](https://schema.org/) - [JSON-LD specification](https://json-ld.org/) diff --git a/docs/features/schema/schema-aggregator/filters.md b/docs/features/schema/schema-aggregator/filters.md index 341e4ecc..dcbfa01d 100644 --- a/docs/features/schema/schema-aggregator/filters.md +++ b/docs/features/schema/schema-aggregator/filters.md @@ -5,7 +5,7 @@ sidebar_label: Filters description: WordPress filters to customize the Schema Aggregator feature behavior and output. --- -The Schema Aggregator provides 18 WordPress filters that allow you to customize its behavior, from cache configuration to content enhancement. This document provides a complete reference with practical examples for each filter. +The Schema Aggregator provides WordPress filters that allow you to customize its behavior, from cache configuration to content enhancement. This document provides a complete reference with practical examples for each filter. ## Quick Reference @@ -23,11 +23,11 @@ The Schema Aggregator provides 18 WordPress filters that allow you to customize | [`wpseo_schema_aggregator_elements_context_map`](#elements-context-map) | Context Map | Override complete context map | | [`wpseo_schema_aggregator_elements_context_map_{context}`](#wpseo_schema_aggregator_elements_context_map_context) | Context Map | Customize elements for specific context | | [`wpseo_article_enhance_config_{key}`](#article-enhancement-configuration) | Article Enhancement | Configure article enhancement settings | -| [`wpseo_article_enhance_{enhancement}`](#article-enhancement-toggles) | Article Enhancement | Toggle specific article enhancements | +| [`wpseo_article_enhance_{enhancement}`](#article-enhancement-toggles) | Article Enhancement | Toggle article enhancements (article_body, use_excerpt, keywords) | | [`wpseo_article_enhance_body_when_excerpt_exists`](#article-body-with-excerpt) | Article Enhancement | Include body when excerpt exists | | [`wpseo_article_enhance_article_body_fallback`](#article-body-fallback) | Article Enhancement | Include body when no excerpt | | [`wpseo_person_enhance_config_{key}`](#person-enhancement-configuration) | Person Enhancement | Configure person enhancement settings | -| [`wpseo_person_enhance_{enhancement}`](#person-enhancement-toggles) | Person Enhancement | Toggle specific person enhancements | +| [`wpseo_person_enhance_{enhancement}`](#person-enhancement-toggles) | Person Enhancement | Toggle person enhancements (person_job_title) | | [`wpseo_disable_robots_schemamap`](#robotstxt-integration) | Robots.txt | Disable schema map in robots.txt | ## Post Type Configuration @@ -42,7 +42,7 @@ Control which post types are included in the schema aggregation. |-----------|------|-------------| | `$post_types` | array | Array of post type names to aggregate | -**Default Value:** All public post types +**Default Value:** All indexable post types **Example: Include Only Specific Post Types** @@ -254,13 +254,11 @@ Set the cache time-to-live (TTL) in seconds. | Parameter | Type | Description | |-----------|------|-------------| | `$ttl` | int | Cache duration in seconds | -| `$post_type` | string | The post type being cached | -| `$post_count` | int | Number of posts for this post type | -**Default Value:** Dynamic based on site size: -- Small sites (< 100 posts): 86400 seconds (24 hours) -- Medium sites (100-1000 posts): 43200 seconds (12 hours) -- Large sites (> 1000 posts): 21600 seconds (6 hours) +**Default Value:** Dynamic based on serialized payload size: +- Small payloads (< 100 KB): 1800 seconds (30 minutes) +- Normal payloads: 3600 seconds (1 hour) +- Large payloads (> 1 MB): 21600 seconds (6 hours) **Example: Fixed TTL** @@ -268,52 +266,20 @@ Set the cache time-to-live (TTL) in seconds. add_filter( 'wpseo_schema_aggregator_cache_ttl', 'custom_cache_ttl' ); /** - * Set a fixed cache duration for all post types. + * Set a fixed cache duration. * * Use this when you want consistent cache behavior regardless - * of site size or post type. + * of payload size. * * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_cache_ttl * - * @param int $ttl Cache duration in seconds. - * @param string $post_type Post type being cached. - * @param int $post_count Number of posts. + * @param int $ttl Cache duration in seconds. * * @return int Modified cache duration. */ -function custom_cache_ttl( $ttl, $post_type, $post_count ) { - // Cache for 1 hour (3600 seconds) regardless of size. - return 3600; -} -``` - -**Example: Post Type Specific TTL** - -```php -add_filter( 'wpseo_schema_aggregator_cache_ttl', 'post_type_specific_ttl', 10, 3 ); - -/** - * Set different cache durations for different post types. - * - * Frequently updated content gets shorter cache times, - * while static content can be cached longer. - * - * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#wpseo_schema_aggregator_cache_ttl - * - * @param int $ttl Cache duration in seconds. - * @param string $post_type Post type being cached. - * @param int $post_count Number of posts. - * - * @return int Modified cache duration. - */ -function post_type_specific_ttl( $ttl, $post_type, $post_count ) { - $custom_ttls = [ - 'post' => 1800, // 30 minutes for frequently updated posts. - 'page' => 86400, // 24 hours for static pages. - 'product' => 3600, // 1 hour for product catalog. - ]; - - return $custom_ttls[ $post_type ] ?? $ttl; +function custom_cache_ttl( $ttl ) { + // Cache for 2 hours regardless of payload size. + return 7200; } ``` @@ -401,9 +367,9 @@ Implement a custom filtering strategy by providing your own strategy class. | Parameter | Type | Description | |-----------|------|-------------| -| `$strategy` | object\|null | Custom filtering strategy instance | +| `$strategy` | Filtering_Strategy_Interface | The filtering strategy instance | -**Default Value:** `null` (uses default strategy) +**Default Value:** `Default_Filter` instance (filters Actions, Enumerations, Meta, and Website categories) **Example:** @@ -575,16 +541,17 @@ Articles and their subtypes (BlogPosting, NewsArticle, etc.) can be enhanced wit Use the `wpseo_article_enhance_config_{key}` filter pattern to configure enhancement behavior. Available keys: -- `max_article_body_length` - Maximum length for articleBody (default: 5000) -- `max_description_length` - Maximum length for description (default: 320) -- `add_article_body` - Whether to add articleBody (default: true) -- `add_description` - Whether to add description (default: true) -- `add_keywords` - Whether to add keywords (default: true) +- `article_body_max_length` - Maximum length for articleBody in characters (default: 500) +- `excerpt_max_length` - Maximum length for excerpt in characters (default: 0, no limit) +- `categories_as_keywords` - Include categories as keywords (default: false) +- `excerpt_prefer_manual` - Only use manually written excerpts; skip auto-generated ones (default: false) +- `strip_shortcodes_from_body` - Strip shortcodes from article body (default: true) +- `strip_html_from_body` - Strip HTML tags from article body (default: true) -**Example: Adjust Maximum Lengths** +**Example: Adjust Article Body Length** ```php -add_filter( 'wpseo_article_enhance_config_max_article_body_length', 'custom_article_body_length' ); +add_filter( 'wpseo_article_enhance_config_article_body_max_length', 'custom_article_body_length' ); /** * Increase maximum article body length. @@ -599,63 +566,36 @@ add_filter( 'wpseo_article_enhance_config_max_article_body_length', 'custom_arti * @return int Modified maximum length. */ function custom_article_body_length( $max_length ) { - return 10000; // Increase from 5000 to 10000 characters. + return 2000; // Increase from 500 to 2000 characters. } ``` -```php -add_filter( 'wpseo_article_enhance_config_max_description_length', 'custom_description_length' ); +**Example: Include Categories as Keywords** -/** - * Adjust maximum description length. - * - * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#article-enhancement-configuration - * - * @param int $max_length Maximum length in characters. - * - * @return int Modified maximum length. - */ -function custom_description_length( $max_length ) { - return 500; // Increase from 320 to 500 characters. -} +```php +add_filter( 'wpseo_article_enhance_config_categories_as_keywords', '__return_true' ); ``` -**Example: Disable Specific Enhancements** +**Example: Only Use Manual Excerpts** ```php -add_filter( 'wpseo_article_enhance_config_add_article_body', '__return_false' ); +add_filter( 'wpseo_article_enhance_config_excerpt_prefer_manual', '__return_true' ); ``` ### Article Enhancement Toggles -Use the `wpseo_article_enhance_{enhancement}` filter pattern to enable or disable enhancements dynamically. Available enhancements match the configuration keys: `article_body`, `description`, `keywords`. +Use the `wpseo_article_enhance_{enhancement}` filter pattern to enable or disable enhancements dynamically. Available enhancements: `article_body`, `use_excerpt`, `keywords` (all default to `true`). -**Example: Conditional Article Body** +**Example: Disable Article Body Enhancement** ```php -add_filter( 'wpseo_article_enhance_article_body', 'conditional_article_body', 10, 2 ); +add_filter( 'wpseo_article_enhance_article_body', '__return_false' ); +``` -/** - * Only include article body for certain post types. - * - * This allows fine-grained control over which content types - * receive full body enhancement. - * - * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#article-enhancement-toggles - * - * @param bool $enabled Whether enhancement is enabled. - * @param array $schema_piece The schema piece being enhanced. - * - * @return bool Modified enabled status. - */ -function conditional_article_body( $enabled, $schema_piece ) { - // Only add article body for blog posts, not news articles. - if ( isset( $schema_piece['@type'] ) && $schema_piece['@type'] === 'NewsArticle' ) { - return false; - } +**Example: Disable Excerpt Enhancement** - return $enabled; -} +```php +add_filter( 'wpseo_article_enhance_use_excerpt', '__return_false' ); ``` ### Article Body with Excerpt @@ -669,7 +609,6 @@ Control whether to include article body when an excerpt already exists. | Parameter | Type | Description | |-----------|------|-------------| | `$include_body` | bool | Whether to include body when excerpt exists | -| `$schema_piece` | array | The schema piece being enhanced | **Default Value:** `false` @@ -690,7 +629,6 @@ Control whether to include article body when no excerpt exists. | Parameter | Type | Description | |-----------|------|-------------| | `$use_fallback` | bool | Whether to use body as fallback | -| `$schema_piece` | array | The schema piece being enhanced | **Default Value:** `true` @@ -706,52 +644,37 @@ Person schema pieces can be enhanced with additional properties based on WordPre ### Person Enhancement Configuration -Use the `wpseo_person_enhance_config_{key}` filter pattern to configure person enhancement. The exact available keys depend on your implementation. +Use the `wpseo_person_enhance_config_{key}` filter pattern to configure person enhancement settings. This follows the same generic pattern as article enhancement configuration — the filter receives a default value and returns a customized one. **Example:** ```php -add_filter( 'wpseo_person_enhance_config_include_social_profiles', '__return_true' ); -``` - -### Person Enhancement Toggles - -Use the `wpseo_person_enhance_\{enhancement\}` filter pattern to enable or disable specific person enhancements dynamically. - -**Example:** - -```php -add_filter( 'wpseo_person_enhance_bio', 'conditional_person_bio', 10, 2 ); +add_filter( 'wpseo_person_enhance_config_my_custom_key', 'custom_person_config' ); /** - * Only include person bio for authors with posts. + * Customize a person enhancement configuration value. * - * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#person-enhancement-toggles + * @link https://developer.yoast.com/features/schema/schema-aggregator/filters/#person-enhancement-configuration * - * @param bool $enabled Whether enhancement is enabled. - * @param array $schema_piece The schema piece being enhanced. + * @param string|int|bool $value The default configuration value. * - * @return bool Modified enabled status. + * @return string|int|bool Modified configuration value. */ -function conditional_person_bio( $enabled, $schema_piece ) { - // Extract user ID from schema piece if available. - if ( isset( $schema_piece['@id'] ) ) { - // Parse user ID from the @id. - preg_match( '/person\/(\d+)/', $schema_piece['@id'], $matches ); - - if ( ! empty( $matches[1] ) ) { - $user_id = (int) $matches[1]; - $post_count = count_user_posts( $user_id ); - - // Only include bio if user has published posts. - return $post_count > 0; - } - } - - return $enabled; +function custom_person_config( $value ) { + return 'custom_value'; } ``` +### Person Enhancement Toggles + +Use the `wpseo_person_enhance_{enhancement}` filter pattern to enable or disable specific person enhancements. Available enhancements: `person_job_title` (default: `true`). + +**Example: Disable Job Title Enhancement** + +```php +add_filter( 'wpseo_person_enhance_person_job_title', '__return_false' ); +``` + ## Robots.txt Integration By default, the schema map is automatically referenced in your site's `robots.txt` file. You can disable this integration if needed. diff --git a/docs/features/schema/schema-aggregator/overview.md b/docs/features/schema/schema-aggregator/overview.md index 6bfa4f12..aecbf362 100644 --- a/docs/features/schema/schema-aggregator/overview.md +++ b/docs/features/schema/schema-aggregator/overview.md @@ -5,13 +5,12 @@ sidebar_label: Overview description: An introduction to the Schema Aggregator feature in Yoast SEO. --- -The Schema Aggregator is a powerful feature in Yoast SEO that collects and serves structured data (schema.org markup) for all content across your WordPress site. +The Schema Aggregator collects structured data (schema.org markup) for all content across your WordPress site and serves it through a unified REST API. +This allows search engines and other consumers to easily access comprehensive schema data without needing to crawl individual pages. ### What gets aggregated -By default, the Schema Aggregator processes: - -- All **public post types** (posts, pages, custom post types) +By default, the Schema Aggregator processes all **public post types** (posts, pages, custom post types). You can customize which post types are included using the `wpseo_schema_aggregator_post_types` filter. @@ -31,12 +30,14 @@ The aggregator handles schema.org types, categorized into 10 contexts: - **Meta**: Schema.org metadata (filtered by default) - **Website Meta**: Site structure elements, breadcrumbs (filtered by default) -The specific schema types that get filtered can be found at the [source](https://github.com/Yoast/wordpress-seo/blob/trunk/src/schema-aggregator/infrastructure/elements-context-map/default-elements-context-map.php). +The specific schema types that get filtered are specified in the [source code](https://github.com/Yoast/wordpress-seo/blob/trunk/src/schema-aggregator/infrastructure/elements-context-map/default-elements-context-map.php). + + ## Key features ### REST API endpoints -Access aggregated schema through clean REST endpoints: +The aggregated schema can be accessed through the following REST endpoints: ``` GET /wp-json/yoast/v1/schema-aggregator/get-schema/{post_type}[/{page}] @@ -66,7 +67,7 @@ The Schema Aggregator implements a dynamic caching strategy: ### Schema map (XML sitemap for structured data) -The schema map provides a XML index of all available schema endpoints: +The schema map provides an XML index of all available schema endpoints: ```xml From 603f57b0374a55ec6f9fc290d2d52be650a170b0 Mon Sep 17 00:00:00 2001 From: "Paolo L. Scala" Date: Tue, 24 Feb 2026 10:04:14 +0100 Subject: [PATCH 4/4] Remove references to the debug mode and change schema map to schemamap --- .../schema/schema-aggregator/api-reference.md | 7 +-- .../schema/schema-aggregator/filters.md | 56 +++++++++---------- .../schema/schema-aggregator/overview.md | 7 +-- 3 files changed, 34 insertions(+), 36 deletions(-) diff --git a/docs/features/schema/schema-aggregator/api-reference.md b/docs/features/schema/schema-aggregator/api-reference.md index 97006645..e5b0d3b8 100644 --- a/docs/features/schema/schema-aggregator/api-reference.md +++ b/docs/features/schema/schema-aggregator/api-reference.md @@ -24,7 +24,6 @@ GET /wp-json/yoast/v1/schema-aggregator/get-schema/{post_type}[/{page}] |-----------|------|----------|---------|-------------| | `post_type` | string | Yes | - | The post type to aggregate (e.g., `post`, `page`, `product`) | | `page` | integer | No | 1 | Page number for pagination | -| `debug` | boolean | No | false | Disables cache when set to true (add `?debug=1` to URL) | **Pagination:** @@ -79,7 +78,7 @@ curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-schema/post/2 --- -### Get XML Schema Map +### Get XML Schemamap Retrieve an XML sitemap of all available schema endpoints. @@ -123,7 +122,7 @@ Cache-Control: max-age=300 **robots.txt Integration:** -The schema map is automatically referenced in your site's `robots.txt`: +The schemamap is automatically referenced in your site's `robots.txt`: ``` Sitemap: https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml @@ -137,7 +136,7 @@ curl https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml **Customizing Post Types:** -By default, the schema map includes all indexable post types. You can customize this using the `wpseo_schema_aggregator_post_types` filter: +By default, the schemamap includes all indexable post types. You can customize this using the `wpseo_schema_aggregator_post_types` filter: ```php add_filter( 'wpseo_schema_aggregator_post_types', 'customize_schema_post_types' ); diff --git a/docs/features/schema/schema-aggregator/filters.md b/docs/features/schema/schema-aggregator/filters.md index dcbfa01d..e15195a0 100644 --- a/docs/features/schema/schema-aggregator/filters.md +++ b/docs/features/schema/schema-aggregator/filters.md @@ -9,26 +9,26 @@ The Schema Aggregator provides WordPress filters that allow you to customize its ## Quick Reference -| Filter | Category | Purpose | -|--------|----------|---------| -| [`wpseo_schema_aggregator_post_types`](#post-type-configuration) | Post Types | Control which post types to aggregate | -| [`wpseo_schema_aggregator_per_page`](#pagination-configuration) | Pagination | Set default items per page (1000) | -| [`wpseo_schema_aggregator_per_page_big`](#pagination-configuration) | Pagination | Set items per page for big schema post types (100) | -| [`wpseo_schema_aggregator_big_schema_post_types`](#pagination-configuration) | Pagination | Define which post types have large schema | -| [`wpseo_schema_aggregator_cache_enabled`](#cache-configuration) | Cache | Enable/disable caching | -| [`wpseo_schema_aggregator_cache_ttl`](#cache-configuration) | Cache | Set cache duration (dynamic by default) | -| [`wpseo_schema_aggregator_schemamap_changefreq`](#schema-map-configuration) | Schema Map | Set XML sitemap update frequency | -| [`wpseo_schema_aggregator_schemamap_priority`](#schema-map-configuration) | Schema Map | Set XML sitemap priority | -| [`wpseo_schema_aggregator_filtering_strategy`](#filtering-strategy) | Filtering | Implement custom filtering logic | -| [`wpseo_schema_aggregator_elements_context_map`](#elements-context-map) | Context Map | Override complete context map | -| [`wpseo_schema_aggregator_elements_context_map_{context}`](#wpseo_schema_aggregator_elements_context_map_context) | Context Map | Customize elements for specific context | -| [`wpseo_article_enhance_config_{key}`](#article-enhancement-configuration) | Article Enhancement | Configure article enhancement settings | +| Filter | Category | Purpose | +|--------|---------------------|------------------------------------------------------------------| +| [`wpseo_schema_aggregator_post_types`](#post-type-configuration) | Post Types | Control which post types to aggregate | +| [`wpseo_schema_aggregator_per_page`](#pagination-configuration) | Pagination | Set default items per page (1000) | +| [`wpseo_schema_aggregator_per_page_big`](#pagination-configuration) | Pagination | Set items per page for big schema post types (100) | +| [`wpseo_schema_aggregator_big_schema_post_types`](#pagination-configuration) | Pagination | Define which post types have large schema | +| [`wpseo_schema_aggregator_cache_enabled`](#cache-configuration) | Cache | Enable/disable caching | +| [`wpseo_schema_aggregator_cache_ttl`](#cache-configuration) | Cache | Set cache duration (dynamic by default) | +| [`wpseo_schema_aggregator_schemamap_changefreq`](#schema-map-configuration) | schemamap | Set XML schemamap update frequency | +| [`wpseo_schema_aggregator_schemamap_priority`](#schema-map-configuration) | schemamap | Set XML schemamap priority | +| [`wpseo_schema_aggregator_filtering_strategy`](#filtering-strategy) | Filtering | Implement custom filtering logic | +| [`wpseo_schema_aggregator_elements_context_map`](#elements-context-map) | Context Map | Override complete context map | +| [`wpseo_schema_aggregator_elements_context_map_{context}`](#wpseo_schema_aggregator_elements_context_map_context) | Context Map | Customize elements for specific context | +| [`wpseo_article_enhance_config_{key}`](#article-enhancement-configuration) | Article Enhancement | Configure article enhancement settings | | [`wpseo_article_enhance_{enhancement}`](#article-enhancement-toggles) | Article Enhancement | Toggle article enhancements (article_body, use_excerpt, keywords) | -| [`wpseo_article_enhance_body_when_excerpt_exists`](#article-body-with-excerpt) | Article Enhancement | Include body when excerpt exists | -| [`wpseo_article_enhance_article_body_fallback`](#article-body-fallback) | Article Enhancement | Include body when no excerpt | -| [`wpseo_person_enhance_config_{key}`](#person-enhancement-configuration) | Person Enhancement | Configure person enhancement settings | -| [`wpseo_person_enhance_{enhancement}`](#person-enhancement-toggles) | Person Enhancement | Toggle person enhancements (person_job_title) | -| [`wpseo_disable_robots_schemamap`](#robotstxt-integration) | Robots.txt | Disable schema map in robots.txt | +| [`wpseo_article_enhance_body_when_excerpt_exists`](#article-body-with-excerpt) | Article Enhancement | Include body when excerpt exists | +| [`wpseo_article_enhance_article_body_fallback`](#article-body-fallback) | Article Enhancement | Include body when no excerpt | +| [`wpseo_person_enhance_config_{key}`](#person-enhancement-configuration) | Person Enhancement | Configure person enhancement settings | +| [`wpseo_person_enhance_{enhancement}`](#person-enhancement-toggles) | Person Enhancement | Toggle person enhancements (person_job_title) | +| [`wpseo_disable_robots_schemamap`](#robotstxt-integration) | Robots.txt | Disable schemamap in robots.txt | ## Post Type Configuration @@ -283,13 +283,13 @@ function custom_cache_ttl( $ttl ) { } ``` -## Schema Map Configuration +## Schemamap Configuration -The schema map is an XML sitemap that lists all available schema endpoints. It's automatically referenced in your site's `robots.txt`. +The schemamap is an XML sitemap that lists all available schema endpoints. It's automatically referenced in your site's `robots.txt`. ### wpseo_schema_aggregator_schemamap_changefreq -Set the change frequency for schema map entries. +Set the change frequency for schemamap entries. **Parameters:** @@ -305,7 +305,7 @@ Set the change frequency for schema map entries. add_filter( 'wpseo_schema_aggregator_schemamap_changefreq', 'custom_schemamap_changefreq' ); /** - * Set schema map change frequency to weekly. + * Set schemamap change frequency to weekly. * * Use this to indicate how often search engines should check * for updated schema data. @@ -323,7 +323,7 @@ function custom_schemamap_changefreq( $changefreq ) { ### wpseo_schema_aggregator_schemamap_priority -Set the priority value for schema map entries. +Set the priority value for schemamap entries. **Parameters:** @@ -339,7 +339,7 @@ Set the priority value for schema map entries. add_filter( 'wpseo_schema_aggregator_schemamap_priority', 'custom_schemamap_priority' ); /** - * Increase schema map priority to indicate importance. + * Increase schemamap priority to indicate importance. * * Higher priority suggests to search engines that this content * is important relative to other URLs on your site. @@ -677,11 +677,11 @@ add_filter( 'wpseo_person_enhance_person_job_title', '__return_false' ); ## Robots.txt Integration -By default, the schema map is automatically referenced in your site's `robots.txt` file. You can disable this integration if needed. +By default, the schemamap is automatically referenced in your site's `robots.txt` file. You can disable this integration if needed. ### wpseo_disable_robots_schemamap -Disable the schema map reference in robots.txt. +Disable the schemamap reference in robots.txt. **Parameters:** @@ -716,7 +716,7 @@ add_filter( 'wpseo_schema_aggregator_per_page', function() { return defined( 'WP_DEBUG' ) && WP_DEBUG ? 10 : 1000; } ); -// Don't add schema map to robots.txt in development. +// Don't add schemamap to robots.txt in development. add_filter( 'wpseo_disable_robots_schemamap', function() { return defined( 'WP_DEBUG' ) && WP_DEBUG; } ); diff --git a/docs/features/schema/schema-aggregator/overview.md b/docs/features/schema/schema-aggregator/overview.md index aecbf362..7cc4c6f3 100644 --- a/docs/features/schema/schema-aggregator/overview.md +++ b/docs/features/schema/schema-aggregator/overview.md @@ -63,11 +63,10 @@ The Schema Aggregator implements a dynamic caching strategy: - Large sites (> 1000 posts): 6 hours - **Automatic invalidation**: Cache clears when posts are updated - **Per-post-type caching**: Each post type has its own cache -- **Debug mode**: Bypass cache with `?debug=1` parameter -### Schema map (XML sitemap for structured data) +### Schemamap (XML map for structured data) -The schema map provides an XML index of all available schema endpoints: +The schemamap provides an XML index of all available schema endpoints: ```xml @@ -81,7 +80,7 @@ The schema map provides an XML index of all available schema endpoints: ``` -The schema map is automatically referenced in your site's `robots.txt`: +The schemamap is automatically referenced in your site's `robots.txt`: ``` Sitemap: https://example.com/wp-json/yoast/v1/schema-aggregator/get-xml