# @nestjs/dynamic-templates

A dynamic template management system for NestJS applications. This package provides a flexible way to manage and render templates with support for multiple template engines and language formats.

## Features

- Support for multiple template engines (Nunjucks, Handlebars, EJS, Pug)
- Support for multiple language formats (MJML, HTML, Markdown, Text)
- Template layouts with inheritance
- Scoped templates with fallback to system templates
- Locale support with fallback
- Template validation
- TypeScript support

## Installation

```bash
npm install @nestjs/dynamic-templates
```

## Quick Start

1. Import the module in your `app.module.ts`:

```typescript
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { NestDynamicTemplatesModule } from '@nestjs/dynamic-templates';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      // your database configuration
    }),
    NestDynamicTemplatesModule
  ]
})
export class AppModule {}
```

2. Use the services in your application:

```typescript
import { Injectable } from '@nestjs/common';
import { TemplateService } from '@nestjs/dynamic-templates';
import { TemplateTypeEnum } from '@nestjs/dynamic-templates';

@Injectable()
export class EmailService {
  constructor(private readonly templateService: TemplateService) {}

  async sendWelcomeEmail(user: any) {
    const result = await this.templateService.renderTemplate({
      type: TemplateTypeEnum.EMAIL,
      name: 'welcome',
      scope: 'user',
      scopeId: user.id,
      locale: user.locale,
      context: {
        user,
        appName: 'My App'
      }
    });

    // Send email using your email service
    await this.emailService.send({
      to: user.email,
      subject: result.subject,
      html: result.content
    });
  }
}
```

## Template Creation

Create a template using the `TemplateService`:

```typescript
await templateService.createTemplate({
  name: 'welcome',
  type: TemplateTypeEnum.EMAIL,
  format: TemplateFormatEnum.NUNJUCKS,
  languageFormat: LanguageFormatEnum.MJML,
  content: `
    <mjml>
      <mj-body>
        <mj-section>
          <mj-column>
            <mj-text>
              Welcome to {{ appName }}, {{ user.name }}!
            </mj-text>
          </mj-column>
        </mj-section>
      </mj-body>
    </mjml>
  `,
  subject: 'Welcome to {{ appName }}',
  scope: 'user',
  scopeId: '123',
  locale: 'en'
});
```

## Template Layouts

Create a layout template:

```typescript
await templateLayoutService.createLayout({
  name: 'email-base',
  format: TemplateFormatEnum.NUNJUCKS,
  languageFormat: LanguageFormatEnum.MJML,
  content: `
    <mjml>
      <mj-head>
        <mj-title>{{ title }}</mj-title>
      </mj-head>
      <mj-body>
        <mj-section>
          <mj-column>
            <mj-text>
              {{ content }}
            </mj-text>
          </mj-column>
        </mj-section>
      </mj-body>
    </mjml>
  `,
  scope: 'system'
});
```

Use the layout in a template:

```typescript
await templateService.createTemplate({
  name: 'welcome',
  type: TemplateTypeEnum.EMAIL,
  format: TemplateFormatEnum.NUNJUCKS,
  languageFormat: LanguageFormatEnum.MJML,
  content: 'Welcome to {{ appName }}, {{ user.name }}!',
  subject: 'Welcome to {{ appName }}',
  templateLayoutName: 'email-base',
  scope: 'user',
  scopeId: '123',
  locale: 'en'
});
```

## API Reference

### TemplateService

- `renderTemplate(data: RenderTemplateDto): Promise<TemplateOutputDTO>`
- `createTemplate(data: CreateTemplateDto): Promise<NestDynamicTemplate>`
- `updateTemplate(data: UpdateTemplateDto): Promise<NestDynamicTemplate>`
- `deleteTemplate(id: string): Promise<void>`
- `findTemplate(id: string): Promise<NestDynamicTemplate>`
- `findTemplates(type?: TemplateTypeEnum, scope?: string, scopeId?: string, locale?: string): Promise<NestDynamicTemplate[]>`

### TemplateLayoutService

- `renderLayout(data: RenderTemplateLayoutDto): Promise<string>`
- `createLayout(data: CreateTemplateLayoutDto): Promise<TemplateLayout>`
- `updateLayout(data: UpdateTemplateLayoutDto): Promise<TemplateLayout>`
- `deleteLayout(id: string): Promise<void>`
- `findLayout(id: string): Promise<TemplateLayout>`
- `findLayouts(scope?: string, scopeId?: string, locale?: string): Promise<TemplateLayout[]>`

## License

MIT
