UNPKG

@ackplus/nest-dynamic-templates

Version:

Dynamic template management for NestJS applications

290 lines (240 loc) 7.82 kB
# NestJS Dynamic Templates A powerful NestJS module for dynamic template management with support for multiple template engines and languages. ## Features - 🚀 Multiple template engines (Nunjucks, Handlebars, EJS, Pug) - 🌐 Multiple language support (HTML, MJML, Markdown, Text) - 💾 Database storage for templates and layouts - 🔧 Configurable and extensible - 🎯 TypeScript support - 📦 Easy integration ## Installation ```bash npm install @ackplus/nest-dynamic-templates # or yarn add @ackplus/nest-dynamic-templates ``` ## Usage ### Option 1: Basic Usage (No Configuration Required) ```typescript import { Module } from '@nestjs/common'; import { NestDynamicTemplatesModule } from '@ackplus/nest-dynamic-templates'; @Module({ imports: [ NestDynamicTemplatesModule, // Provides basic services with default configuration ], }) export class AppModule {} ``` ### Option 2: Using forFeature() (Explicit Basic Usage) ```typescript import { Module } from '@nestjs/common'; import { NestDynamicTemplatesModule } from '@ackplus/nest-dynamic-templates'; @Module({ imports: [ NestDynamicTemplatesModule.forFeature(), // Explicitly import basic services ], }) export class AppModule {} ``` ### Option 3: Using forRoot() (With Configuration) ```typescript import { Module } from '@nestjs/common'; import { NestDynamicTemplatesModule, TemplateEngineEnum, TemplateLanguageEnum } from '@ackplus/nest-dynamic-templates'; @Module({ imports: [ NestDynamicTemplatesModule.forRoot({ isGlobal: true, engines: { template: [TemplateEngineEnum.NUNJUCKS, TemplateEngineEnum.HANDLEBARS], language: [TemplateLanguageEnum.HTML, TemplateLanguageEnum.MJML], }, enginesOptions: { filters: { uppercase: (str) => str.toUpperCase(), reverse: (str) => str.split('').reverse().join(''), }, template: { [TemplateEngineEnum.NUNJUCKS]: { autoescape: true, }, }, }, }), ], }) export class AppModule {} ``` ### Option 4: Using forRootAsync() (Async Configuration) #### With useFactory ```typescript import { Module } from '@nestjs/common'; import { ConfigModule, ConfigService } from '@nestjs/config'; import { NestDynamicTemplatesModule } from '@ackplus/nest-dynamic-templates'; @Module({ imports: [ ConfigModule.forRoot(), NestDynamicTemplatesModule.forRootAsync({ imports: [ConfigModule], useFactory: async (configService: ConfigService) => ({ isGlobal: true, engines: { template: configService.get('TEMPLATE_ENGINES')?.split(',') || ['nunjucks'], language: configService.get('LANGUAGE_ENGINES')?.split(',') || ['html'], }, }), inject: [ConfigService], }), ], }) export class AppModule {} ``` #### With useClass ```typescript import { Injectable } from '@nestjs/common'; import { NestDynamicTemplatesModuleOptionsFactory, NestDynamicTemplatesModuleConfig, TemplateEngineEnum, TemplateLanguageEnum } from '@ackplus/nest-dynamic-templates'; @Injectable() export class TemplatesConfigService implements NestDynamicTemplatesModuleOptionsFactory { createNestDynamicTemplatesModuleOptions(): NestDynamicTemplatesModuleConfig { return { isGlobal: true, engines: { template: [TemplateEngineEnum.NUNJUCKS], language: [TemplateLanguageEnum.HTML, TemplateLanguageEnum.MJML], }, }; } } @Module({ imports: [ NestDynamicTemplatesModule.forRootAsync({ useClass: TemplatesConfigService, }), ], providers: [TemplatesConfigService], }) export class AppModule {} ``` ## Using the Services Once imported, you can inject and use the template services: ```typescript import { Injectable } from '@nestjs/common'; import { TemplateService, TemplateLayoutService } from '@ackplus/nest-dynamic-templates'; @Injectable() export class EmailService { constructor( private readonly templateService: TemplateService, private readonly templateLayoutService: TemplateLayoutService, ) {} async sendWelcomeEmail(user: any) { // Create a template const template = await this.templateService.createTemplate({ name: 'welcome-email', displayName: 'Welcome Email', engine: 'nunjucks', language: 'html', subject: 'Welcome {{ user.name }}!', content: '<h1>Hello {{ user.name }}</h1><p>Welcome to our platform!</p>', scope: 'system', locale: 'en', }); // Render the template const rendered = await this.templateService.renderTemplate('welcome-email', { user: { name: user.name }, }); console.log('Rendered email:', rendered); // Send email using your preferred email service } async createEmailLayout() { // Create a layout const layout = await this.templateLayoutService.createTemplateLayout({ name: 'email-layout', displayName: 'Email Layout', engine: 'nunjucks', language: 'html', content: ` <!DOCTYPE html> <html> <head><title>{{ subject }}</title></head> <body> <header>Our Company</header> <main>{{ content | safe }}</main> <footer>© 2024 Our Company</footer> </body> </html> `, scope: 'system', locale: 'en', }); return layout; } } ``` ## Configuration Options ### NestDynamicTemplatesModuleConfig ```typescript interface NestDynamicTemplatesModuleConfig { isGlobal?: boolean; // Make module global engines?: { template?: TemplateEngineEnum[]; // Enabled template engines language?: TemplateLanguageEnum[]; // Enabled language engines }; enginesOptions?: { filters?: Record<string, Function>; // Custom filters template?: Partial<Record<TemplateEngineEnum, any>>; // Engine-specific options language?: Partial<Record<TemplateLanguageEnum, any>>; // Language-specific options }; } ``` ### Supported Engines #### Template Engines - `nunjucks` - Nunjucks templating - `handlebars` - Handlebars templating - `ejs` - EJS templating - `pug` - Pug templating #### Language Engines - `html` - HTML output - `mjml` - MJML email templates - `markdown` - Markdown output - `text` - Plain text output ## Benefits of Each Approach ### Basic Usage (`NestDynamicTemplatesModule`) - ✅ **Zero configuration** - Works out of the box - ✅ **Quick setup** - Just import and use - ✅ **Default engines** - Nunjucks + HTML/MJML/Text - ❌ **Limited customization** - No custom filters or options ### forFeature() - ✅ **Explicit** - Clear intent for basic usage - ✅ **Same as basic** - All benefits of basic usage - ✅ **Consistent API** - Matches other NestJS modules ### forRoot() - ✅ **Full configuration** - Complete control over engines and options - ✅ **Custom filters** - Add your own template filters - ✅ **Engine options** - Configure individual engines - ✅ **Global module** - Available throughout the app ### forRootAsync() - ✅ **Dynamic configuration** - Load config from external sources - ✅ **Dependency injection** - Use other services for configuration - ✅ **Environment-based** - Different configs for different environments - ✅ **Factory pattern** - Clean separation of configuration logic ## Migration Guide If you're upgrading from a previous version: ### Before ```typescript // Only forRoot was available NestDynamicTemplatesModule.forRoot(config) ``` ### After ```typescript // Multiple options now available NestDynamicTemplatesModule // Basic usage NestDynamicTemplatesModule.forFeature() // Explicit basic usage NestDynamicTemplatesModule.forRoot(config) // With configuration NestDynamicTemplatesModule.forRootAsync(...) // Async configuration ``` ## License MIT