Demos and the importer
How a demo is stored
One file per demo lives in data/demos/<slug>.php. Each returns a PHP array:
phpreturn array(
'title' => 'Lantern Quarter',
'category' => 'Editorial / Travel',
'summary' => 'A long-form editorial layout with chapter index masthead.',
'tags' => array( 'editorial', 'long-form' ),
'kit' => 'atelier-mono',
'plugin_upsells' => array( 'oforms' ),
'masthead' => array( 'type' => 'minimal', 'title' => 'Lantern Quarter' ),
'sections' => array(
array( 'type' => 'editorial_split_hero_v3', /* fields... */ ),
// ...
),
);Importer API
Orv_D3_Importer exposes three AJAX endpoints and three matching PHP entry points:
wp_ajax_orvd3_import_demo -> ajax_import_demo()
wp_ajax_orvd3_import_all -> ajax_import_all()
wp_ajax_orvd3_remove_imported -> ajax_remove_imported()php// PHP entry points
Orv_D3_Importer::import( string $slug, bool $force_new = false ): array;
Orv_D3_Importer::remove_imported( string $slug, bool $trash = true ): array;
Orv_D3_Importer::imported_post_id_for( string $slug ): ?int;Idempotency
Every imported post carries:
_orvd3_demo_slug- the demo's slug_orvd3_demo_version- the demo's version at import time
Re-importing reuses the post unless force_new = true, in which case the importer inserts a fresh orv_page and leaves the old one alone.
Authoring a new demo
Drop a file into data/demos/<your-slug>.php returning the array shape above. Refresh Demos v3, hit Import on the new card. Done. The registry (Orv_D3_Registry) memoizes demo lookups, so a plugin upgrade automatically picks up new files.

