2.48.0 • Published 6 months ago

@memberjunction/templates v2.48.0

Weekly downloads
-
License
ISC
Repository
-
Last release
6 months ago

@memberjunction/templates

The @memberjunction/templates library provides a powerful templating engine built on Nunjucks with MemberJunction-specific extensions for dynamic content generation, AI-powered prompts, and recursive template embedding.

Overview

This package serves as the core templating engine for MemberJunction applications, offering:

  • Nunjucks-based templating with full syntax support
  • Template management with metadata integration
  • Custom extensions for AI prompts and template embedding
  • Type-safe interfaces for template rendering
  • Caching and performance optimization
  • Async rendering support

Installation

npm install @memberjunction/templates

Key Features

1. Template Engine

  • Manages template metadata and caching
  • Provides both metadata-based and simple rendering APIs
  • Integrates with MemberJunction's entity system
  • Supports template validation and parameter checking

2. AI Prompt Extension

  • Embeds AI-generated content directly in templates
  • Supports multiple AI models (OpenAI, Groq, etc.)
  • Configurable formatting options
  • Seamless integration with MemberJunction's AI Engine

3. Template Embed Extension

  • Recursive template inclusion with cycle detection
  • Content type inheritance and fallbacks
  • Data context passing and merging
  • Error handling for missing templates

Usage

Basic Template Rendering

import { TemplateEngineServer } from '@memberjunction/templates';
import { UserInfo } from '@memberjunction/core';

// Get the template engine instance
const templateEngine = TemplateEngineServer.Instance;

// Configure the engine (usually done once at startup)
await templateEngine.Config(false, contextUser);

// Simple rendering without metadata
const result = await templateEngine.RenderTemplateSimple(
    'Hello {{ name }}! Welcome to {{ company }}.',
    { name: 'John', company: 'Acme Corp' }
);

if (result.Success) {
    console.log(result.Output); // "Hello John! Welcome to Acme Corp."
}

Rendering with Template Metadata

import { TemplateEngineServer } from '@memberjunction/templates';
import { TemplateContentEntity } from '@memberjunction/core-entities';

// Assume you have loaded a template entity and its content
const templateEntity = await templateEngine.GetTemplateByName('WelcomeEmail');
const templateContent = templateEntity.GetHighestPriorityContent();

// Render with validation
const result = await templateEngine.RenderTemplate(
    templateEntity,
    templateContent,
    {
        userName: 'John Doe',
        accountType: 'Premium',
        signupDate: new Date()
    },
    false // SkipValidation = false
);

if (!result.Success) {
    console.error('Template rendering failed:', result.Message);
}

Using the AI Prompt Extension

// In your template:
const templateText = `
Dear {{ userName }},

{% AIPrompt AIModel="gpt-4", AllowFormatting=false %}
Generate a personalized welcome message for a new {{ accountType }} customer 
named {{ userName }} who just signed up for our service. Make it warm and 
professional, highlighting the benefits of their account type.
{% endAIPrompt %}

Best regards,
The Team
`;

const result = await templateEngine.RenderTemplateSimple(templateText, {
    userName: 'Sarah',
    accountType: 'Enterprise'
});

Using the Template Embed Extension

// Main template
const mainTemplate = `
{% template "Header", type="HTML" %}

<div class="content">
    <h1>Welcome {{ user.name }}</h1>
    {% template "UserProfile", data={showDetails: true} %}
</div>

{% template "Footer" %}
`;

// The embedded templates will be loaded from the template metadata
// and rendered with the appropriate content type and data context

API Reference

TemplateEngineServer

The main template engine class that handles all template operations.

Methods

