{"id":30827474,"url":"https://github.com/builtnorth/wp-schema","last_synced_at":"2026-01-20T16:59:09.307Z","repository":{"id":309476038,"uuid":"1017706401","full_name":"builtnorth/wp-schema","owner":"builtnorth","description":"A WordPress SEO schema generation framework","archived":false,"fork":false,"pushed_at":"2025-08-26T06:42:44.000Z","size":306,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-26T08:37:22.755Z","etag":null,"topics":["schema","schema-org","wordpress","wordpress-development","wordpress-plugin"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/builtnorth/wp-schema","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/builtnorth.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-11T01:17:24.000Z","updated_at":"2025-08-26T06:42:52.000Z","dependencies_parsed_at":"2025-08-12T05:38:59.850Z","dependency_job_id":"01530f27-2df9-45e0-94ae-4ed4f86337ed","html_url":"https://github.com/builtnorth/wp-schema","commit_stats":null,"previous_names":["builtnorth/wp-schema"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/builtnorth/wp-schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtnorth%2Fwp-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtnorth%2Fwp-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtnorth%2Fwp-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtnorth%2Fwp-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/builtnorth","download_url":"https://codeload.github.com/builtnorth/wp-schema/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/builtnorth%2Fwp-schema/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":273908581,"owners_count":25189162,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-06T02:00:13.247Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["schema","schema-org","wordpress","wordpress-development","wordpress-plugin"],"created_at":"2025-09-06T13:12:53.534Z","updated_at":"2026-01-20T16:59:09.260Z","avatar_url":"https://github.com/builtnorth.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# WP Schema Framework\n\nA comprehensive, WordPress schema generation framework with a clean provider-based architecture.\n\n## Architecture\n\nWP Schema follows a clean, modular architecture:\n\n- **Core Framework**: Provider registration, schema assembly, and output management\n- **Provider System**: Hook-based registration for extensible schema generation\n- **Clean References**: Schema graphs with @id references and automatic deduplication\n- **WordPress Integration**: Deep integration with WordPress core data and features\n- **@graph Format**: Modern JSON-LD output using Google's recommended @graph structure\n\n## Features\n\n- **Simple Provider Interface**: Easy to implement schema providers\n- **Comprehensive Coverage**: Built-in providers for all major WordPress contexts\n- **Registration Priority System**: Predictable schema ordering with priority-based registration\n- **Flexible Filtering**: Multiple filter hooks for customization at every level\n- **Reference Resolution**: Clean @id references for building complex schema graphs\n- **WordPress Core Integration**: Automatic schema for posts, pages, archives, media, and more\n- **Type Registry**: Comprehensive registry of 250+ schema.org types with UI support\n\n## Installation\n\n```bash\n# Via Composer\ncomposer require builtnorth/wp-schema\n```\n\n## Quick Start\n\nInitialize the framework in your plugin or theme:\n\n```php\n// Initialize wp-schema\nif (class_exists('BuiltNorth\\WPSchema\\App')) {\n\tadd_action('init', function() {\n\t\tBuiltNorth\\WPSchema\\App::initialize();\n\t});\n}\n```\n\nOnce initialized, the framework automatically outputs schema via HTML `\u003cscript type=\"application/ld+json\"\u003e` tags in the document head.\n\n### For Plugin Developers\n\nRegister your schema providers via hook:\n\n```php\nadd_action('wp_schema_framework_register_providers', function($provider_manager) {\n    $provider_manager-\u003eregister(\n        'my_plugin_provider',\n        'MyPlugin\\\\Schema\\\\MySchemaProvider'\n    );\n});\n```\n\n### Simple Filter Approach\n\nFor basic schema additions:\n\n```php\nadd_filter('wp_schema_framework_pieces', function($pieces, $context) {\n    if ($context === 'singular' \u0026\u0026 get_post_type() === 'event') {\n        $pieces[] = [\n            '@type' =\u003e 'Event',\n            'name' =\u003e get_the_title(),\n            'startDate' =\u003e get_post_meta(get_the_ID(), 'event_date', true)\n        ];\n    }\n    return $pieces;\n}, 10, 2);\n```\n\n### Schema Type Override\n\nOverride the schema type for specific posts:\n\n```php\nadd_filter('wp_schema_framework_post_type_override', function($type, $post_id, $post_type, $post) {\n    if (get_post_meta($post_id, 'page_type', true) === 'contact') {\n        return 'ContactPage';\n    }\n    return $type;\n}, 10, 4);\n```\n\n### Product Schema Integration\n\nThe ProductProvider automatically detects WooCommerce, Easy Digital Downloads, and BigCommerce products. \n\n**Note**: To avoid conflicts, ProductProvider automatically disables itself when WooCommerce's built-in schema is active. To force wp-schema to handle product schema instead:\n\n```php\n// Disable WooCommerce's built-in structured data\nadd_filter('woocommerce_structured_data_disable', '__return_true');\n\n// Or tell wp-schema that WooCommerce schema is not active\nadd_filter('wp_schema_framework_woocommerce_schema_active', '__return_false');\n```\n\nYou can also integrate custom e-commerce solutions:\n\n```php\n// Mark custom post type as product\nadd_filter('wp_schema_framework_is_product', function($is_product, $post_id, $context) {\n    return get_post_type($post_id) === 'my_product_type';\n}, 10, 3);\n\n// Provide product data for custom e-commerce\nadd_filter('wp_schema_framework_get_product_data', function($data, $post_id) {\n    if (get_post_type($post_id) !== 'my_product_type') {\n        return $data;\n    }\n    \n    return [\n        'name' =\u003e get_the_title($post_id),\n        'price' =\u003e get_post_meta($post_id, 'price', true),\n        'currency' =\u003e 'USD',\n        'availability' =\u003e 'https://schema.org/InStock',\n        'sku' =\u003e get_post_meta($post_id, 'sku', true),\n        'brand' =\u003e get_post_meta($post_id, 'brand', true),\n        'aggregateRating' =\u003e [\n            'ratingValue' =\u003e get_post_meta($post_id, 'rating', true),\n            'reviewCount' =\u003e get_post_meta($post_id, 'review_count', true),\n        ],\n    ];\n}, 10, 2);\n```\n\n### Event Schema Integration\n\nThe EventProvider automatically detects The Events Calendar, Events Manager, Modern Events Calendar, and Event Organiser. You can also integrate custom event solutions:\n\n```php\n// Mark custom post type as event\nadd_filter('wp_schema_framework_is_event', function($is_event, $post_id, $context) {\n    return get_post_type($post_id) === 'my_event_type';\n}, 10, 3);\n\n// Provide event data for custom events\nadd_filter('wp_schema_framework_get_event_data', function($data, $post_id) {\n    if (get_post_type($post_id) !== 'my_event_type') {\n        return $data;\n    }\n    \n    return [\n        'name' =\u003e get_the_title($post_id),\n        'description' =\u003e get_the_excerpt($post_id),\n        'startDate' =\u003e get_post_meta($post_id, 'event_start', true), // ISO 8601 format\n        'endDate' =\u003e get_post_meta($post_id, 'event_end', true),\n        'eventStatus' =\u003e 'https://schema.org/EventScheduled',\n        'eventAttendanceMode' =\u003e 'https://schema.org/OfflineEventAttendanceMode',\n        'location' =\u003e [\n            'name' =\u003e get_post_meta($post_id, 'venue_name', true),\n            'address' =\u003e [\n                'streetAddress' =\u003e get_post_meta($post_id, 'venue_address', true),\n                'addressLocality' =\u003e get_post_meta($post_id, 'venue_city', true),\n                'addressRegion' =\u003e get_post_meta($post_id, 'venue_state', true),\n                'postalCode' =\u003e get_post_meta($post_id, 'venue_zip', true),\n            ],\n            'type' =\u003e 'Place'\n        ],\n        'offers' =\u003e [\n            'price' =\u003e get_post_meta($post_id, 'ticket_price', true),\n            'currency' =\u003e 'USD',\n            'availability' =\u003e 'https://schema.org/InStock',\n        ],\n    ];\n}, 10, 2);\n```\n\n\n## Provider Interface\n\nCreate schema providers by implementing `SchemaProviderInterface`:\n\n```php\n\u003c?php\n\nnamespace MyPlugin\\Schema;\n\nuse BuiltNorth\\WPSchema\\Contracts\\SchemaProviderInterface;\n\nclass MySchemaProvider implements SchemaProviderInterface\n{\n    public function can_provide(string $context): bool\n    {\n        // Return true if this provider can generate schema for the current context\n        return $context === 'singular' \u0026\u0026 get_post_type() === 'my_post_type';\n    }\n\n    public function get_pieces(string $context): array\n    {\n        // Return array of schema pieces\n        return [\n            [\n                '@type' =\u003e 'Thing',\n                '@id' =\u003e get_permalink() . '#my-thing',\n                'name' =\u003e get_the_title()\n            ]\n        ];\n    }\n\n    public function get_priority(): int\n    {\n        // Return priority for ordering (lower = higher priority)\n        return 20;\n    }\n}\n```\n\n## Built-in Providers\n\n### Core Content Providers\n\n- **OrganizationProvider**: Organization/LocalBusiness schema with support for all organization types\n- **WebsiteProvider**: WebSite schema with site-wide metadata and SearchAction for sitelinks\n- **ArticleProvider**: Article, BlogPosting, and NewsArticle schema for posts\n- **ProductProvider**: Product schema with auto-detection for WooCommerce, Easy Digital Downloads, and BigCommerce\n- **EventProvider**: Event schema with auto-detection for The Events Calendar, Events Manager, Modern Events Calendar, and Event Organiser\n- **AuthorProvider**: Person schema for post authors\n- **NavigationProvider**: SiteNavigationElement schema from WordPress menus\n\n### Page Type Providers\n\n- **PageTypeProvider**: Specialized page types (ContactPage, AboutPage, FAQPage, etc.)\n- **WebPageProvider**: Standard WebPage schema for pages\n- **ArchiveProvider**: CollectionPage and ItemList for category, tag, and date archives\n- **SearchResultsProvider**: SearchResultsPage with search action and results\n- **MediaProvider**: ImageObject, VideoObject, and AudioObject for attachments\n\n### Enhancement Providers\n\n- **CommentProvider**: Comment schema added to posts and pages\n- **LogoProvider**: Organization logo from WordPress site logo/custom logo\n- **SiteIconProvider**: Site icon/favicon added to WebSite schema\n- **GenericSchemaProvider**: Handles custom schema types via post meta and filters\n\n## Schema Output\n\nThe package outputs clean schema with proper relationships using the @graph format:\n\n```json\n{\n\t\"@context\": \"https://schema.org\",\n\t\"@graph\": [\n\t\t{\n\t\t\t\"@type\": \"Organization\",\n\t\t\t\"@id\": \"https://example.com/#organization\",\n\t\t\t\"name\": \"My Organization\",\n\t\t\t\"logo\": {\n\t\t\t\t\"@type\": \"ImageObject\",\n\t\t\t\t\"url\": \"https://example.com/logo.png\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"@type\": \"WebSite\",\n\t\t\t\"@id\": \"https://example.com/#website\",\n\t\t\t\"name\": \"My Site\",\n\t\t\t\"publisher\": { \"@id\": \"https://example.com/#organization\" },\n\t\t\t\"image\": {\n\t\t\t\t\"@type\": \"ImageObject\",\n\t\t\t\t\"url\": \"https://example.com/icon.png\"\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"@type\": \"Article\",\n\t\t\t\"@id\": \"https://example.com/post/#article\",\n\t\t\t\"headline\": \"Article Title\",\n\t\t\t\"author\": { \"@id\": \"https://example.com/#author-1\" },\n\t\t\t\"publisher\": { \"@id\": \"https://example.com/#organization\" },\n\t\t\t\"comment\": [\n\t\t\t\t{\n\t\t\t\t\t\"@type\": \"Comment\",\n\t\t\t\t\t\"author\": { \"@type\": \"Person\", \"name\": \"Commenter\" },\n\t\t\t\t\t\"text\": \"Great article!\"\n\t\t\t\t}\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"@type\": \"Person\",\n\t\t\t\"@id\": \"https://example.com/#author-1\",\n\t\t\t\"name\": \"Author Name\",\n\t\t\t\"url\": \"https://example.com/author/authorname/\"\n\t\t}\n\t]\n}\n```\n\n## Contexts\n\nThe system recognizes these contexts for schema generation:\n\n- `home` - Front page\n- `singular` - Individual posts/pages\n- `archive` - Archive pages (categories, tags, dates, authors, custom taxonomies)\n- `search` - Search results pages\n- `404` - 404 error pages\n- `attachment` - Media/attachment pages\n\n## Available Hooks\n\n### Hooks \u0026 Filters\n\nThe framework provides extensive hooks and filters for customization. Here are the most commonly used:\n\n#### Actions\n- `wp_schema_framework_register_providers` - Register custom providers\n- `wp_schema_framework_ready` - Framework initialization complete\n- `wp_schema_framework_before_output` - Before schema is output to page\n- `wp_schema_framework_after_output` - After schema has been output\n\n#### Core Filters\n- `wp_schema_framework_output_enabled` - Enable/disable schema output globally\n- `wp_schema_framework_context` - Override detected page context\n- `wp_schema_framework_pieces` - Modify final schema pieces array\n- `wp_schema_framework_graph` - Modify complete schema graph before output\n- `wp_schema_framework_json_output` - Modify final JSON-LD string before output\n- `wp_schema_framework_piece_{type}` - Modify specific schema piece (e.g., `article`, `product`)\n- `wp_schema_framework_piece_id_{id}` - Modify schema piece by ID (e.g., `#organization`)\n\n#### Provider Data Filters\n- `wp_schema_framework_organization_data` - Modify organization schema\n- `wp_schema_framework_organization_type` - Override organization type\n- `wp_schema_framework_website_data` - Modify website schema\n- `wp_schema_framework_website_can_provide` - Control website schema output\n- `wp_schema_framework_article_data` - Modify article schema\n- `wp_schema_framework_webpage_data` - Modify webpage schema\n- `wp_schema_framework_author_data` - Modify author/person schema\n- `wp_schema_framework_product_data` - Modify product schema\n- `wp_schema_framework_event_data` - Modify event schema\n- `wp_schema_framework_archive_data` - Modify archive schema\n- `wp_schema_framework_search_results_data` - Modify search results schema\n- `wp_schema_framework_media_data` - Modify media schema\n- `wp_schema_framework_page_type_data` - Modify specialized page type schema\n\n#### Post Type Filters\n- `wp_schema_framework_post_type_override` - Override schema type for specific posts\n- `wp_schema_framework_post_type_mapping` - Map post types to schema types\n- `wp_schema_framework_post_description` - Provide custom post descriptions\n- `wp_schema_framework_homepage_type` - Override homepage schema type\n- `wp_schema_framework_homepage_data` - Modify homepage schema data\n\n#### Detection Filters\n- `wp_schema_framework_is_product` - Custom product detection\n- `wp_schema_framework_is_event` - Custom event detection\n- `wp_schema_framework_get_product_data` - Provide custom product data\n- `wp_schema_framework_get_event_data` - Provide custom event data\n\n#### Plugin Conflict Filters\n- `wp_schema_framework_woocommerce_schema_active` - Override WooCommerce conflict detection\n- `wp_schema_framework_tribe_events_schema_active` - Override The Events Calendar conflict detection\n\n#### Specialized Filters\n- `wp_schema_framework_faq_items` - Provide FAQ items for FAQPage\n- `wp_schema_framework_collection_items` - Provide collection items\n- `wp_schema_framework_gallery_items` - Provide gallery images\n- `wp_schema_framework_available_types` - Modify available schema types for UI\n\n📚 **[View Complete Hooks Reference](docs/hooks-reference.md)** - Comprehensive documentation with examples and use cases\n\n### Schema Type Registry\n\nAccess available schema types for UI elements like dropdowns in admin settings:\n\n```php\n// Get available schema types\n$types = apply_filters('wp_schema_framework_available_types', []);\n// Returns array with label, value, category, subcategory, and parent fields\n\n// Example: Creating a schema type dropdown in admin\necho '\u003cselect name=\"schema_type\"\u003e';\nforeach ($types as $type) {\n    echo sprintf(\n        '\u003coption value=\"%s\"\u003e%s\u003c/option\u003e',\n        esc_attr($type['value']),\n        esc_html($type['label'])\n    );\n}\necho '\u003c/select\u003e';\n```\n\n#### Categorized Schema Types\n\nThe registry now includes category metadata for better organization:\n\n```php\n// Get types organized by category\n$type_registry = BuiltNorth\\WPSchema\\App::instance()-\u003eget_type_registry();\n$categorized = $type_registry-\u003eget_categorized_types();\n\n// Returns structure like:\n// [\n//     'Organization' =\u003e [\n//         'LocalBusiness' =\u003e [...types],\n//         'FoodEstablishment' =\u003e [...types],\n//         'Store' =\u003e [...types]\n//     ],\n//     'CreativeWork' =\u003e [\n//         'Article' =\u003e [...types],\n//         'WebPage' =\u003e [...types]\n//     ]\n// ]\n```\n\n#### Specialized Type Getters\n\nGet filtered sets of types for specific use cases:\n\n```php\n$type_registry = BuiltNorth\\WPSchema\\App::instance()-\u003eget_type_registry();\n\n// Get only organization/business types (for organization settings)\n$org_types = $type_registry-\u003eget_organization_types();\n\n// Get organization types categorized for dropdowns\n$categorized_org = $type_registry-\u003eget_categorized_organization_types();\n// Returns user-friendly categories like:\n// - General Business\n// - Food \u0026 Dining  \n// - Retail Stores\n// - Home \u0026 Construction\n// - Medical Services\n// etc.\n\n// Get content-focused types (for posts/pages)\n$content_types = $type_registry-\u003eget_content_types();\n// Returns Article, BlogPosting, HowTo, Product, Event, etc.\n```\n\nThe registry provides 250+ comprehensive schema types including:\n\n- **Content Types**: Article, BlogPosting, NewsArticle, HowTo, QAPage, TechArticle, Report\n- **Business \u0026 Services**: LocalBusiness subtypes, home services (Plumber, Electrician, etc.), professional services (Attorney, Dentist, etc.)\n- **Commerce**: Product, Service, Store types, automotive services\n- **Places \u0026 Venues**: Restaurant, Hotel, Museum, Zoo, Park, recreational facilities\n- **Events**: 20+ event subtypes including BusinessEvent, MusicEvent, SportsEvent\n- **Media \u0026 Creative Works**: Various media types, artwork, publications\n- **Digital Products**: SoftwareApplication, MobileApplication, WebApplication\n- **Geographic**: Country, City, Mountain, Beach, tourist destinations\n\nAll types can be extended/consolidated via the `wp_schema_framework_type_registry_types` filter.\n\n#### Extending the Type Registry\n\nAdd custom schema types to the registry:\n\n```php\n// Add custom schema types with categories\nadd_filter('wp_schema_framework_type_registry_types', function($types) {\n    // Add custom types with category metadata\n    $types[] = [\n        'label' =\u003e 'Podcast', \n        'value' =\u003e 'PodcastSeries',\n        'category' =\u003e 'CreativeWork',\n        'subcategory' =\u003e 'PodcastSeries'\n    ];\n    $types[] = [\n        'label' =\u003e 'Coworking Space', \n        'value' =\u003e 'CoworkingSpace',\n        'category' =\u003e 'Organization',\n        'subcategory' =\u003e 'LocalBusiness',\n        'parent' =\u003e 'LocalBusiness'\n    ];\n    $types[] = [\n        'label' =\u003e 'Webinar', \n        'value' =\u003e 'Webinar',\n        'category' =\u003e 'Event',\n        'subcategory' =\u003e 'Event'\n    ];\n    \n    return $types;\n});\n```\n\nReplace with a custom curated list:\n\n```php\n// Replace entire registry with your own curated list\nadd_filter('wp_schema_framework_type_registry_types', function($types) {\n    // Ignore default types and define only what you need\n    return [\n        ['label' =\u003e 'Article', 'value' =\u003e 'Article'],\n        ['label' =\u003e 'Product', 'value' =\u003e 'Product'],\n        ['label' =\u003e 'LocalBusiness', 'value' =\u003e 'LocalBusiness'],\n        ['label' =\u003e 'Event', 'value' =\u003e 'Event'],\n        ['label' =\u003e 'Person', 'value' =\u003e 'Person'],\n        ['label' =\u003e 'Organization', 'value' =\u003e 'Organization'],\n    ];\n});\n```\n\nRemove or modify existing types:\n\n```php\n// Remove specific schema types from existing list\nadd_filter('wp_schema_framework_type_registry_types', function($types) {\n    // Remove all Action types (not typically used as main entity)\n    $types = array_filter($types, function($type) {\n        return !str_contains($type['value'], 'Action');\n    });\n    \n    // Remove specific types\n    $remove_types = ['Cemetery', 'Canal', 'Mountain'];\n    $types = array_filter($types, function($type) use ($remove_types) {\n        return !in_array($type['value'], $remove_types);\n    });\n    \n    return $types;\n});\n```\n\nOrganize types for better UX using built-in categories:\n\n```php\n// Create optgroups using the built-in category metadata\n$type_registry = BuiltNorth\\WPSchema\\App::instance()-\u003eget_type_registry();\n$categorized = $type_registry-\u003eget_categorized_organization_types();\n\necho '\u003cselect name=\"organization_type\"\u003e';\nforeach ($categorized as $category =\u003e $types) {\n    echo '\u003coptgroup label=\"' . esc_attr($category) . '\"\u003e';\n    foreach ($types as $type) {\n        echo sprintf(\n            '\u003coption value=\"%s\"\u003e%s\u003c/option\u003e',\n            esc_attr($type['value']),\n            esc_html($type['label'])\n        );\n    }\n    echo '\u003c/optgroup\u003e';\n}\necho '\u003c/select\u003e';\n```\n\n## Requirements\n\n- PHP 8.1+\n- WordPress 6.0+\n\n## API Reference\n\n### App Class\n\nThe main application class provides static methods for framework interaction:\n\n```php\n// Initialize the framework\nBuiltNorth\\WPSchema\\App::initialize();\n\n// Register a provider programmatically\nBuiltNorth\\WPSchema\\App::register_provider('my_provider', 'MyPlugin\\MyProvider');\n\n// Get the singleton instance\n$app = BuiltNorth\\WPSchema\\App::instance();\n\n// Check if initialized\nif ($app-\u003eis_initialized()) {\n    // Access services\n    $registry = $app-\u003eget_registry();\n    $graph_builder = $app-\u003eget_graph_builder();\n    $type_registry = $app-\u003eget_type_registry();\n}\n```\n\n### SchemaGraph Class\n\nManages the schema graph with piece management:\n\n```php\nuse BuiltNorth\\WPSchema\\Graph\\SchemaGraph;\nuse BuiltNorth\\WPSchema\\Graph\\SchemaPiece;\n\n$graph = new SchemaGraph();\n\n// Add pieces\n$piece = new SchemaPiece('my-id', 'Article', ['headline' =\u003e 'Title']);\n$graph-\u003eadd_piece($piece);\n\n// Query pieces\n$article = $graph-\u003eget_piece('my-id');\n$all_articles = $graph-\u003eget_pieces_by_type('Article');\n\n// Convert to output\n$array = $graph-\u003eto_array();\n$json = $graph-\u003eto_json();\n```\n\n### SchemaPiece Class\n\nRepresents individual schema pieces:\n\n```php\nuse BuiltNorth\\WPSchema\\Graph\\SchemaPiece;\n\n// Create a piece\n$piece = new SchemaPiece('article-1', 'Article');\n\n// Set properties\n$piece-\u003eset('headline', 'My Article')\n      -\u003eset('datePublished', '2024-01-01')\n      -\u003eadd_reference('author', 'person-1');\n\n// Access properties\n$headline = $piece-\u003eget('headline');\n$has_author = $piece-\u003ehas('author');\n\n// Convert to array\n$data = $piece-\u003eto_array();\n```\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for details on how to contribute to this project.\n\n## License\n\nThis package is licensed under the GPL version 2 or later. See [LICENSE.md](LICENSE.md) for details.\n\n## Support\n\nFor support and questions, please open an issue on GitHub.\n\n## Disclaimer\n\nTHIS SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nThe schema markup generated by this package is not guaranteed to result in rich snippets or enhanced search results. Search engines determine rich snippet eligibility based on many factors including content quality, site authority, and their own algorithms. Always validate your schema output using official testing tools and follow search engine guidelines.\n\nThis package has not been fully tested across all WordPress configurations and use cases. The generated schema may not be accurate or complete for all scenarios. Users are responsible for validating and testing the schema output for their specific implementations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuiltnorth%2Fwp-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbuiltnorth%2Fwp-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbuiltnorth%2Fwp-schema/lists"}