builder

package
v0.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 3, 2026 License: Apache-2.0 Imports: 7 Imported by: 0

README

Email Template Builder

A beautiful, minimalist email template builder for AuthSome, inspired by email-builder-js.

Features

  • 🎨 Visual Drag & Drop Editor - Build emails visually without writing HTML
  • 📱 Mobile Responsive - All templates are mobile-friendly by default
  • 🧱 Block-Based - Compose emails from reusable blocks
  • 👁️ Live Preview - See changes in real-time
  • 💾 JSON Storage - Templates stored as clean JSON configuration
  • 🎯 Variable Support - Use template variables like {{.UserName}}
  • 📦 Sample Templates - Pre-built templates to get started quickly
  • 🔧 Extensible - Easy to add custom blocks

Architecture

The builder is composed of several key components:

1. Block Types (types.go)

Defines all available block types and their data structures:

  • EmailLayout - Root container with global styles
  • Text - Paragraph text with formatting
  • Heading - Section headings (h1-h6)
  • Button - Call-to-action buttons
  • Image - Pictures and logos
  • Divider - Horizontal separators
  • Spacer - Vertical spacing
  • Container - Group blocks together
  • Columns - Multi-column layouts
  • Avatar - Profile pictures
  • HTML - Custom HTML code
2. Renderer (renderer.go)

Converts JSON documents to HTML email:

doc := NewDocument()
renderer := NewRenderer(doc)
html, err := renderer.RenderToHTML()

The renderer uses gomponents to generate email-safe HTML that works across all email clients.

3. Templates (templates.go)

Pre-built sample templates:

  • Welcome Email - Greet new users
  • OTP Code - One-time password verification
  • Password Reset - Secure password reset
  • Invitation - Organization invitations
  • Notification - General purpose notifications
4. UI (ui.go)

Visual builder interface with:

  • Left Sidebar - Block palette and sample templates
  • Center Canvas - Design, preview, and code views
  • Right Sidebar - Properties panel for selected blocks
5. Dashboard Integration (dashboard.go)

Integrates the builder into the AuthSome dashboard:

  • Builder routes
  • Template management
  • Preview generation
  • Sample template loading

Usage

Creating a New Template
// Create a new empty document
doc := builder.NewDocument()

// Add blocks
blockID, _ := doc.AddBlock(builder.BlockTypeHeading, map[string]interface{}{
    "style": map[string]interface{}{
        "textAlign": "center",
        "color": "#1a1a1a",
    },
    "props": map[string]interface{}{
        "text": "Welcome!",
        "level": "h1",
    },
}, doc.Root)

// Render to HTML
renderer := builder.NewRenderer(doc)
html, _ := renderer.RenderToHTML()
Using Sample Templates
// Load a sample template
doc, err := builder.GetSampleTemplate("welcome")

// Customize it
// ... modify blocks ...

// Render with variables
html, err := builder.RenderTemplate(doc, map[string]interface{}{
    "AppName": "My App",
    "UserName": "John Doe",
    "DashboardURL": "https://example.com/dashboard",
})
Integrating with Dashboard
// In your plugin initialization
builderHandler := builder.NewDashboardHandler(notificationService)
routes := builderHandler.RegisterRoutes()

// Register routes with dashboard
for _, route := range routes {
    dashboardPlugin.RegisterRoute(route)
}

Block Structure

Each block in the document has this structure:

{
  "type": "BlockType",
  "data": {
    "style": {
      "color": "#333",
      "fontSize": 16,
      "padding": {
        "top": 16,
        "right": 24,
        "bottom": 16,
        "left": 24
      }
    },
    "props": {
      // Block-specific properties
    },
    "childrenIds": [] // For container blocks
  }
}

Email Client Compatibility

All blocks are tested and compatible with:

  • ✅ Gmail (Desktop & Mobile)
  • ✅ Apple Mail (Desktop & Mobile)
  • ✅ Outlook (2016+, Office 365, Web)
  • ✅ Yahoo! Mail
  • ✅ Thunderbird
  • ✅ Mobile clients (iOS Mail, Android Gmail)

Template Variables

The builder supports Go template variables:

Hello {{.UserName}},

Welcome to {{.AppName}}!

{{if .HasPremium}}
You have premium access!
{{end}}

Variables are rendered using Go's text/template engine in the notification service.

