Creating Modules
Guide to creating new modules for THLSPress
Guide: Creating a New Module
This guide provides a comprehensive walkthrough for developers on how to create a new, installable module for the THLSPress ecosystem. Adhering to this structure ensures compatibility with the thlspress-cli.
A module is a self-contained directory located in the /templates folder of the monorepo.
1. Module Structure
Every module must follow a specific directory structure. Let's use a hypothetical store module as an example:
templates/
└── store/
├── app/
│ ├── (auth-routes)/admin-panel/store/
│ │ ├── products/
│ │ └── orders/
│ ├── (pages)/store/
│ └── api/store/
├── codemods/
│ └── sidebar.snippet.ts
├── prisma/
│ ├── append.prisma.snippet
│ └── inject.prisma.snippet
└── module.jsonmodule.json(Required): The manifest file that defines the module.app/(Required): Contains the Next.js application code. The CLI will merge this directory with the user's projectapp/directory.prisma/(Optional): Contains snippets for modifying the database schema.codemods/(Optional): Contains snippets for modifying existing TypeScript/JavaScript files.
2. The module.json Manifest
This JSON file is the heart of your module. It provides the CLI with all the necessary metadata.
Example templates/store/module.json:
{
"name": "store",
"version": "1.0.0",
"description": "Adds a fully-featured e-commerce platform to THLSPress.",
"dependencies": {
"stripe": "15.8.0",
"zod": "3.23.8"
},
"devDependencies": {}
}name: The unique, kebab-case identifier for the module.version: The semantic version of the module.dependencies: A map of production dependencies and their exact versions required by the module.devDependencies: A map of development dependencies.
3. Modifying the Database (/prisma)
If your module requires database changes, you must provide snippets in the /prisma directory.
-
append.prisma.snippet:- Purpose: To add brand new, self-contained models and enums.
- Content: Contains full Prisma model definitions (e.g.,
model Product { ... },model Order { ... }). - Convention: Wrap the entire content in
// --- START <MODULE_NAME> MODULE ---and// --- END <MODULE_NAME> MODULE ---comments to prevent duplicate injection.
-
inject.prisma.snippet:- Purpose: To add fields or relations to existing core models.
- Content: Uses a special syntax with
// @@TARGET:blocks to specify where to inject code.
Example
inject.prisma.snippet:// Add a relation to the core User model for their orders. // @@TARGET: USER orders Order[]
4. Modifying Source Code (/codemods)
To modify existing files like the admin panel sidebar, use the /codemods directory.
-
File Naming: Snippets should be named descriptively (e.g.,
sidebar.snippet.ts,tailwind.config.snippet.js). -
Snippet Syntax: A snippet file has two parts: an optional import section and one or more target sections.
Example
sidebar.snippet.ts:// Defines required imports for the code below. // Format: <package-name>: <Import1>, <Import2> // @@IMPORTS // lucide-react: ShoppingCart, Package // Defines the code block to be injected. // @@TARGET: SIDEBAR_ROOT { type: "collapsible", label: "Store", icon: ShoppingCart, children: [ { type: "sublink", label: "Products", href: "/admin-panel/store/products", icon: Package, }, ], }, -
Target File Preparation: The target file in the Core CMS (e.g.,
cms/components/Sidebar/defaultSidebarItems.ts) must be prepared with corresponding markers:// THLSPRESS:INJECT:IMPORTSfor new import statements.// THLSPRESS:INJECT:LUCIDE_IMPORTSspecifically forlucide-reactimports.// THLSPRESS:INJECT:SIDEBAR_ROOTfor the code block itself.
By following this guide, you can create powerful, reusable modules that seamlessly integrate with the THLSPress ecosystem.