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_data → int\|bool |
A new inventory type |
dms_add_type_tab() |
array $tab_data |
A settings tab on a type |
dms_add_type_badge() |
array $badge_data → int |
A badge on a type |
dms_add_category() |
array $category_data → int\|bool |
A listing category (attribute) |
dms_add_category_term() |
array $term_data → int\|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¶
- Getting Started - boot phases and the accessor pattern.
- Actions Reference -
dms_init_extension. - Cookbook - worked recipes.