Extending the Builder

Adding a Custom Block
  1. Define the block type in types.go:
const BlockTypeCustom BlockType = "Custom"

type CustomBlockData struct {
    Style Style              `json:"style"`
    Props CustomBlockProps   `json:"props"`
}

type CustomBlockProps struct {
    CustomField string `json:"customField"`
}
  1. Add renderer in renderer.go:
func (r *Renderer) renderCustom(block Block) g.Node {
    data := block.Data
    props := getMap(data, "props")
    
    customField := getString(props, "customField", "")
    
    return Div(
        g.Text(customField),
    )
}
  1. Update the UI block palette in ui.go

  2. Add default data in getDefaultBlockData()

Best Practices

Design Guidelines
  1. Keep it Simple - Use clear hierarchy and whitespace
  2. Mobile First - Test on mobile devices
  3. Readable Typography - Use 14-16px for body text
  4. Clear CTAs - Make buttons obvious and actionable
  5. Brand Consistency - Use consistent colors and fonts
Technical Guidelines
  1. Use Tables for Layout - Email clients require table-based layouts
  2. Inline Styles - The renderer uses inline styles for compatibility
  3. Test Thoroughly - Test across different email clients
  4. Keep Images Small - Optimize images for fast loading
  5. Alt Text - Always provide alt text for images

Performance

  • Lightweight - Minimal JavaScript, no external dependencies
  • Fast Rendering - Gomponents generates HTML efficiently
  • Small Payloads - JSON documents are compact
  • Cacheable - Templates can be cached once rendered

Future Enhancements

  • Undo/Redo functionality
  • Copy/paste blocks
  • Block templates library
  • A/B testing support
  • Dark mode support
  • Export to other formats (MJML, React Email)
  • Advanced layout blocks (grids, carousels)
  • Custom CSS support
  • Template marketplace

Credits

Inspired by:

Built with:

License

Part of AuthSome - see main project LICENSE

Documentation

Index

Constants

This section is empty.

Variables

View Source
var SampleTemplates = map[string]*Document{}

SampleTemplates provides pre-built email templates

Functions

func BuilderButton

func BuilderButton(basePath string, appID string) g.Node

BuilderButton returns a button component to launch the builder

func BuilderIntegrationCard

func BuilderIntegrationCard() g.Node

BuilderIntegrationCard renders an info card about the builder

func ExampleComplexLayout

func ExampleComplexLayout()

ExampleComplexLayout shows how to create a complex layout with columns

func ExampleCreateTemplate

func ExampleCreateTemplate()

ExampleCreateTemplate shows how to create a template from scratch

func ExampleModifyTemplate

func ExampleModifyTemplate()

ExampleModifyTemplate shows how to modify an existing template

func ExampleSerialization

func ExampleSerialization()

ExampleSerialization shows how to save and load documents

func ExampleUseSampleTemplate

func ExampleUseSampleTemplate()

ExampleUseSampleTemplate shows how to use a sample template

func ExampleValidation

func ExampleValidation()

ExampleValidation shows how to validate a document

func ListSampleTemplates

func ListSampleTemplates() []string

ListSampleTemplates returns list of available sample templates

func RenderTemplate

func RenderTemplate(doc *Document, variables map[string]interface{}) (string, error)

RenderTemplate is a helper to render a template to HTML

func RunAllExamples

func RunAllExamples()

RunAllExamples runs all example functions

func SampleTemplatesCompact

func SampleTemplatesCompact(basePath string, currentApp *app.App) g.Node

SampleTemplatesCompact renders a compact version for sidebars/modals

func SampleTemplatesGallery

func SampleTemplatesGallery(basePath string, currentApp *app.App) g.Node

SampleTemplatesGallery renders a gallery of sample templates

func TemplatePreviewCard

func TemplatePreviewCard(template *Document, name, description, category string) g.Node

TemplatePreviewCard renders a preview card for a template

func TemplateSelector

func TemplateSelector(basePath string, currentApp *app.App) g.Node

TemplateSelector renders a template selection component for the create modal

Types

type AvatarBlockData

type AvatarBlockData struct {
	Style BlockStyle       `json:"style"`
	Props AvatarBlockProps `json:"props"`
}

AvatarBlockData represents avatar block configuration

type AvatarBlockProps