Config(forceRefresh?: boolean, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<void>

Configures the template engine and loads template metadata.

RenderTemplate(templateEntity: TemplateEntityExtended, templateContent: TemplateContentEntity, data: any, SkipValidation?: boolean): Promise<TemplateRenderResult>

Renders a template using metadata entities with optional validation.

RenderTemplateSimple(templateText: string, data: any): Promise<TemplateRenderResult>

Renders a template string without metadata integration.

GetTemplateByName(templateName: string): TemplateEntityExtended | null

Retrieves a template entity by its name.

GetTemplateByID(templateID: string): TemplateEntityExtended | null

Retrieves a template entity by its ID.

ClearTemplateCache(): void

Clears the internal template cache.

TemplateRenderResult

interface TemplateRenderResult {
    Success: boolean;     // Whether rendering succeeded
    Output: string;       // The rendered output (null if failed)
    Message?: string;     // Error message (only when Success=false)
}

Extension Configuration

AIPrompt Extension Parameters

  • AIModel (optional): Specific AI model to use (e.g., "gpt-4", "claude-3")
  • AllowFormatting (optional): Whether to allow formatted output (HTML, Markdown, etc.)

Template Embed Extension Parameters

  • First parameter: Template name (required)
  • type (optional): Specific content type to use
  • data (optional): Additional data to pass to the embedded template

Template Extension Development

To create custom template extensions:

import { TemplateExtensionBase, RegisterClass } from '@memberjunction/templates';

@RegisterClass(TemplateExtensionBase, 'MyExtension')
export class MyExtension extends TemplateExtensionBase {
    constructor(contextUser: UserInfo) {
        super(contextUser);
        this.tags = ['myTag'];
    }
    
    public parse(parser: Parser, nodes: Nodes, lexer: Lexer) {
        const tok = parser.nextToken();
        const params = parser.parseSignature(null, true);
        parser.advanceAfterBlockEnd(tok.value);
        
        const body = parser.parseUntilBlocks('endMyTag');
        parser.advanceAfterBlockEnd();
        
        return new nodes.CallExtensionAsync(this, 'run', params, [body]);
    }
    
    public run(context: Context, params: any, body: any, callBack: NunjucksCallback) {
        // Your extension logic here
        try {
            const content = body();
            // Process content...
            callBack(null, processedContent);
        } catch (error) {
            callBack(error);
        }
    }
}

Dependencies

  • @memberjunction/core: Core MemberJunction functionality
  • @memberjunction/templates-base-types: Base types and interfaces
  • @memberjunction/ai: AI integration interfaces
  • @memberjunction/aiengine: AI engine implementation
  • @memberjunction/ai-groq: Groq AI provider
  • @memberjunction/core-entities: Entity definitions
  • @memberjunction/global: Global utilities
  • nunjucks: Template engine

Integration with MemberJunction

This package integrates seamlessly with other MemberJunction packages:

  • Entity System: Templates are stored as entities with full metadata support
  • AI Engine: Direct integration for AI-powered content generation
  • User Context: Templates respect user permissions and context
  • Metadata Provider: Flexible metadata loading strategies

Configuration

The template engine uses the MemberJunction configuration system. Key configuration options:

  • Template caching strategies
  • Default AI models for prompts
  • Extension registration
  • Nunjucks environment settings

Performance Considerations

  • Templates are cached after first compilation
  • Use ClearTemplateCache() when templates are updated
  • AI prompts are processed asynchronously
  • Template embedding includes cycle detection

Error Handling

All rendering methods return a TemplateRenderResult object:

const result = await templateEngine.RenderTemplateSimple(template, data);

if (!result.Success) {
    console.error('Rendering failed:', result.Message);
    // Handle error appropriately
} else {
    // Use result.Output
}

Best Practices

  1. Always check rendering results for success before using output
  2. Configure the engine once at application startup
  3. Use template validation for user-provided data
  4. Clear cache when templates are modified
  5. Handle AI failures gracefully with fallback content
  6. Avoid deep template nesting to prevent performance issues

License

ISC - See LICENSE file for details.

Support

For issues, questions, or contributions, please visit MemberJunction.com or contact the development team.

2.27.1

9 months ago

2.23.2

10 months ago

2.46.0

6 months ago

2.23.1

10 months ago

2.27.0

9 months ago

2.34.0

7 months ago

2.30.0

9 months ago

2.19.4

10 months ago

2.19.5

10 months ago

2.19.2

10 months ago

2.19.3

10 months ago

2.19.0

10 months ago

2.19.1

10 months ago

2.15.2

11 months ago

2.34.2

7 months ago

2.15.0

11 months ago

2.34.1

7 months ago

2.15.1

11 months ago

2.38.0

7 months ago

2.45.0

6 months ago

2.22.1

10 months ago

2.22.0

10 months ago

2.41.0

6 months ago

2.22.2

10 months ago

2.26.1

9 months ago

2.26.0

9 months ago

2.33.0

7 months ago

2.18.3

11 months ago

2.18.1

11 months ago

2.18.2

11 months ago

2.18.0

11 months ago

2.37.1

7 months ago

2.37.0

7 months ago

2.14.0

11 months ago

2.21.0

10 months ago

2.44.0

6 months ago

2.40.0

7 months ago

2.29.0

9 months ago

2.29.2

9 months ago

2.29.1

9 months ago

2.25.0

10 months ago

2.48.0

6 months ago

2.32.0

8 months ago

2.32.2

8 months ago

2.32.1

8 months ago

2.17.0

11 months ago

2.13.4

11 months ago

2.36.0

7 months ago

2.13.2

12 months ago

2.13.3

11 months ago

2.13.0

1 year ago

2.36.1

7 months ago

2.13.1

1 year ago

2.43.0

6 months ago

2.20.2

10 months ago

2.20.3

10 months ago

2.20.0

10 months ago

2.20.1

10 months ago

2.28.0

9 months ago

2.47.0

6 months ago

2.24.1

10 months ago

2.24.0

10 months ago

2.31.0

8 months ago

2.12.0

1 year ago

2.39.0

7 months ago

2.16.1

11 months ago

2.35.1

7 months ago

2.35.0

7 months ago

2.16.0

11 months ago

2.42.1

6 months ago

2.42.0

6 months ago

2.23.0

10 months ago

2.11.0

1 year ago

2.10.0

1 year ago

2.9.0

1 year ago

2.8.0

1 year ago

2.7.0

1 year ago

2.6.1

1 year ago

2.5.2

1 year ago

2.6.0

1 year ago

2.7.1

1 year ago

2.5.1

1 year ago

2.5.0

1 year ago

2.4.1

1 year ago

2.4.0

1 year ago

2.3.3

1 year ago

2.3.2

1 year ago

2.3.1

1 year ago

2.3.0

1 year ago

2.2.1

1 year ago

2.2.0

1 year ago

2.1.5

1 year ago

2.1.4

1 year ago

2.1.3

1 year ago

2.1.2

1 year ago

2.1.1

1 year ago

2.1.0

1 year ago

2.0.0

1 year ago

1.8.1

1 year ago

1.8.0

1 year ago

1.7.1

1 year ago

1.7.0

1 year ago

1.6.1

1 year ago

1.6.0

1 year ago

1.5.3

1 year ago

1.5.2

1 year ago

1.5.1

1 year ago

1.5.0

1 year ago

1.4.1

1 year ago