Skip to content

Building Extensions (Developers)

DMS is extended via separate plugins that hook into dms_init_extension. An extension must be independently activatable, must never edit encoded core files, and should keep its settings under the Dealer.ms menu (project standard).


Entry Point

dms_init_extension fires on plugins_loaded, after core DMS is available. Use it as your boot point.

<?php
/**
 * Plugin Name: DMS Custom Export Feed
 * Description: Adds a custom export feed to DMS.
 * Version:     1.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

add_action( 'dms_init_extension', function () {
    DMS_Custom_Export_Feed::init();
} );

The hook only fires when DMS is active, so no "is DMS active?" guard is needed - an extension activated without DMS simply does nothing, satisfying the independent-activation rule.


Registrar Helpers

Use these documented helpers instead of touching internal classes. Each takes a config array (CMB2-style) and wires the object into DMS.

Helper Signature Registers
dms_register_metabox() array $metabox_data A CMB2 metabox on a listing/page
dms_register_options_page() array $options_data A settings page under Dealer.ms
dms_register_permission_group() string $key, string $label A permissions group
dms_register_permission() array $data A single role permission
dms_add_type() array $type_dataint\|bool A new inventory type
dms_add_type_tab() array $tab_data A settings tab on a type
dms_add_type_badge() array $badge_dataint A badge on a type
dms_add_category() array $category_dataint\|bool A listing category (attribute)
dms_add_category_term() array $term_dataint\|bool A term within a category
dms_add_listing_filter() Category $category, Term $term An SRP filter (runtime)
dms_add_dashboard_widget() string $widget_id, array $widget_data An admin dashboard widget

Register a permission

Register a group first (optional), then permissions that reference it by key. Permissions must include key and label.

add_action( 'dms_init', function () {
    dms_register_permission_group( 'export_feed', __( 'Custom Export Feed', 'dms-custom-export-feed' ) );

    dms_register_permission( [
        'key'         => 'manage_export_feed',
        'label'       => __( 'Manage Export Feed', 'dms-custom-export-feed' ),
        'description' => __( 'Configure and run the custom export feed', 'dms-custom-export-feed' ),
        'group'       => 'export_feed',
    ] );
}, 25 ); // after core permissions (registered at priority 20)

Check it later with dms_user_can( 'manage_export_feed' ).

Register an options page

Options pages take a data block (identity/menu) and a tabs block (fields). Set parent_slug to dms to sit under the Dealer.ms menu.

$page = [
    'data' => [
        'id'          => 'export_feed_options',
        'title'       => __( 'Custom Export Feed', 'dms-custom-export-feed' ),
        'option_key'  => 'export_feed_settings',
        'parent_slug' => 'dms',
        'position'    => 40,
    ],
    'tabs' => [
        'layout' => 'horizontal',
        'tabs'   => [
            [
                'id'     => 'general',
                'title'  => __( 'General', 'dms-custom-export-feed' ),
                'fields' => [
                    'export_feed_api_key' => [
                        'id'   => 'export_feed_api_key',
                        'type' => 'text',
                        'name' => __( 'API Key', 'dms-custom-export-feed' ),
                    ],
                ],
            ],
        ],
    ],
];

dms_register_options_page( $page );

Read the saved values back with get_option( 'export_feed_settings' ) (the option_key).

Add a metabox / custom listing field

dms_register_metabox() takes a CMB2-style array (id, title, object_types, context, fields). Read the field back off a listing with $listing->get_meta( 'key' ).

dms_register_metabox( [
    'id'           => 'export_feed_extra',
    'title'        => __( 'Export Feed Data', 'dms-custom-export-feed' ),
    'object_types' => dms_get_types( true ), // all DMS post-type slugs
    'context'      => 'side',
    'fields'       => [
        [
            'id'   => 'export_feed_ref',
            'name' => __( 'Export Feed Reference', 'dms-custom-export-feed' ),
            'type' => 'text',
        ],
    ],
] );

// later:
$ref = dms_get_listing( $id )->get_meta( 'export_feed_ref' );

Settings Placement

Keep all extension settings under the Dealer.ms menu hierarchy (parent_slug => 'dms' on options pages). Don't scatter top-level admin menus - it breaks the unified UX and the permission model.


See also