Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Structured Data Laravel Package

brick/structured-data

Generate, parse, and validate Schema.org structured data in PHP. brick/structured-data helps you build JSON-LD and other formats with a typed API, ensuring correct properties and values for SEO-rich pages and interoperable metadata.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require brick/structured-data:^0.2.0
    
    • Note: Requires PHP 8.1+ (breaking change in v0.2.0).
    • Add to composer.json if using a monorepo or custom package management.
  2. First Use Case: Reading Structured Data

    use Brick\StructuredData\Reader\Reader;
    use Brick\StructuredData\Reader\ReaderFactory;
    
    $reader = ReaderFactory::create();
    $data = $reader->readFromHtml('<div itemscope itemtype="https://schema.org/Person">...</div>');
    
  3. Where to Look First

    • Documentation (if available)
    • src/Reader/ for core parsing logic (all classes are now final in v0.2.0)
    • tests/ for real-world examples (e.g., JSON-LD, Microdata, RDFa)

Implementation Patterns

1. Parsing HTML for Structured Data

$html = file_get_contents('https://example.com');
$reader = ReaderFactory::create();
$structuredData = $reader->readFromHtml($html);

// Extract specific data (e.g., Schema.org Person)
$people = $structuredData->getItemsOfType('Person');
foreach ($people as $person) {
    echo $person->getPropertyValue('name');
}

2. Handling JSON-LD Directly

$jsonLd = json_decode(file_get_contents('data.json'), true);
$reader = ReaderFactory::create();
$structuredData = $reader->readFromJsonLd($jsonLd);

// Validate or transform data
$valid = $structuredData->validate();

3. Integration with Laravel

  • Service Provider Binding
    // app/Providers/AppServiceProvider.php
    public function register()
    {
        $this->app->bind(Reader::class, function () {
            return ReaderFactory::create();
        });
    }
    
  • Middleware for Scraping
    // app/Http/Middleware/ParseStructuredData.php
    public function handle($request, Closure $next)
    {
        $reader = app(Reader::class);
        $data = $reader->readFromHtml($request->getContent());
        $request->merge(['structured_data' => $data]);
        return $next($request);
    }
    

4. Batch Processing

$urls = ['https://example.com/page1', 'https://example.com/page2'];
$reader = ReaderFactory::create();

foreach ($urls as $url) {
    $html = file_get_contents($url);
    $data = $reader->readFromHtml($html);
    // Store in DB or process
}

5. Custom Property Mappings

$item = $structuredData->getItemsOfType('Product')->first();
$price = $item->getPropertyValue('offers', 'price'); // Nested properties

6. URI Handling (New in v0.2.0)

// Compatible with `sabre/uri` v3 (updated dependency)
$reader = ReaderFactory::create(['uri_resolver' => new \Sabre\Uri\Uri()]);

Gotchas and Tips

Pitfalls

  1. PHP 8.1 Requirement (Breaking Change)

    • Ensure your Laravel project uses PHP 8.1+:
      php -v  # Verify version
      
    • Update composer.json constraints if needed:
      "require": {
          "php": "^8.1"
      }
      
  2. Final Classes (Breaking Change)

    • All classes in Brick\StructuredData are now final. No inheritance possible.
    • Use composition or decorators for extensions (see Extension Points below).
  3. HTML Parsing Quirks

    • Malformed HTML may break parsing. Use DOMDocument to clean input first:
      $dom = new DOMDocument();
      @$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
      $cleanHtml = $dom->saveHTML();
      $reader->readFromHtml($cleanHtml);
      
  4. Namespace Conflicts

    • Schema.org types like Person vs. custom types (e.g., App\\Person). Prefix or validate types explicitly:
      if ($item->getType() !== 'https://schema.org/Person') {
          continue;
      }
      
  5. Performance with Large JSON-LD

    • Stream JSON-LD files for memory efficiency:
      $reader->readFromJsonLdStream(fopen('large.jsonld', 'r'));
      

Debugging Tips

  • Enable Verbose Output
    $reader = ReaderFactory::create(['verbose' => true]);
    
  • Inspect Raw Data
    $rawData = $reader->readFromHtml($html)->getRawData();
    dd($rawData); // Debug with Laravel's `dd()`
    

Extension Points

  1. Decorators for Extensibility Since classes are final, use decorators to wrap functionality:

    class StructuredDataDecorator {
        private $reader;
    
        public function __construct(Reader $reader) {
            $this->reader = $reader;
        }
    
        public function readWithCustomLogic(string $html): StructuredData {
            $data = $this->reader->readFromHtml($html);
            // Add custom logic here
            return $data;
        }
    }
    
  2. Plugin System via Callbacks Use listener-like patterns (if supported) or attach callbacks:

    $reader = ReaderFactory::create();
    $reader->addPostProcessCallback(function (StructuredData $data) {
        // Post-process all items
        foreach ($data->getItems() as $item) {
            // Custom logic
        }
    });
    
  3. Laravel Service Extensions Publish config or extend the reader via boot() in a service provider:

    public function boot()
    {
        $reader = app(Reader::class);
        $reader->setDefaultNamespace('https://myapp.org/');
    }
    

Configuration Quirks

  • Default Namespaces Configure globally in ReaderFactory:

    $reader = ReaderFactory::create([
        'default_namespaces' => [
            'schema' => 'https://schema.org/',
            'myapp'  => 'https://myapp.org/',
        ]
    ]);
    
  • Case Sensitivity Property names are case-sensitive. Normalize inputs:

    $normalized = strtolower($propertyName);
    
  • URI Resolver (New in v0.2.0) Explicitly set a sabre/uri v3-compatible resolver:

    $reader = ReaderFactory::create([
        'uri_resolver' => new \Sabre\Uri\Uri(),
    ]);
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor