Create your first NetSeller plugin
A plugin is a CFML package that registers functionality with NetSeller. You need basic CFML/CFC, HTML and SQL knowledge, a development installation, and permission to manage plugins and roles.
Start with the existing Demo Admin Integration plugin. It adds a protected admin page, a navigation entry, an integration entry and a plugin-owned database table.
1. Install the example
Section titled “1. Install the example”If your installation already lists demo.admin_integration under Settings → Plugins, enable that existing copy. Do not upload another package with the same ID over a locally managed copy.
Otherwise upload the ZIP under Settings → Plugins. A successful upload also enables it. Activation creates its table and registers its permission. Follow Installation and updates if activation reports an error.
The Super Admin role receives the plugin permission automatically. For other roles, assign View demo plugin in the role editor. Open Demo plugin in the navigation. The page displays “The demo plugin route is active.” The integrations area also contains its status entry.
2. Understand the package
Section titled “2. Understand the package”demo.admin_integration/ netseller-plugin.json db/migrations/V1__create_demo_tables.sql src/ providers/plugin_provider.cfc controllers/demo_controller.cfc views/demo/index.cfm| File | Responsibility |
|---|---|
netseller-plugin.json |
Identifies the package and declares its provider. |
plugin_provider.cfc |
Registers the route, menu entry, permission and integration status. |
demo_controller.cfc |
Returns the admin layout, plugin view and page metadata. |
index.cfm |
Renders the page. |
V1__create_demo_tables.sql |
Creates the plugin settings table and an installation marker. |
The table is not used by the static page. Forms and saving data adds a complete editable setting to it.
3. Follow a request
Section titled “3. Follow a request”- The provider registers a named GET route and its permission middleware.
- The navigation entry links to that route name.
- NetSeller checks authentication and permission, then calls the controller’s
index()method. - The returned struct supplies
routeConfigto the view and selects the admin layout.
The manifest is:
{ "id": "demo.admin_integration", "version": "0.1.0", "name": "Demo Admin Integration", "description": "Demo admin plugin for the local plugin system.", "providers": ["providers.plugin_provider"]}The provider’s route points to netseller_plugin_demo_admin_integration.controllers.demo_controller. NetSeller maps that component prefix to this plugin’s src/ directory; you do not configure a separate CFML mapping.
The controller returns:
component output="false" { public struct function index() { return { 'layout' = "../application/admin/views/layouts/app.cfm", 'view' = "/netseller_plugin_demo_admin_integration/views/demo/index.cfm", 'pageTitle' = "Demo plugin", 'pagePretitle' = request.t("admin.plugins.title", "Plugins"), 'pageHeading' = "Demo plugin", 'pageDescription' = "Demo admin route provided by a local plugin.", 'activeNav' = "settings", 'statusCode' = 200 }; }}Use the shown layout value for the shared admin shell. The view path uses the plugin mapping. Additional returned fields become routeConfig.<field> in your view. A controller action returns a struct; it does not write the complete document directly.
4. Make your own plugin
Section titled “4. Make your own plugin”Copy the extracted package to example.hello/, then change these identifiers throughout your copy:
| Demo value | Your value |
|---|---|
Folder and manifest ID demo.admin_integration |
example.hello |
Component/view mapping netseller_plugin_demo_admin_integration |
netseller_plugin_example_hello |
Route and permission prefix plugin.demo.admin_integration. |
plugin.example.hello. |
Route path prefix /plugins/demo.admin_integration |
/plugins/example.hello |
Table/index prefix plg_demo_admin_integration_ |
plg_example_hello_ |
Navigation ID plugin_demo_admin_integration |
plugin_example_hello |
Also update the manifest name, description and version, the integration’s id and ownerKey, and its statusResolverKey comparison. The demo uses fallback labels; add your own translation catalogs for localized text.
Rename identifiers before your new plugin’s first installation. Do not edit an already-applied migration in an installed plugin. See Manifest and package for naming rules.
Next steps
Section titled “Next steps”- Forms and saving data adds a protected POST action.
- Contribution contracts explains provider fields.
- Database and migrations covers persistent data and shop scope.
- Public runtime services covers access to supported shared functionality.