Developer Guide

Developer Guide

Extending with Custom Discovery Endpoints

Create a new handler by extending BaseHandler:

use Cybermaps\Discovery\BaseHandler;
use Cybermaps\Core\URLManager;
use Cybermaps\Discovery\Integrity;

class MyCustomHandler extends BaseHandler {
    protected function path(): string {
        return '/custom-endpoint.json';
    }

    protected function contentType(): string {
        return 'application/json; charset=utf-8';
    }

    protected function generate(): string {
        $data = [
            'message' => 'Hello from a custom discovery endpoint',
            'timestamp' => gmdate('c'),
        ];
        return wp_json_encode($data, JSON_PRETTY_PRINT);
    }
}

Register it in your theme or plugin:

add_action('init', function() {
    $manager = new \Cybermaps\Discovery\Manager();
    $manager->register(new MyCustomHandler());
});

Available Filter Hooks

cybermaps_schema_type_tree Modify the hierarchy of schema.org types available in the Identity Hub:

add_filter('cybermaps_schema_type_tree', function(array $tree): array {
    $tree['Custom Category'] = [
        ['type' => 'MyCustomType', 'label' => 'My Custom Type'],
    ];
    return $tree;
});

cybermaps_ai_manifest_capabilities Add capabilities to the ADP manifest:

add_filter('cybermaps_ai_manifest_capabilities', function(array $capabilities): array {
    $capabilities[] = 'custom_integration';
    return $capabilities;
});

cybermaps_llms_optional_sections Add links to the Optional section of llms.txt:

add_filter('cybermaps_llms_optional_sections', function(array $sections): array {
    $sections[] = ['label' => 'Custom Docs', 'url' => '/custom-docs.md'];
    return $sections;
});

cybermaps_content_signals Add custom Content-Signal directives to robots.txt:

add_filter('cybermaps_content_signals', function(array $signals): array {
    $signals[] = 'Custom-Signal: my-value';
    return $signals;
});

Registering Custom Sitemap Providers

use Cybermaps\Sitemap\Orchestrator;
use Cybermaps\Sitemap\ProviderInterface;
use Cybermaps\Sitemap\SitemapItem;

class CustomProvider implements ProviderInterface {
    public function get_urls(int $page): array {
        return [
            new SitemapItem(
                loc: 'https://example.com/custom-url',
                lastmod: '2026-05-26',
                changefreq: 'weekly',
                priority: 0.7,
            ),
        ];
    }

    public function get_count(): int {
        return 1;
    }

    public function get_lastmod(): string {
        return '2026-05-26';
    }
}

add_action('init', function() {
    Orchestrator::register_provider('custom', new CustomProvider());
});

Overriding Bot Definitions

The CrawlerRegistry::get_all() method returns an array of BotMetadata objects. You can filter this array to add, remove, or modify bot definitions before they’re used for identification and robots.txt generation.

PSR-4 Autoloading

The plugin uses Composer PSR-4 autoloading:

{
  "autoload": {
    "psr-4": {
      "Cybermaps\\": "src/"
    }
  }
}

If Composer’s autoloader is not available (e.g., the plugin was installed without running composer install), the bundled Autoloader.php provides a manual fallback that maps the Cybermaps namespace to the src/ directory.