type AvatarBlockProps struct {
	ImageURL string `json:"imageUrl"`
	Alt      string `json:"alt"`
	Size     int    `json:"size"`
	Shape    string `json:"shape"` // circle, square, rounded
}

type Block

type Block struct {
	Type BlockType              `json:"type"`
	Data map[string]interface{} `json:"data"`
}

Block represents a single block in the email

type BlockStyle

type BlockStyle struct {
	BackgroundColor string   `json:"backgroundColor,omitempty"`
	Color           string   `json:"color,omitempty"`
	FontFamily      string   `json:"fontFamily,omitempty"`
	FontSize        int      `json:"fontSize,omitempty"`
	FontWeight      string   `json:"fontWeight,omitempty"`
	TextAlign       string   `json:"textAlign,omitempty"`
	Padding         *Padding `json:"padding,omitempty"`
}

BlockStyle represents common style properties for blocks

type BlockType

type BlockType string

BlockType represents the type of email block

const (
	BlockTypeEmailLayout BlockType = "EmailLayout"
	BlockTypeText        BlockType = "Text"
	BlockTypeHeading     BlockType = "Heading"
	BlockTypeButton      BlockType = "Button"
	BlockTypeImage       BlockType = "Image"
	BlockTypeDivider     BlockType = "Divider"
	BlockTypeSpacer      BlockType = "Spacer"
	BlockTypeContainer   BlockType = "Container"
	BlockTypeColumns     BlockType = "Columns"
	BlockTypeColumn      BlockType = "Column"
	BlockTypeHTML        BlockType = "HTML"
	BlockTypeAvatar      BlockType = "Avatar"
)

type BuilderUI

type BuilderUI struct {
	// contains filtered or unexported fields
}

BuilderUI renders the visual email builder interface

func NewBuilderUI

func NewBuilderUI(doc *Document, previewURL, saveURL string) *BuilderUI

NewBuilderUI creates a new builder UI instance

func NewBuilderUIWithAutosave

func NewBuilderUIWithAutosave(doc *Document, previewURL, saveURL, backURL, templateID string) *BuilderUI

NewBuilderUIWithAutosave creates a new builder UI instance with autosave enabled

func (*BuilderUI) Render

func (b *BuilderUI) Render() g.Node

Render renders the complete builder interface

type ButtonBlockData

type ButtonBlockData struct {
	Style BlockStyle       `json:"style"`
	Props ButtonBlockProps `json:"props"`
}

ButtonBlockData represents button block configuration

type ButtonBlockProps

type ButtonBlockProps struct {
	Text         string `json:"text"`
	URL          string `json:"url"`
	ButtonColor  string `json:"buttonColor"`
	TextColor    string `json:"textColor"`
	BorderRadius int    `json:"borderRadius"`
	FullWidth    bool   `json:"fullWidth"`
}

type ColumnBlockData

type ColumnBlockData struct {
	Style       BlockStyle       `json:"style"`
	Props       ColumnBlockProps `json:"props"`
	ChildrenIDs []string         `json:"childrenIds"`
}

ColumnBlockData represents a single column in columns block

type ColumnBlockProps

type ColumnBlockProps struct {
	Width string `json:"width,omitempty"` // Can be percentage or auto
}

type ColumnsBlockData

type ColumnsBlockData struct {
	Style       BlockStyle        `json:"style"`
	Props       ColumnsBlockProps `json:"props"`
	ChildrenIDs []string          `json:"childrenIds"` // Column IDs
}

ColumnsBlockData represents columns block configuration

type ColumnsBlockProps

type ColumnsBlockProps struct {
	ColumnsCount int `json:"columnsCount"`
	ColumnsGap   int `json:"columnsGap"`
}

type ContainerBlockData

type ContainerBlockData struct {
	Style       BlockStyle          `json:"style"`
	Props       ContainerBlockProps `json:"props"`
	ChildrenIDs []string            `json:"childrenIds"`
}

ContainerBlockData represents container block configuration

type ContainerBlockProps

type ContainerBlockProps struct {
	BackgroundColor string `json:"backgroundColor,omitempty"`
}

type DividerBlockData

type DividerBlockData struct {
	Style BlockStyle        `json:"style"`
	Props DividerBlockProps `json:"props"`
}

DividerBlockData represents divider block configuration

type DividerBlockProps

type DividerBlockProps struct {
	LineColor  string `json:"lineColor"`
	LineHeight int    `json:"lineHeight"`
}

type Document

type Document struct {
	Root   string           `json:"root"`
	Blocks map[string]Block `json:"blocks"`
}

Document represents the email builder document structure

func FromJSON

func FromJSON(jsonStr string) (*Document, error)

FromJSON creates a document from JSON string

func GetSampleTemplate

func GetSampleTemplate(name string) (*Document, error)

GetSampleTemplate returns a sample template by name

func NewDocument

func NewDocument() *Document

NewDocument creates a new empty email document

func (*Document) AddBlock

func (d *Document) AddBlock(blockType BlockType, data map[string]interface{}, parentID string) (string, error)

AddBlock adds a block to the document and returns its ID

func (*Document) RemoveBlock

func (d *Document) RemoveBlock(blockID string) error

RemoveBlock removes a block from the document

func (*Document) ToJSON

func (d *Document) ToJSON() (string, error)

ToJSON converts the document to JSON string

func (*Document) Validate

func (d *Document) Validate() error

Validate validates the document structure

type EmailLayoutData

type EmailLayoutData struct {
	BackdropColor string   `json:"backdropColor"`
	CanvasColor   string   `json:"canvasColor"`
	TextColor     string   `json:"textColor"`
	LinkColor     string   `json:"linkColor"`
	FontFamily    string   `json:"fontFamily"`
	ChildrenIDs   []string `json:"childrenIds"`
}

EmailLayoutData represents the root email layout configuration

type HTMLBlockData

type HTMLBlockData struct {
	Style BlockStyle     `json:"style"`
	Props HTMLBlockProps `json:"props"`
}

HTMLBlockData represents raw HTML block configuration

type HTMLBlockProps

type HTMLBlockProps struct {
	HTML string `json:"html"`
}

type HeadingBlockData

type HeadingBlockData struct {
	Style BlockStyle        `json:"style"`
	Props HeadingBlockProps `json:"props"`
}

HeadingBlockData represents heading block configuration

type HeadingBlockProps

type HeadingBlockProps struct {
	Text  string `json:"text"`
	Level string `json:"level"` // h1, h2, h3, h4, h5, h6
}

type ImageBlockData

type ImageBlockData struct {
	Style BlockStyle      `json:"style"`
	Props ImageBlockProps `json:"props"`
}

ImageBlockData represents image block configuration

type ImageBlockProps

type ImageBlockProps struct {
	URL              string `json:"url"`
	Alt              string `json:"alt"`
	LinkURL          string `json:"linkUrl,omitempty"`
	Width            string `json:"width"`
	Height           string `json:"height,omitempty"`
	ContentAlignment string `json:"contentAlignment"` // left, center, right
}

type Padding

type Padding struct {
	Top    int `json:"top"`
	Right  int `json:"right"`
	Bottom int `json:"bottom"`
	Left   int `json:"left"`
}

Padding represents padding configuration

type Renderer

type Renderer struct {
	// contains filtered or unexported fields
}

Renderer converts email builder documents to HTML

func NewRenderer

func NewRenderer(document *Document) *Renderer

NewRenderer creates a new renderer for the given document

func (*Renderer) Render

func (r *Renderer) Render() (g.Node, error)

Render renders the document to gomponents Node

func (*Renderer) RenderToHTML

func (r *Renderer) RenderToHTML() (string, error)

RenderToHTML renders the document to HTML string

type SpacerBlockData

type SpacerBlockData struct {
	Style BlockStyle       `json:"style"`
	Props SpacerBlockProps `json:"props"`
}

SpacerBlockData represents spacer block configuration

type SpacerBlockProps

type SpacerBlockProps struct {
	Height int `json:"height"`
}

type TemplateInfo

type TemplateInfo struct {
	Name        string
	DisplayName string
	Description string
	Category    string
}

TemplateInfo holds metadata about sample templates

func GetAllTemplateInfo

func GetAllTemplateInfo() []TemplateInfo

GetAllTemplateInfo returns info about all available templates

type TextBlockData

type TextBlockData struct {
	Style BlockStyle     `json:"style"`
	Props TextBlockProps `json:"props"`
}

TextBlockData represents text block configuration

type TextBlockProps

type TextBlockProps struct {
	Text string `json:"text"`
}

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL