Documentation → Developer Resources

Extending the Plugin

Add custom content types and modify sitemap behavior.

Adding Custom Post Types

The easiest way to add custom post types is using the filter:

/**
 * Add portfolio and testimonial post types to sitemap
 */
add_filter('developer_sitemap_post_types', function($types) {
    $types[] = 'portfolio';
    $types[] = 'testimonial';
    return $types;
});

/**
 * Customize priority for these post types
 */
add_filter('developer_sitemap_url_entry', function($entry, $post_id) {
    $post_type = get_post_type($post_id);
    
    if ($post_type === 'portfolio') {
        $entry['priority'] = 0.8;
        $entry['changefreq'] = 'monthly';
    }
    
    if ($post_type === 'testimonial') {
        $entry['priority'] = 0.4;
        $entry['changefreq'] = 'yearly';
    }
    
    return $entry;
}, 10, 2);

Creating a Custom URL Provider

For complete control, create a custom URL provider class:

<?php
namespace MyPlugin\Sitemap;

use DeveloperSitemap\Domain\Interface\UrlProviderInterface;
use DeveloperSitemap\Domain\Entity\SitemapUrl;

class EventUrlProvider implements UrlProviderInterface
{
    /**
     * Unique identifier for this provider
     */
    public function getType(): string
    {
        return 'event';
    }

    /**
     * Get all URLs for this content type
     */
    public function getUrls(array $config): array
    {
        $urls = [];
        
        // Query your events
        $events = get_posts([
            'post_type'      => 'event',
            'post_status'    => 'publish',
            'posts_per_page' => -1,
            'meta_query'     => [
                [
                    'key'     => 'event_date',
                    'value'   => date('Y-m-d'),
                    'compare' => '>=',
                    'type'    => 'DATE'
                ]
            ]
        ]);
        
        foreach ($events as $event) {
            // Skip excluded events
            if (in_array($event->ID, $config['excluded_posts'] ?? [])) {
                continue;
            }
            
            $urls[] = new SitemapUrl(
                get_permalink($event),
                get_post_modified_time('c', true, $event),
                'weekly',
                $config['event_priority'] ?? 0.7
            );
        }
        
        return $urls;
    }

    /**
     * Get URL count (for dashboard display)
     */
    public function getCount(array $config): int
    {
        return count($this->getUrls($config));
    }
}

Register the Provider

add_action('developer_sitemap_init', function($kernel) {
    $kernel->registerUrlProvider(
        new \MyPlugin\Sitemap\EventUrlProvider()
    );
});

Modifying URLs

Exclude by Custom Field

/**
 * Exclude posts with _sitemap_exclude meta
 */
add_filter('developer_sitemap_exclude_post', function($exclude, $post_id) {
    if (get_post_meta($post_id, '_sitemap_exclude', true)) {
        return true;
    }
    return $exclude;
}, 10, 2);

Dynamic Priority Based on Content

/**
 * Set priority based on post age and engagement
 */
add_filter('developer_sitemap_url_entry', function($entry, $post_id) {
    $post = get_post($post_id);
    $days_old = (time() - strtotime($post->post_date)) / DAY_IN_SECONDS;
    
    // Newer posts get higher priority
    if ($days_old < 7) {
        $entry['priority'] = 0.9;
        $entry['changefreq'] = 'daily';
    } elseif ($days_old < 30) {
        $entry['priority'] = 0.7;
        $entry['changefreq'] = 'weekly';
    } else {
        $entry['priority'] = 0.5;
        $entry['changefreq'] = 'monthly';
    }
    
    return $entry;
}, 10, 2);

Add External URLs

/**
 * Add external landing pages to sitemap
 */
add_filter('developer_sitemap_urls', function($urls, $type) {
    if ($type === 'page') {
        // Add URLs from external source
        $external = [
            'https://example.com/landing-1/',
            'https://example.com/landing-2/',
        ];
        
        foreach ($external as $loc) {
            $urls[] = new \DeveloperSitemap\Domain\Entity\SitemapUrl(
                $loc,
                date('c'),
                'weekly',
                0.8
            );
        }
    }
    return $urls;
}, 10, 2);

Creating an Add-on Plugin

For reusable extensions, create a separate plugin:

<?php
/**
 * Plugin Name: Developer Sitemap - Events Extension
 * Description: Adds event support to Developer Sitemap
 * Version: 1.0.0
 * Requires Plugins: developer-sitemap
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
    exit;
}

// Check if Developer Sitemap is active
add_action('plugins_loaded', function() {
    if (!class_exists('DeveloperSitemap\Application\Kernel')) {
        add_action('admin_notices', function() {
            echo '<div class="notice notice-error">';
            echo '<p>Developer Sitemap - Events Extension requires Developer Sitemap.</p>';
            echo '</div>';
        });
        return;
    }
    
    // Load extension
    require_once __DIR__ . '/includes/class-event-url-provider.php';
    
    add_action('developer_sitemap_init', function($kernel) {
        $kernel->registerUrlProvider(
            new \DevSitemapEvents\EventUrlProvider()
        );
    });
});

Best Practice: Use the Requires Plugins header (WordPress 6.5+) to ensure Developer Sitemap is installed.