Feature modules bundle a database table, its model, controller, and templates. You can scaffold them automatically from Developer Tools or build them manually by copying demo assets.
- Add the table to your schema: mirror the demo tables in
App_Data/sql/demo.sql, then append theCREATE TABLEtoApp_Data/sql/database.sqland create a dated script underApp_Data/sql/updates/for deployments. - Open Developer Tools at
/Dev/Manageand use the Create Model form. Pick your table and optional model name; the action reads the schema and generates the model file for you. - Create the controller from the same screen. Select the model, provide a target URL/title, and choose controller type (dynamic, Vue, lookup, or API). The generator copies demo templates, rewrites URLs/titles, configures
config.json, writes the controller class, and adds a menu item. - Restart the project or apply hot reload, then navigate to the new controller URL.
- Review and tweak
config.jsonin the generated template folder (see dynamic controller config). - Prune unused partials/includes in the generated template folder so only the needed pages and widgets remain.
CreateModelActionconverts the selected table into an entity description (DevEntityBuilder.table2entity) and passes it toDevCodeGen.createModel, which clones demo model templates and adjusts names/fields based on schema metadata.CreateControllerActionbuilds a temporary entity with the chosen model and controller options, loadsdev/db.json, and callsDevCodeGen.createController. The generator copies the demo controller/templates (dynamic or Vue), rewrites URLs/titles, regeneratesconfig.json, writes the controller class, and appends/updatesmenu_items.
If you need full control, replicate what the generators do:
-
Database table
- Define the table in
App_Data/sql/database.sqland add a migration underApp_Data/sql/updates/for environments that need incremental updates. - Keep naming consistent: snake_case plural table names (e.g.,
orders), include system columns (status,add_time,add_users_id,upd_time,upd_users_id) for built-in behaviors.
- Define the table in
-
Model class
- Copy
App_Code/models/DemoDicts.cs(orDemosDemoDicts.csfor junction tables) to a new file named after your model. - Update
table_name, optional field mappings (field_id,field_iname,field_status, etc.), and row properties to match your columns. - Add helper methods (select options, validations, derived calculations) similar to
Demosand related demo models.
- Copy
-
Controller
- Copy the closest demo controller (static:
AdminDemosController; dynamic:AdminDemosDynamicorAdminDemosVue) and rename the class/file. - Adjust
base_url,required_fields,save_fields, and related model wiring ininit. Tailor list/show/showform logic and validation to your schema. - Expose extra actions (autocomplete, file uploads, junction updates) as needed by your feature.
- Copy the closest demo controller (static:
-
Templates and config
- Duplicate the matching folder under
App_Data/template/admin/(for example,demosordemosdynamic) to a folder named after your controller URL. - Replace hardcoded titles/URLs inside
url.html,title.html, and other snippets. Updateconfig.jsonsosave_fields, list columns, and lookup dropdowns mirror your schema and foreign keys (see dynamic controller config). - Prune unused partials or fields in
index/,show/, andshowform/templates and keep layout hooks (return URLs, list filters, buttons) aligned with your controller logic.
- Duplicate the matching folder under
-
Navigation and permissions
- Either add a static link to the admin sidebar template or insert/update a
menu_itemsrow that points to the controller URL and display name so the sidebar shows your module. - Confirm
access_levelon the controller (e.g.,Users.ACL_MANAGERor, with RBAC enabled,Users.ACL_VISITORgated by roles) matches who should reach the module and ensure any lookup controllers are registered infwcontrollersif they support dropdowns.
- Either add a static link to the admin sidebar template or insert/update a
Following these steps replicates what the Developer Tools automate while letting you tailor every file.