### Install Gomjml as Go Package Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Import the gomjml library into your Go project using go get. ```bash # Import as library go get github.com/preslavrachev/gomjml ``` -------------------------------- ### Install Gomjml CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Clone the repository, build the binary, and optionally add it to your system's PATH. ```bash # Clone and build git clone https://github.com/preslavrachev/gomjml cd gomjml go build -o bin/gomjml ./cmd/gomjml # Add to PATH (optional) export PATH=$PATH:$(pwd)/bin ``` -------------------------------- ### Get Gomjml CLI Help Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Display help information for the Gomjml CLI or specific commands. ```bash # Get help ./bin/gomjml --help ./bin/gomjml compile --help ``` -------------------------------- ### File Structure Example Source: https://github.com/preslavrachev/gomjml/blob/main/mjml/testdata/AGENTS.md Illustrates the typical file structure for MJML test cases, including input MJML and expected HTML output files. ```bash testdata/ ├── basic.mjml # Input MJML template ├── basic.html # Expected HTML output ├── mj-button.mjml # Button component test ├── mj-button.html # Expected button HTML └── ... # Additional test cases ``` -------------------------------- ### Go Component Rendering Example Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Demonstrates how to implement the Render and GetTagName methods for a component. It shows attribute retrieval using constants, HTML tag building with styles, and basic rendering logic. Ensure all internal rendering methods use io.StringWriter. ```go func (c *MyComponent) Render(w io.StringWriter) error { // Get attributes using constants padding := c.getAttribute(constants.MJMLPadding) fontFamily := c.getAttribute(constants.MJMLFontFamily) // Use HTMLTag builder tdTag := html.NewHTMLTag("td"). AddStyle(constants.CSSPadding, padding). AddStyle(constants.CSSFontFamily, fontFamily) if err := tdTag.RenderOpen(w); err != nil { return err } // Render content... if _, err := w.WriteString(""); err != nil { return err } return nil } func (c *MyComponent) GetTagName() string { return "mj-my-component" } ``` -------------------------------- ### MJML Wrapper and Section Padding Example Source: https://github.com/preslavrachev/gomjml/blob/main/docs/width-calculation-behavior.md Illustrates a common MJML structure where a section is nested within a wrapper that has horizontal padding. This example is used to explain how the wrapper's padding impacts the section's max-width. ```mjml ... ``` -------------------------------- ### MJML Section Structure Example Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/group-vs-section-column-comparison.md Shows the expected HTML structure for an MJML section directly containing columns, without a group wrapper. ```html
``` -------------------------------- ### MJML Group Structure Example Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/group-vs-section-column-comparison.md Illustrates the expected HTML structure for an MJML group, including its wrapper and column elements. ```html
``` -------------------------------- ### MJML Column Rendering Example Source: https://github.com/preslavrachev/gomjml/blob/main/docs/mj-spec.md Illustrates how MJML's internal rendering for columns might produce adjacent MSO conditional blocks, which are then merged by the post-processing step. ```javascript render() { // ... // ... next column ... // ... } ``` -------------------------------- ### Section MRML CSS Class Example Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/group-vs-section-column-comparison.md Shows the CSS classes generated for MJML sections with columns, focusing on column-specific widths like '.mj-column-per-50'. ```css .mj-column-per-50 { width:50% !important; max-width:50%; } ``` -------------------------------- ### Group MRML CSS Class Example Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/group-vs-section-column-comparison.md Demonstrates the additional CSS class '.mj-column-per-100' generated for MJML groups, affecting full-width columns. ```css .mj-column-per-100 { width:100% !important; max-width:100%; } ``` -------------------------------- ### Example MJML Structure for Width Calculation Source: https://github.com/preslavrachev/gomjml/blob/main/docs/container-width-flow.md This MJML structure demonstrates the nested relationship between section, column, and divider components, which is used to illustrate the width flow calculation. ```xml ``` -------------------------------- ### Direct Go Testing Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Navigate to the mjml directory and run tests directly using Go's testing utility. ```bash cd mjml && go test -v ``` -------------------------------- ### Build and Use htmlcompare Utility Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Builds the htmlcompare utility for semantic HTML comparison and demonstrates its usage for comparing MJML test cases. ```bash go build -o bin/htmlcompare ./cmd/htmlcompare ``` ```bash cd mjml/testdata ../../bin/htmlcompare basic ``` ```bash ../../bin/htmlcompare basic --verbose ``` ```bash ./bin/htmlcompare basic --testdata-dir mjml/testdata ``` ```bash ./bin/htmlcompare mj-button-align --testdata-dir mjml/testdata ``` ```bash ./bin/htmlcompare basic -v --testdata-dir mjml/testdata ``` -------------------------------- ### Run Comparative Benchmarks Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Execute comparative benchmarks against the Austin MJML implementation. This command is useful for understanding relative performance. ```bash # Run comparative benchmarks ./bench-austin.sh --markdown ``` -------------------------------- ### Run Benchmarks Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Executes benchmark tests for the gomjml project. ```bash ./bench.sh ``` -------------------------------- ### Run Gomjml Test Suite using CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Execute the project's test suite against the MRML reference implementation. ```bash # Run test suite ./bin/gomjml test ``` -------------------------------- ### Enable AST Caching via CLI Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Use the --cache flag to enable AST caching. Configure the cache Time-To-Live (TTL) with --cache-ttl. ```bash ./bin/gomjml compile input.mjml --cache ``` ```bash ./bin/gomjml compile input.mjml --cache --cache-ttl=10m ``` -------------------------------- ### Go MJML Project Structure Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Illustrates the directory layout for the Go MJML project, separating CLI, core library, and parsing concerns. ```tree go/ ├── cmd/gomjml/ # CLI application │ ├── main.go # Minimal entry point │ └── command/ # Individual CLI commands │ ├── root.go # Root command setup │ ├── compile.go # MJML compilation command │ └── test.go # Test runner command │ ├── mjml/ # Core MJML library (importable) │ ├── component.go # Component factory and interfaces │ ├── render.go # Main rendering logic and MJMLComponent │ ├── mjml_test.go # Library unit tests │ ├── integration_test.go # MJML comparison tests │ │ │ ├── components/ # Individual component implementations │ │ ├── base.go # Shared Component interface and BaseComponent │ │ ├── head.go # mj-head, mj-title, mj-font components │ │ ├── body.go # mj-body component │ │ ├── section.go # mj-section component │ │ ├── column.go # mj-column component │ │ ├── text.go # mj-text component │ │ ├── button.go # mj-button component │ │ └── image.go # mj-image component │ │ │ └── testdata/ # Test MJML files │ ├── basic.mjml │ ├── with-head.mjml │ └── complex-layout.mjml │ └── parser/ # MJML parsing package (importable) ├── parser.go # XML parsing logic with MJMLNode AST └── parser_test.go # Parser unit tests ``` -------------------------------- ### Enable AST Caching in Library Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Enable caching by passing mjml.WithCache() option to the Render function. Configure cache TTL once using SetASTCacheTTLOnce. ```go html, err := mjml.Render(template, mjml.WithCache()) ``` ```go mjml.SetASTCacheTTLOnce(10 * time.Minute) ``` ```go defer mjml.StopASTCacheCleanup() ``` -------------------------------- ### Compile MJML with Custom Cache TTL using CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Configure the cache with a custom Time-To-Live (TTL) duration. ```bash # Configure cache with custom TTL ./bin/gomjml compile input.mjml -o output.html --cache --cache-ttl=10m ``` -------------------------------- ### Go Package Render Method Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Renders MJML content to HTML using the Go package API. Supports direct rendering, enabling debug attributes, and AST caching. ```APIDOC ## Render MJML to HTML (Go Package) ### Description Renders MJML content string to an HTML string using the Go package API. Supports direct rendering with options to include debug attributes and enable AST caching for performance. ### Method Go Function Call ### Endpoint `mjml.Render(mjmlContent string, options ...mjml.RenderOption)` ### Parameters #### Path Parameters - **mjmlContent** (string) - Required - The MJML content as a string. #### Query Parameters - **options** ([]mjml.RenderOption) - Optional - A variadic list of render options. - `mjml.WithDebugTags(bool)`: If true, includes debug attributes. - `mjml.WithCache()`: Enables AST caching. ### Request Example ```go html, err := mjml.Render(mjmlContent, mjml.WithDebugTags(true), mjml.WithCache()) ``` ### Response #### Success Response - **html** (string) - The rendered HTML content. - **err** (error) - An error if the rendering process fails. ``` -------------------------------- ### Compile MJML to HTML using CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Basic command to compile an MJML input file to an HTML output file. ```bash # Basic compilation ./bin/gomjml compile input.mjml -o output.html ``` -------------------------------- ### Run All Tests via CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Execute all tests using the command-line interface. Use the -v flag for verbose output. ```bash # Run all tests via CLI ./bin/gomjml test # Run with verbose output ./bin/gomjml test -v # Run specific test pattern ./bin/gomjml test -pattern "basic" ``` -------------------------------- ### Run gomjml Integration Tests Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Executes integration tests against the reference implementation. Use the -v flag for verbose output or -pattern to filter tests. ```bash ./bin/gomjml test ``` ```bash ./bin/gomjml test -v ``` ```bash ./bin/gomjml test -pattern "basic" ``` -------------------------------- ### Run Internal Go Benchmarks Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Execute the internal Go benchmark suite for gomjml. This command is used for performance testing within the project. ```bash # Run internal Go benchmarks ./bench.sh ``` -------------------------------- ### Configure AST Cache TTL Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Set the Time-To-Live for cached Abstract Syntax Tree entries. This should be called only once. ```go // Set cache TTL before first use (call only once) mjml.SetASTCacheTTLOnce(10 * time.Minute) ``` -------------------------------- ### Compile MJML with Caching Enabled using CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Enable AST caching during compilation for improved performance on repeated renders. ```bash # Enable caching for better performance on repeated renders ./bin/gomjml compile input.mjml -o output.html --cache ``` -------------------------------- ### Build gomjml CLI Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Builds the command-line interface for gomjml. Use the debug build for development and troubleshooting. ```bash go build -tags debug -o bin/gomjml ./cmd/gomjml ``` ```bash go build -o bin/gomjml ./cmd/gomjml ``` -------------------------------- ### Run Detailed MJML Tests Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Runs detailed MJML tests with verbose output using the Go testing framework. Requires a debug build. ```bash go test -tags debug -v ./mjml -run TestMJMLAgainstExpected ``` -------------------------------- ### Debugging Failed Tests with htmlcompare Source: https://github.com/preslavrachev/gomjml/blob/main/mjml/testdata/AGENTS.md Demonstrates how to use the htmlcompare utility to debug failed MJML compilation tests. It shows commands to run from the project root and from the testdata directory. ```bash # From project root ./bin/htmlcompare basic --testdata-dir mjml/testdata # From testdata directory ../../bin/htmlcompare basic ``` -------------------------------- ### Compile MJML to Stdout using CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Compile an MJML input file and output the resulting HTML directly to standard output. ```bash # Output to stdout ./bin/gomjml compile input.mjml -s ``` -------------------------------- ### Render MJML to HTML using Go Package API (Direct) Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Directly render an MJML string to HTML using the `mjml.Render` function. This is the recommended method. ```go package main import ( "fmt" "log" "github.com/preslavrachev/gomjml/mjml" "github.com/preslavrachev/gomjml/parser" ) func main() { mjmlContent := ` My Newsletter Hello World! Click Me ` // Method 1: Direct rendering (recommended) html, err := mjml.Render(mjmlContent) if err != nil { log.Fatal("Render error:", err) } fmt.Println(html) // Method 1b: Direct rendering with debug attributes htmlWithDebug, err := mjml.Render(mjmlContent, mjml.WithDebugTags(true)) if err != nil { log.Fatal("Render error:", err) } fmt.Println(htmlWithDebug) // Includes data-mj-debug-* attributes // Method 1c: Enable caching for performance (opt-in feature) htmlWithCache, err := mjml.Render(mjmlContent, mjml.WithCache()) if err != nil { log.Fatal("Render error:", err) } fmt.Println(htmlWithCache) // Uses cached AST if available // For long-running applications, configure cache TTL before first use mjml.SetASTCacheTTLOnce(10 * time.Minute) // For graceful shutdown in long-running applications (optional) // Not needed for CLI tools or short-lived processes defer mjml.StopASTCacheCleanup() // Method 2: Step-by-step processing ast, err := parser.ParseMJML(mjmlContent) if err != nil { log.Fatal("Parse error:", err) } component, err := mjml.NewFromAST(ast) if err != nil { log.Fatal("Component creation error:", err) } html, err = mjml.RenderComponentString(component) if err != nil { log.Fatal("Render error:", err) } fmt.Println(html) } ``` -------------------------------- ### Run MJML Benchmarks Source: https://github.com/preslavrachev/gomjml/blob/main/docs/benchmarks.md Execute the benchmark script to compare MJML compilation tools. Use the --markdown flag for markdown table output. ```bash # Run with ASCII table output ./bench-austin.sh # Run with markdown table output ./bench-austin.sh --markdown # Get help ./bench-austin.sh --help ``` -------------------------------- ### Go Package AST Processing Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Processes MJML content step-by-step using the Go package API, involving parsing to AST, creating a component, and rendering. ```APIDOC ## Process MJML Step-by-Step (Go Package) ### Description Provides a step-by-step approach to processing MJML content using the Go package API. This involves parsing the MJML string into an Abstract Syntax Tree (AST), creating a component from the AST, and then rendering the component to HTML. ### Method Go Function Calls ### Endpoint 1. `parser.ParseMJML(mjmlContent string)` 2. `mjml.NewFromAST(ast *parser.MJMLNode)` 3. `mjml.RenderComponentString(component *mjml.Component)` ### Parameters #### Step 1: Parse MJML - **mjmlContent** (string) - Required - The MJML content as a string. #### Step 2: Create Component from AST - **ast** (*parser.MJMLNode) - Required - The AST node obtained from `parser.ParseMJML`. #### Step 3: Render Component - **component** (*mjml.Component) - Required - The component created from the AST. ### Request Example ```go ast, err := parser.ParseMJML(mjmlContent) component, err := mjml.NewFromAST(ast) html, err := mjml.RenderComponentString(component) ``` ### Response #### Success Response - **ast** (*parser.MJMLNode) - The Abstract Syntax Tree representation of the MJML content. - **component** (*mjml.Component) - The component representation of the MJML content. - **html** (string) - The rendered HTML content. - **err** (error) - An error if any step in the process fails. ``` -------------------------------- ### Go MJML Processing Pipeline Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Visualizes the data flow from MJML input to HTML output, including parsing, AST generation, component tree construction, and CSS processing. ```text MJML Input → XML Parser → AST → Component Tree → HTML Output ↓ ↓ ↓ Validation Attribute CSS Generation Processing & Email Compatibility ``` -------------------------------- ### CLI Compile Command Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Compiles MJML content to HTML using the command-line interface. Supports output to file or stdout, debug attributes, and caching. ```APIDOC ## Compile MJML to HTML ### Description Compiles MJML content to HTML. Supports output to a specified file or to standard output. Includes options for enabling debug attributes, AST caching for performance, and configuring cache TTL. ### Method CLI Command ### Endpoint `./bin/gomjml compile [input]` ### Parameters #### Path Parameters - **input** (string) - Required - Path to the MJML input file. #### Query Parameters - **-o, --output** (string) - Optional - Output file path for the generated HTML. - **-s, --stdout** (boolean) - Optional - If set, outputs the generated HTML to standard output instead of a file. - **--debug** (boolean) - Optional - If set, includes debug attributes for component traceability. Defaults to false. - **--cache** (boolean) - Optional - If set, enables AST caching for performance. Defaults to false. - **--cache-ttl** (string) - Optional - Configures the cache Time-To-Live duration. Defaults to 5m. - **--cache-cleanup-interval** (string) - Optional - Configures the cache cleanup interval. Defaults to `cache-ttl/2`. ### Request Example ```bash ./bin/gomjml compile input.mjml -o output.html --debug --cache --cache-ttl=10m ``` ### Response #### Success Response (HTML Output) - The compiled HTML content is either written to the specified output file or printed to standard output. ``` -------------------------------- ### Compile MJML with Debug Attributes using CLI Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Compile MJML and include debug attributes for component traceability in the output. ```bash # Include debug attributes for component traceability ./bin/gomjml compile input.mjml -s --debug ``` -------------------------------- ### Full MJML Integration Test Suite Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/mj-group-structure-mismatch.md Run the complete integration test suite for MJML against MRML. This is useful for a comprehensive verification of all components. ```bash go test ./mjml -run TestMJMLAgainstMRML -v ``` -------------------------------- ### MJML Test Case for Column Widths Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/column-width-precision-mismatch.md An MJML snippet demonstrating a 3-column section used to reproduce the column width precision mismatch issue. ```mjml 3 Col A 3 Col B 3 Col C ``` -------------------------------- ### Handle NotImplementedError for Components Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Implements the `NotImplementedError` pattern for components that are registered but not yet implemented. This ensures that the component is recognized but signals that its functionality is pending. ```go func (c *MJNewComponent) Render(w io.Writer) error { // TODO: Implement mj-new component functionality return &NotImplementedError{ComponentName: "mj-new"} } func (c *MJNewComponent) GetTagName() string { return "mj-new" } ``` -------------------------------- ### Register New Component in Factory Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Adds a new component to the component factory in `mjml/component.go` by associating the MJML tag name with its corresponding constructor function. This enables the parser to recognize and instantiate the new component. ```go case "mj-new": return components.NewMJNewComponent(node, opts), nil ``` -------------------------------- ### Iterating with Go Template in MJML Raw Source: https://github.com/preslavrachev/gomjml/blob/main/mjml/testdata/mj-raw-go-template.html This snippet demonstrates how to use a Go template to iterate over a collection (e.g., .Columns) and render each item within an MJML raw component. Ensure your data structure has a field named 'Columns'. ```mjml {{ range .Columns }} {{ . }} {{ end }} ``` -------------------------------- ### Create New MJML Component in Go Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Defines a new custom MJML component by creating its Go struct, constructor, and implementing the Render and GetTagName methods. This is the primary step for adding new components. ```go package components import ( "io" "strings" "github.com/preslavrachev/gomjml/mjml/options" "github.com/preslavrachev/gomjml/parser" ) type MJNewComponent struct { *BaseComponent } func NewMJNewComponent(node *parser.MJMLNode, opts *options.RenderOpts) *MJNewComponent { return &MJNewComponent{ BaseComponent: NewBaseComponent(node, opts), } } // Note: RenderString() is no longer part of the Component interface // Use mjml.RenderComponentString(component) helper function instead func (c *MJNewComponent) Render(w io.Writer) error { // Implementation here - write HTML directly to Writer // Use c.AddDebugAttribute(tag, "new") for debug traceability // Example implementation: // if _, err := w.Write([]byte("
Hello World
")); err != nil { // return err // } return nil } func (c *MJNewComponent) GetTagName() string { return "mj-new" } ``` -------------------------------- ### Compile MJML to HTML Source: https://github.com/preslavrachev/gomjml/blob/main/AGENTS.md Compiles an MJML input file to an HTML output file. Use the --debug flag to include debug attributes in the output. ```bash ./bin/gomjml compile input.mjml -o output.html ``` ```bash ./bin/gomjml compile input.mjml -o output.html --debug ``` -------------------------------- ### Configure AST Cache Cleanup Interval Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Set the interval at which the AST cache is cleaned up. This should be called only once. ```go // Set cleanup interval (call only once) mjml.SetASTCacheCleanupIntervalOnce(5 * time.Minute) ``` -------------------------------- ### Stop AST Cache Cleanup Source: https://github.com/preslavrachev/gomjml/blob/main/README.md Defer stopping the AST cache cleanup process. This is useful for graceful shutdown in long-running applications. ```go // For graceful shutdown in long-running applications (optional) // Not needed for CLI tools or short-lived processes defer mjml.StopASTCacheCleanup() ``` -------------------------------- ### Test MJML Against MRML Commands Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/group-vs-section-column-comparison.md Run these commands to test both section-with-columns and mj-group components against MRML after shared fixes are applied. Use diff to verify improvements. ```bash # Test both after shared fixes go test ./mjml -run TestMJMLAgainstMRML/mj-section-with-columns -v go test ./mjml -run TestMJMLAgainstMRML/mj-group -v # Verify improvements diff -u /tmp/mrml_section_columns.html /tmp/gomjml_section_columns.html diff -u /tmp/mrml_mj_group.html /tmp/gomjml_mj_group.html ``` -------------------------------- ### Standard Responsive Columns in MJML Section Source: https://github.com/preslavrachev/gomjml/blob/main/docs/columns-in-sections-columns-in-groups.md Use this pattern for standard email layouts where columns should stack responsively on mobile devices. MJML automatically handles breakpoints. ```xml Content 1 Content 2 ``` -------------------------------- ### MJML Stylesheet for Email Clients Source: https://github.com/preslavrachev/gomjml/blob/main/mjml/testdata/notifuse-full.html Contains essential styles for email clients, including resets and media queries for responsive design. Applied globally to ensure consistent rendering. ```css outlook a { padding:0; } body { margin:0;padding:0;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%; } table,td { border-collapse:collapse;mso-table-lspace:0pt;mso-table-rspace:0pt; } img { border:0;height:auto;line-height:100%; outline:none;text-decoration:none;-ms-interpolation-mode:bicubic; } p { display:block;margin:13px 0; } @media only screen and (min-width:480px) { .mj-column-per-100 { width:100% !important; max-width: 100%; } .mj-column-per-50 { width:50% !important; max-width: 50%; } } .moz-text-html .mj-column-per-100 { width:100% !important; max-width: 100%; } .moz-text-html .mj-column-per-50 { width:50% !important; max-width: 50%; } @media only screen and (max-width:479px) { table.mj-full-width-mobile { width: 100% !important; } td.mj-full-width-mobile { width: auto !important; } } ``` -------------------------------- ### MJML Test Case for Merging Conditionals Source: https://github.com/preslavrachev/gomjml/blob/main/docs/mj-spec.md A test case from MJML's codebase demonstrating the expected output when adjacent MSO conditional blocks are processed and merged. ```javascript { input: ` ``` -------------------------------- ### Social Media Links with Images Source: https://github.com/preslavrachev/gomjml/blob/main/mjml/testdata/notifuse-full.html Includes social media icons linked to respective platforms. Uses image components within links for interactive elements. ```mjml ``` -------------------------------- ### MJML with Valid
Source: https://github.com/preslavrachev/gomjml/blob/main/issues/done/mjml-text-render-html-as-is.md Demonstrates how a valid
tag within an component is preserved as-is in the rendered HTML output. ```mjml foo
bar
``` ```html
foo
bar
``` -------------------------------- ### MJML Raw HTML Block Source: https://github.com/preslavrachev/gomjml/blob/main/mjml/testdata/notifuse-full.html Shows how to embed custom HTML content directly within an MJML template using the 'mj-raw' component. Ideal for custom styling or complex structures. ```mjml This is custom HTML content from an mj-raw block!

Perfect for custom styling, special HTML structures, or advanced layouts.

```