Search by

dorsetdigital / silverstripe-schema-manager

DorsetDigital

Structured data schema registry and helpers for Silverstripe CMS 6.

Package info

github.com/DorsetDigital/silverstripe-schema-manager

Type:silverstripe-vendormodule

pkg:composer/dorsetdigital/silverstripe-schema-manager

Statistics

Installs: 17

Dependents: 0

Suggesters: 1

Stars: 2

Open Issues: 0


README

Structured-data management for Silverstripe CMS 6.

Schema Manager combines CMS-managed site information with automatic page schema and a request-scoped registry. Schema.org entities are emitted as a single linked JSON-LD @graph in the page <head>.

Requirements

  • PHP 8.3+
  • Silverstripe CMS 6

Installation

composer require dorsetdigital/silverstripe-schema-manager
vendor/bin/sake dev/build flush=1

What is automatic?

By default Schema Manager adds site, page and breadcrumb schema to normal ContentController page requests:

Organization
    ↑ publisher
WebSite
    ↑ isPartOf
WebPage

BreadcrumbList

Stable entity IDs are based on the canonical site/page URLs:

https://example.com/#organisation
https://example.com/#website
https://example.com/about/#webpage
https://example.com/about/#breadcrumb

The JSON-LD is inserted automatically with Silverstripe Requirements. No template change is required.

Automatic WebPage schema

Every normal SiteTree page receives a WebPage entity containing its URL, title, description where available, created/modified dates and a reference to the site's WebSite entity. No page extension is required.

Configuration

Each automatic layer can be disabled independently:

DorsetDigital\SchemaManager\Service\SchemaManager:
  automatic_organisation_schema: true
  automatic_website_schema: true
  automatic_webpage_schema: true
  automatic_breadcrumb_schema: true

Supported schema types

Detailed examples and configuration are kept in separate documentation:

  • Site schemaOrganization and WebSite
  • Breadcrumbs — automatic and manual BreadcrumbList
  • FAQPage — questions and accepted answers
  • ImageGallery — image collections and ImageObject metadata
  • Product — products, offers, stock and brands
  • Service — services, providers and pricing
  • JobPosting — vacancies, locations and salaries
  • BlogPosting — optional Silverstripe Blog integration

Page-level typed builders link to their WebPage with isPartOf by default. When an entity is the primary subject of a dedicated page, setMainEntityOfPage($pageURL) promotes that relationship explicitly.

All typed builders inherit Schema::update(), allowing projects to add less common Schema.org properties without the module needing to model every possible field.

Adding schema manually

Raw entities can still be registered directly:

use DorsetDigital\SchemaManager\Control\SchemaRegistry;

SchemaRegistry::addEntity(
    'https://example.com/#service',
    [
        '@type' => 'Service',
        '@id' => 'https://example.com/#service',
        'name' => 'Example service',
    ]
);

If an entity is registered again using the same @id, its data is recursively merged with the existing entity.

Typed schema objects can also be registered:

SchemaRegistry::add($schema);

where $schema extends DorsetDigital\SchemaManager\Model\Schema\Schema.

Extension point

The registry API can be called directly from application code; an extension hook is not required. For reusable integrations that need to contribute schema automatically to arbitrary pages, Schema Manager also calls this Silverstripe extension hook before page entities are registered:

updateSchemaManagerEntities(array &$entities)

Extensions can therefore append, remove or modify typed schema objects without replacing the registry or controller integration. This is primarily an integration mechanism rather than a requirement for ordinary project code.

For example:

use SilverStripe\Core\Extension;

class MyPageSchemaExtension extends Extension
{
    public function updateSchemaManagerEntities(array &$entities): void
    {
        // Add another Schema object, or update an existing one.
    }
}

The same hook is called on SiteConfig for site-wide entities.

The bundled Blog integration uses this mechanism, so it also provides a reference implementation for future module integrations.

Registry API

SchemaRegistry::add(Schema $schema)

Registers a typed schema object. It can be called directly from controllers or other application code. Relationships are resolved when the graph is rendered, so schemas registered independently still participate in automatic WebPage.mainEntity and breadcrumb relationship resolution.

SchemaRegistry::addEntity(string $id, array $data)

Registers a raw Schema.org entity. Existing data under the same ID is recursively merged, including entities previously registered as typed schemas with add(). This allows project code to augment a typed entity without replacing it.

SchemaRegistry::addFAQ(string $question, string $answer, ?string $pageURL = null)

Deprecated compatibility helper for adding FAQ questions. New code should use FAQPageSchema and SchemaRegistry::add().

SchemaRegistry::addBreadCrumbs(SiteTree $page, int $maxDepth = 20, bool|string $stopAtPageType = false, bool $showHidden = false)

Adds a BreadcrumbList using Silverstripe's standard breadcrumb hierarchy. The method remains available when automatic breadcrumb schema is disabled.

SchemaRegistry::getGraph(): array

Returns all registered entities.

SchemaRegistry::getSchema(): array

Returns the complete structure containing @context and @graph.

SchemaRegistry::getJSON(): string

Returns JSON suitable for an application/ld+json script element.

SchemaRegistry::flush(): void

Clears the request registry.

Documentation

The docs/ directory contains the detailed guides for each supported schema type. The README is intentionally focused on installation, automatic behaviour, configuration and the common registry API.

Project structure

_config/
  schema-manager.yml
src/
  Control/
    SchemaRegistry.php
  Extension/
    BlogPostSchemaExtension.php
    SchemaControllerExtension.php
    SiteConfigSchemaExtension.php
  Model/
    Schema/
      BlogPostingSchema.php
      FAQPageSchema.php
      ImageGallerySchema.php
      JobPostingSchema.php
      OrganisationSchema.php
      ProductSchema.php
      Schema.php
      ServiceSchema.php
      WebPageSchema.php
      WebsiteSchema.php
  Service/
    SchemaManager.php

The module is deliberately split into small responsibilities:

  • schema classes build individual Schema.org entities
  • the registry collects, merges and renders the graph
  • Silverstripe extensions decide which entities should be registered for a request

This keeps the public API small while leaving room for additional schema types and project-specific extensions.

License

BSD 3-Clause License.