Developer Portal
Plugin API Reference

Custom Post Types (PostTypeRegistry)

Register custom content types beyond the default "Post" and "Page". Each custom post type gets its own admin UI, listing, and optional archive pages.

📍 Source: App\CMS\PostTypes\PostTypeRegistry

Registering a Post Type

Call PostTypeRegistry::register() inside your plugin's boot() method:

use App\CMS\PostTypes\PostTypeRegistry;

public function boot(): void
{
    PostTypeRegistry::register('announcement', [
        'label'        => 'Announcements',
        'singular'     => 'Announcement',
        'icon'         => '📢',
        'supports'     => ['title', 'editor', 'thumbnail', 'excerpt'],
        'has_archive'  => true,
        'public'       => true,
        'menu_position'=> 5,
    ]);
}

Method Signature

PostTypeRegistry::register(string $slug, array $options): void

Options Reference

KeyTypeDefaultDescription
labelstringslug (ucfirst)Plural display name (e.g., "Announcements")
singularstringlabelSingular display name (e.g., "Announcement")
iconstring'📄'Emoji or icon class for admin menus
supportsarray['title','editor']Features: title, editor, thumbnail, excerpt, comments, revisions
has_archiveboolfalseWhether this post type has an archive listing page
publicbooltrueWhether posts of this type are publicly viewable
menu_positionint25Position in admin sidebar (lower = higher)

Querying Custom Post Types

Use the standard Post model scoped by type:

use App\CMS\Models\Post;

// Get all published announcements
$announcements = Post::where('post_type', 'announcement')
    ->where('status', 'published')
    ->orderBy('created_at', 'desc')
    ->get();

// Get a single announcement by slug
$post = Post::where('post_type', 'announcement')
    ->where('slug', $slug)
    ->firstOrFail();

Real Example: postify-announcements

The postify-announcements plugin registers the announcement post type in its boot() method:

// From content/plugins/postify-announcements/PostifyAnnouncements.php
public function boot(): void
{
    PostTypeRegistry::register('announcement', [
        'label'       => 'Announcements',
        'singular'    => 'Announcement',
        'icon'        => '📢',
        'supports'    => ['title', 'editor', 'thumbnail', 'excerpt'],
        'has_archive' => true,
        'public'      => true,
    ]);
}

💡 Tip: Custom Post Types automatically get their own admin listing page and create/edit forms. No additional routing is needed.

Last verified against AIPostify core. © 2026 AIPostify Marketplace Developer Documentation.