Htmler

Htmler is Finch's Dart-based HTML builder. Instead of writing HTML in a .j2.html template file, you construct the page entirely in Dart code using a tree of Tag objects. Each Dart class corresponds to an HTML element ($Div, $P, $H1, etc.).

When to use Htmler:

  • You want to keep a small page or widget as a single Dart file with no external template.
  • You are generating dynamic HTML structures that are easier to express as Dart code than as template loops.
  • You want to build reusable UI components in Dart.

When to use Jinja templates instead:

  • For full pages with complex layouts — templates are more readable.
  • For production apps where designers or front-end developers also work on the HTML.

Htmler tags are rendered via rq.renderTag(tag: htmlTag).

Basic Example

Every Htmler tree starts with a $Cache (the root document fragment) and builds downward:

import 'package:finch/finch_htmler.dart';

class HtmlerController extends Controller {
  @override
  Future<String> index() async {
    rq.addParam('year', DateTime.now().year);

    Tag page = $Cache(children: [
      $Doctype(),
      $Html(
        attrs: {
          'lang': rq.getLanguage(),
          // JJ.$var() embeds a Jinja expression inside Htmler output
          'dir': JJ.$var(r'$t("dir")'),
        },
        children: [
          $Head(children: [
            $Meta(attrs: {'charset': 'UTF-8'}),
            $Title(children: [$Text('My App')]),
          ]),
          $Body(children: [
            $Div(
              attrs: {'class': 'container'},
              children: [
                $H1(children: [$Text('Hello from Htmler')]),
                $P(children: [
                  $Text('Current year: '),
                  $Text('{{ year }}'),  // Jinja variable
                ]),
              ],
            ),
          ]),
        ],
      ),
    ]);

    return rq.renderTag(tag: page);
  }
}

Available Tags

Htmler provides Dart classes for all standard HTML elements. The naming convention is $ + capitalised tag name:

Dart class HTML tag Dart class HTML tag
$Html <html> $Body <body>
$Head <head> $Header <header>
$Div <div> $Span <span>
$P <p> $A <a>
$H1$H6 <h1><h6> $Img <img>
$Form <form> $Input <input>
$Button <button> $Select <select>
$Table <table> $Tr <tr>
$Td <td> $Th <th>
$Ul <ul> $Li <li>
$Script <script> $Link <link>
$Style <style> $Meta <meta>
$Title <title> $Doctype <!DOCTYPE html>
$Raw raw string $Text text node
$Cache root fragment $Footer <footer>

Tag Constructor

All Tag classes accept the same parameters:

$Div(
  attrs: {'class': 'card', 'id': 'main'},   // HTML attributes
  children: [                                // Nested tags
    $P(children: [$Text('Hello')]),
  ],
)

Embedding Jinja in Htmler

The JJ class provides helpers to embed Jinja expressions inside Htmler-generated HTML. This is useful when you want Finch to process template variables at render time:

// Output a template variable: {{ year }}
$Text(JJ.$var('year'))

// Output a translation: {{ $t('welcome') }}
$Text(JJ.$var(r'$t("welcome")'))

// Output a raw Jinja block
$Raw(JJ.raw('{% for item in items %}...{% endfor %}'))

The JJ helpers insert the Jinja syntax as a literal string into the rendered HTML, which Finch then processes through the template engine.

Rendering

Use rq.renderTag(tag: myTag) to render an Htmler tree and return it as the HTTP response:

return rq.renderTag(tag: page);

This is the Htmler equivalent of rq.renderView(path: '...').

Tag htmlTag = $Cache(children: [
  $Doctype(),
  $Html(attrs: {
    'lang': rq.getLanguage(),
    'dir': JJ.$var('\$t("dir")'),
  }, children: [
    $Head(
      children: [
        $Meta(attrs: {'charset': 'UTF-8'}),
        $Meta(
          attrs: {
            'name': 'viewport',
            'content': 'width=device-width, initial-scale=1.0',
          },
        ),
        $Title(
            children: [$Text('Htmler Framework - Modern Web Development')]),
        $Link(attrs: {
          'href':
              'https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css',
          'rel': 'stylesheet',
          'integrity':
              'sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM',
          'crossorigin': 'anonymous'
        }),
        $Style(children: [
          $Raw('''
              @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
              
              :root {
                --md-primary: #E91E63;
                --md-primary-variant: #C2185B;
                --md-secondary: #FF4081;
                --md-secondary-variant: #F50057;
                --md-accent: #9C27B0;
                --md-accent-light: #E1BEE7;
                --md-background: #FAFAFA;
                --md-surface: #FFFFFF;
                --md-error: #F44336;
                --md-on-primary: #FFFFFF;
                --md-on-secondary: #FFFFFF;
                --md-on-background: #212121;
                --md-on-surface: #424242;
                --md-on-error: #FFFFFF;
                --md-text-primary: #212121;
                --md-text-secondary: #757575;
                --md-divider: #E0E0E0;
                --md-success: #4CAF50;
                --md-warning: #FF9800;
                --md-info: #2196F3;
                --google-play-pink: #E91E63;
                --google-play-purple: #9C27B0;
                --google-play-light-pink: #FCE4EC;
              }
              
              * {
                box-sizing: border-box;
              }
              
              body {
                font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
                line-height: 1.6;
                background-color: var(--md-background);
                color: var(--md-text-primary);
                margin: 0;
                padding: 0;
              }
              
              .hero-section {
                background-color: var(--md-primary);
                color: var(--md-on-primary);
                min-height: 80vh;
                display: flex;
                align-items: center;
                position: relative;
              }
              
              .hero-section::before {
                content: '';
                position: absolute;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"><defs><pattern id="grain" width="100" height="100" patternUnits="userSpaceOnUse"><circle cx="25" cy="25" r="1" fill="rgba(255,255,255,0.02)"/><circle cx="75" cy="75" r="1" fill="rgba(255,255,255,0.02)"/><circle cx="50" cy="10" r="0.5" fill="rgba(255,255,255,0.01)"/></pattern></defs><rect width="100" height="100" fill="url(%23grain)"/></svg>');
                pointer-events: none;
              }
              
              .hero-title {
                font-size: 3.5rem;
                font-weight: 700;
                letter-spacing: -0.02em;
                margin-bottom: 1rem;
                line-height: 1.1;
              }
              
              .hero-subtitle {
                font-size: 1.25rem;
                font-weight: 400;
                opacity: 0.9;
                margin-bottom: 2.5rem;
                max-width: 600px;
              }
              
              .section-title {
                font-size: 2.5rem;
                font-weight: 600;
                margin-bottom: 3rem;
                color: var(--md-text-primary);
                text-align: center;
                letter-spacing: -0.01em;
              }
              
              .card {
                background: var(--md-surface);
                border: none;
                border-radius: 12px;
                box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1), 0 1px 2px rgba(0, 0, 0, 0.06);
                transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
                overflow: hidden;
              }
              
              .card:hover {
                box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 2px 4px rgba(0, 0, 0, 0.06);
                transform: translateY(-2px);
              }
              
              .stat-card {
                background: var(--md-surface);
                border-radius: 16px;
                box-shadow: 0 2px 8px rgba(233, 30, 99, 0.15);
                backdrop-filter: blur(10px);
                border: 1px solid var(--google-play-light-pink);
              }
              
              .stat-number {
                font-size: 2.5rem;
                font-weight: 700;
                color: var(--md-primary);
              }
              
              .navbar-brand {
                font-weight: 600;
                font-size: 1.25rem;
              }
              
              .btn {
                border-radius: 8px;
                font-weight: 500;
                padding: 12px 24px;
                transition: all 0.2s ease;
                border: none;
                text-decoration: none;
                display: inline-flex;
                align-items: center;
                gap: 8px;
              }
              
              .btn-primary {
                background-color: var(--md-primary);
                color: var(--md-on-primary);
              }
              
              .btn-primary:hover {
                background-color: var(--md-primary-variant);
                transform: translateY(-1px);
              }
              
              .btn-outline-primary {
                background-color: transparent;
                border: 2px solid var(--md-primary);
                color: var(--md-primary);
              }
              
              .btn-outline-primary:hover {
                background-color: var(--md-primary);
                color: var(--md-on-primary);
              }
              
              .btn-light {
                background-color: var(--md-surface);
                color: var(--md-text-primary);
              }
              
              .btn-outline-light {
                background-color: transparent;
                border: 2px solid rgba(255, 255, 255, 0.3);
                color: var(--md-on-primary);
              }
              
              .btn-outline-light:hover {
                background-color: rgba(255, 255, 255, 0.1);
                border-color: rgba(255, 255, 255, 0.5);
              }
              
              .progress {
                height: 8px;
                background-color: var(--md-divider);
                border-radius: 4px;
                overflow: hidden;
              }
              
              .progress-bar {
                border-radius: 4px;
              }
              
              .table {
                border-radius: 8px;
                overflow: hidden;
                box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
              }
              
              .table th {
                background-color: var(--md-primary);
                color: var(--md-on-primary);
                font-weight: 600;
                border: none;
                padding: 16px;
              }
              
              .table td {
                vertical-align: middle;
                padding: 16px;
                border-color: var(--md-divider);
              }
              
              .form-control, .form-select {
                border: 2px solid var(--md-divider);
                border-radius: 8px;
                padding: 12px 16px;
                background-color: var(--md-surface);
                transition: border-color 0.2s ease;
              }
              
              .form-control:focus, .form-select:focus {
                border-color: var(--md-primary);
                box-shadow: 0 0 0 3px rgba(233, 30, 99, 0.1);
                outline: none;
              }
              
              .form-label {
                font-weight: 500;
                margin-bottom: 8px;
                color: var(--md-text-primary);
              }
              
              .alert {
                border: none;
                border-radius: 8px;
                padding: 16px;
                margin: 16px 0;
              }
              
              .alert-info {
                background-color: rgba(33, 150, 243, 0.1);
                color: var(--md-info);
                border-left: 4px solid var(--md-info);
              }
              
              .alert-success {
                background-color: rgba(76, 175, 80, 0.1);
                color: var(--md-success);
                border-left: 4px solid var(--md-success);
              }
              
              .code-block {
                background-color: #F5F5F5;
                border: 1px solid var(--md-divider);
                border-radius: 8px;
                padding: 20px;
                font-family: 'Fira Code', 'Consolas', 'Monaco', monospace;
                font-size: 14px;
                line-height: 1.5;
                overflow-x: auto;
              }
              
              .footer {
                background-color: var(--md-text-primary);
                color: var(--md-surface);
              }
              
              .footer a {
                color: rgba(255, 255, 255, 0.7);
                text-decoration: none;
                transition: color 0.2s ease;
              }
              
              .footer a:hover {
                color: var(--md-surface);
              }
              
              .container {
                max-width: 1200px;
              }
              
              .section {
                padding: 80px 0;
              }
              
              .card-title {
                color: var(--md-primary);
                font-weight: 600;
                font-size: 1.25rem;
              }
              
              .navbar {
                background-color: var(--md-surface) !important;
                box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
              }
              
              .navbar-dark .navbar-nav .nav-link {
                color: var(--md-text-primary);
              }
              
              .list-group-item {
                border-color: var(--md-divider);
                transition: background-color 0.2s ease;
              }
              
              .list-group-item:hover {
                background-color: rgba(233, 30, 99, 0.05);
              }
              
              .badge {
                font-weight: 500;
                padding: 6px 12px;
              }
              
              .bg-primary {
                background-color: var(--md-primary) !important;
              }
              
              .bg-secondary {
                background-color: var(--md-secondary) !important;
              }
              
              .bg-accent {
                background-color: var(--md-accent) !important;
              }
              
              .bg-success {
                background-color: var(--md-success) !important;
              }
              
              .text-primary {
                color: var(--md-primary) !important;
              }
              
              .text-secondary {
                color: var(--md-secondary) !important;
              }
              
              .text-accent {
                color: var(--md-accent) !important;
              }
              
              .text-muted {
                color: var(--md-text-secondary) !important;
              }
              
              .google-play-card {
                background: linear-gradient(45deg, var(--google-play-light-pink) 0%, #FFFFFF 50%);
                border-left: 4px solid var(--md-primary);
              }
              
              @media (max-width: 768px) {
                .hero-title {
                  font-size: 2.5rem;
                }
                
                .section-title {
                  font-size: 2rem;
                }
                
                .hero-section {
                  min-height: 60vh;
                  text-align: center;
                }
                
                .section {
                  padding: 40px 0;
                }
              }
            ''')
        ]),
      ],
    ),
    $Body(children: [
      // Hero Section
      $Section(attrs: {
        'class': 'hero-section'
      }, children: [
        $Div(attrs: {
          'class': 'container'
        }, children: [
          $Div(attrs: {
            'class': 'row align-items-center min-vh-100'
          }, children: [
            $Div(attrs: {
              'class': 'col-lg-6 mb-5 mb-lg-0'
            }, children: [
              $H1(
                  attrs: {'class': 'hero-title'},
                  children: [$Text('Htmler Framework')]),
              $P(attrs: {
                'class': 'hero-subtitle'
              }, children: [
                $Text(
                    'Build modern web applications with type-safe HTML generation. Clean, efficient, and developer-friendly.')
              ]),
              $Div(attrs: {
                'class': 'd-flex gap-3 flex-wrap'
              }, children: [
                $Button(
                        attrs: {'class': 'btn btn-light'},
                        children: [$Text('Get Started')])
                    .addAttr('data-language', JJ.$var('language')),
                $Button(
                    attrs: {'class': 'btn btn-outline-light'},
                    children: [$Text('Documentation')]),
              ]),
            ]),
            $Div(attrs: {
              'class': 'col-lg-6'
            }, children: [
              $Div(attrs: {
                'class': 'row g-4'
              }, children: [
                $Div(attrs: {
                  'class': 'col-6'
                }, children: [
                  $Div(attrs: {
                    'class': 'stat-card p-4 text-center'
                  }, children: [
                    $Div(
                        attrs: {'class': 'stat-number'},
                        children: [$Text('40+')]),
                    $P(
                        attrs: {'class': 'text-muted mb-0 small'},
                        children: [$Text('HTML Tags')]),
                  ]),
                ]),
                $Div(attrs: {
                  'class': 'col-6'
                }, children: [
                  $Div(attrs: {
                    'class': 'stat-card p-4 text-center'
                  }, children: [
                    $Div(
                        attrs: {'class': 'stat-number'},
                        children: [$Text('100%')]),
                    $P(
                        attrs: {'class': 'text-muted mb-0 small'},
                        children: [$Text('Type Safe')]),
                  ]),
                ]),
                $Div(attrs: {
                  'class': 'col-6'
                }, children: [
                  $Div(attrs: {
                    'class': 'stat-card p-4 text-center'
                  }, children: [
                    $Div(
                        attrs: {'class': 'stat-number'},
                        children: [$Text('0')]),
                    $P(
                        attrs: {'class': 'text-muted mb-0 small'},
                        children: [$Text('Dependencies')]),
                  ]),
                ]),
                $Div(attrs: {
                  'class': 'col-6'
                }, children: [
                  $Div(attrs: {
                    'class': 'stat-card p-4 text-center'
                  }, children: [
                    $Div(
                        attrs: {'class': 'stat-number'},
                        children: [$Text('∞')]),
                    $P(
                        attrs: {'class': 'text-muted mb-0 small'},
                        children: [$Text('Possibilities')]),
                  ]),
                ]),
              ]),
            ]),
          ]),
        ]),
      ]),

      // Navigation
      $Nav(attrs: {
        'class': 'navbar navbar-expand-lg sticky-top'
      }, children: [
        $Div(attrs: {
          'class': 'container'
        }, children: [
          $A(attrs: {
            'class': 'navbar-brand text-primary fw-bold',
            'href': '#'
          }, children: [
            $Text('Htmler')
          ]),
          $Button(attrs: {
            'class': 'navbar-toggler',
            'type': 'button',
            'data-bs-toggle': 'collapse',
            'data-bs-target': '#navbarNav'
          }, children: [
            $Span(attrs: {'class': 'navbar-toggler-icon'}, children: []),
          ]),
          $Div(attrs: {
            'class': 'collapse navbar-collapse',
            'id': 'navbarNav'
          }, children: [
            $Ul(attrs: {
              'class': 'navbar-nav ms-auto'
            }, children: [
              $Li(attrs: {
                'class': 'nav-item'
              }, children: [
                $A(attrs: {
                  'class': 'nav-link fw-medium',
                  'href': '#typography'
                }, children: [
                  $Text('Typography')
                ]),
              ]),
              $Li(attrs: {
                'class': 'nav-item'
              }, children: [
                $A(attrs: {
                  'class': 'nav-link fw-medium',
                  'href': '#forms'
                }, children: [
                  $Text('Forms')
                ]),
              ]),
              $Li(attrs: {
                'class': 'nav-item'
              }, children: [
                $A(attrs: {
                  'class': 'nav-link fw-medium',
                  'href': '#tables'
                }, children: [
                  $Text('Tables')
                ]),
              ]),
              $Li(attrs: {
                'class': 'nav-item'
              }, children: [
                $A(attrs: {
                  'class': 'nav-link fw-medium',
                  'href': '#media'
                }, children: [
                  $Text('Media')
                ]),
              ]),
            ]),
          ]),
        ]),
      ]),

      // Main Content
      $Main(attrs: {
        'class': 'section'
      }, children: [
        $Div(attrs: {
          'class': 'container'
        }, children: [
          // Typography Section
          $Section(attrs: {
            'id': 'typography',
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Typography Elements')]),
            $Div(attrs: {
              'class': 'row g-4'
            }, children: [
              $Div(attrs: {
                'class': 'col-lg-4'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Headings Hierarchy')]),
                    $H1(
                        attrs: {'class': 'h3 mb-2'},
                        children: [$Text('H1 - Main Title')]),
                    $H2(
                        attrs: {'class': 'h4 mb-2'},
                        children: [$Text('H2 - Section Title')]),
                    $H3(
                        attrs: {'class': 'h5 mb-2'},
                        children: [$Text('H3 - Subsection')]),
                    $H4(
                        attrs: {'class': 'h6 mb-2'},
                        children: [$Text('H4 - Minor Heading')]),
                    $H5(
                        attrs: {'class': 'small mb-2'},
                        children: [$Text('H5 - Small Heading')]),
                    $H6(
                        attrs: {'class': 'small mb-3'},
                        children: [$Text('H6 - Smallest Heading')]),
                    $Hr(),
                    $Small(attrs: {
                      'class': 'text-muted'
                    }, children: [
                      $Text(
                          'Perfect semantic hierarchy for SEO and accessibility')
                    ]),
                  ]),
                ]),
              ]),
              $Div(attrs: {
                'class': 'col-lg-4'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Text Formatting')]),
                    $P(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Text('This paragraph demonstrates '),
                      $B(children: [$Text('bold text')]),
                      $Text(', '),
                      $I(children: [$Text('italic text')]),
                      $Text(', and '),
                      $U(children: [$Text('underlined text')]),
                      $Text(' formatting options.'),
                    ]),
                    $P(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Text('You can also combine them: '),
                      $B(children: [
                        $I(children: [$Text('bold italic')])
                      ]),
                      $Text(' or '),
                      $U(children: [
                        $B(children: [$Text('underlined bold')])
                      ]),
                      $Text(' text.'),
                    ]),
                    $P(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Text('Inline code example: '),
                      $Code(attrs: {
                        'class': 'bg-light p-1 rounded'
                      }, children: [
                        $Text('const result = htmler.render()')
                      ]),
                      $Text(' within a paragraph.'),
                    ]),
                    $Small(attrs: {
                      'class': 'text-muted'
                    }, children: [
                      $Text(
                          'This is small text that provides additional context or footnotes.')
                    ]),
                  ]),
                ]),
              ]),
              $Div(attrs: {
                'class': 'col-lg-4'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Advanced Typography')]),
                    $P(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Text('Modern web typography with '),
                      $Span(
                          attrs: {'class': 'text-accent fw-bold'},
                          children: [$Text('styled text effects')]),
                      $Text(' and beautiful spacing.'),
                    ]),
                    $P(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Text('Use '),
                      $Code(children: [$Text('\$Span')]),
                      $Text(' with custom styles for '),
                      $Span(
                          attrs: {'class': 'badge bg-secondary text-white'},
                          children: [$Text('highlighted text')]),
                      $Text(' or '),
                      $Span(attrs: {
                        'class':
                            'border border-primary text-primary px-2 py-1 rounded'
                      }, children: [
                        $Text('outlined badges')
                      ]),
                      $Text('.'),
                    ]),
                    $P(children: [
                      $Text('Typography is the '),
                      $B(children: [$Text('foundation')]),
                      $Text(' of great web design.'),
                    ]),
                  ]),
                ]),
              ]),
            ]),
            $Div(attrs: {
              'class': 'alert alert-info mt-4'
            }, children: [
              $P(attrs: {
                'class': 'mb-0'
              }, children: [
                $B(children: [$Text('Pro Tip:')]),
                $Text(
                    ' All these typography elements are created using Htmler tags, providing type-safe HTML generation with excellent IntelliSense support in your IDE!')
              ]),
            ]),
          ]),

          // Lists Section
          $Section(attrs: {
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Lists & Navigation')]),
            $Div(attrs: {
              'class': 'row g-4'
            }, children: [
              $Div(attrs: {
                'class': 'col-lg-6'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Unordered List')]),
                    $Ul(attrs: {
                      'class': 'list-group list-group-flush'
                    }, children: [
                      $Li(attrs: {
                        'class':
                            'list-group-item d-flex justify-content-between align-items-center'
                      }, children: [
                        $Text('First item'),
                        $Span(attrs: {
                          'class': 'badge bg-primary rounded-pill'
                        }, children: [
                          $Text('1')
                        ])
                      ]),
                      $Li(attrs: {
                        'class':
                            'list-group-item d-flex justify-content-between align-items-center'
                      }, children: [
                        $Text('Second item'),
                        $Span(attrs: {
                          'class': 'badge bg-primary rounded-pill'
                        }, children: [
                          $Text('2')
                        ])
                      ]),
                      $Li(attrs: {
                        'class':
                            'list-group-item d-flex justify-content-between align-items-center'
                      }, children: [
                        $Text('Third item'),
                        $Span(attrs: {
                          'class':
                              'badge bg-secondary rounded-pill text-white'
                        }, children: [
                          $Text('NEW')
                        ])
                      ]),
                      $Li(attrs: {
                        'class':
                            'list-group-item d-flex justify-content-between align-items-center'
                      }, children: [
                        $Text('Fourth item'),
                        $Span(attrs: {
                          'class': 'badge bg-primary rounded-pill'
                        }, children: [
                          $Text('4')
                        ])
                      ]),
                    ]),
                  ]),
                ]),
              ]),
              $Div(attrs: {
                'class': 'col-lg-6'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Ordered List')]),
                    $Ol(attrs: {
                      'class': 'list-group list-group-numbered'
                    }, children: [
                      $Li(
                          attrs: {'class': 'list-group-item'},
                          children: [$Text('Setup your environment')]),
                      $Li(
                          attrs: {'class': 'list-group-item'},
                          children: [$Text('Import Htmler library')]),
                      $Li(
                          attrs: {'class': 'list-group-item'},
                          children: [$Text('Create your tags')]),
                      $Li(
                          attrs: {'class': 'list-group-item'},
                          children: [$Text('Render beautiful HTML')]),
                    ]),
                  ]),
                ]),
              ]),
            ]),
          ]),

          // Forms Section
          $Section(attrs: {
            'id': 'forms',
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Interactive Form Elements')]),
            $Form(attrs: {
              'method': 'post',
              'action': '#'
            }, children: [
              $Div(attrs: {
                'class': 'row g-4'
              }, children: [
                $Div(attrs: {
                  'class': 'col-lg-4'
                }, children: [
                  $Div(attrs: {
                    'class': 'card h-100'
                  }, children: [
                    $Div(attrs: {
                      'class': 'card-body'
                    }, children: [
                      $H5(
                          attrs: {'class': 'card-title text-primary mb-4'},
                          children: [$Text('User Information')]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(
                            attrs: {'for': 'name', 'class': 'form-label'},
                            children: [$Text('Full Name')]),
                        $Input(attrs: {
                          'type': 'text',
                          'class': 'form-control',
                          'id': 'name',
                          'name': 'name',
                          'placeholder': 'Enter your full name',
                          'required': 'true',
                        }),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(
                            attrs: {'for': 'email', 'class': 'form-label'},
                            children: [$Text('Email Address')]),
                        $Input(attrs: {
                          'type': 'email',
                          'class': 'form-control',
                          'id': 'email',
                          'name': 'email',
                          'placeholder': '[email protected]',
                          'required': 'true',
                        }),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'password',
                          'class': 'form-label'
                        }, children: [
                          $Text('Password')
                        ]),
                        $Input(attrs: {
                          'type': 'password',
                          'class': 'form-control',
                          'id': 'password',
                          'name': 'password',
                          'placeholder': 'Enter secure password',
                          'required': 'true',
                        }),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(
                            attrs: {'for': 'phone', 'class': 'form-label'},
                            children: [$Text('Phone Number')]),
                        $Input(attrs: {
                          'type': 'tel',
                          'class': 'form-control',
                          'id': 'phone',
                          'name': 'phone',
                          'placeholder': '+1 (555) 123-4567',
                        }),
                      ]),
                    ]),
                  ]),
                ]),
                $Div(attrs: {
                  'class': 'col-lg-4'
                }, children: [
                  $Div(attrs: {
                    'class': 'card h-100'
                  }, children: [
                    $Div(attrs: {
                      'class': 'card-body'
                    }, children: [
                      $H5(
                          attrs: {'class': 'card-title text-primary mb-4'},
                          children: [$Text('Preferences')]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'country',
                          'class': 'form-label'
                        }, children: [
                          $Text('Country')
                        ]),
                        $Select(attrs: {
                          'class': 'form-select',
                          'id': 'country',
                          'name': 'country'
                        }, children: [
                          $Option(
                              attrs: {'value': ''},
                              children: [$Text('Select your country')]),
                          $Option(
                              attrs: {'value': 'us'},
                              children: [$Text('United States')]),
                          $Option(
                              attrs: {'value': 'ca'},
                              children: [$Text('Canada')]),
                          $Option(
                              attrs: {'value': 'uk'},
                              children: [$Text('United Kingdom')]),
                          $Option(
                              attrs: {'value': 'de'},
                              children: [$Text('Germany')]),
                        ]),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'interests',
                          'class': 'form-label'
                        }, children: [
                          $Text('Interests')
                        ]),
                        $Select(attrs: {
                          'class': 'form-select',
                          'id': 'interests',
                          'name': 'interests',
                          'multiple': 'true',
                          'size': '4',
                        }, children: [
                          $Option(
                              attrs: {'value': 'web-dev'},
                              children: [$Text('Web Development')]),
                          $Option(
                              attrs: {'value': 'mobile-dev'},
                              children: [$Text('Mobile Development')]),
                          $Option(
                              attrs: {'value': 'design'},
                              children: [$Text('UI/UX Design')]),
                          $Option(
                              attrs: {'value': 'data-science'},
                              children: [$Text('Data Science')]),
                        ]),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'message',
                          'class': 'form-label'
                        }, children: [
                          $Text('Tell us about yourself')
                        ]),
                        $TextArea(attrs: {
                          'class': 'form-control',
                          'id': 'message',
                          'name': 'message',
                          'rows': '3',
                          'placeholder':
                              'Share your experience, goals, or anything you\'d like us to know...',
                        }, children: []),
                      ]),
                    ]),
                  ]),
                ]),
                $Div(attrs: {
                  'class': 'col-lg-4'
                }, children: [
                  $Div(attrs: {
                    'class': 'card h-100'
                  }, children: [
                    $Div(attrs: {
                      'class': 'card-body'
                    }, children: [
                      $H5(
                          attrs: {'class': 'card-title text-primary mb-4'},
                          children: [$Text('Additional Options')]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'birthdate',
                          'class': 'form-label'
                        }, children: [
                          $Text('Birth Date')
                        ]),
                        $Input(attrs: {
                          'type': 'date',
                          'class': 'form-control',
                          'id': 'birthdate',
                          'name': 'birthdate',
                        }),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'website',
                          'class': 'form-label'
                        }, children: [
                          $Text('Website URL')
                        ]),
                        $Input(attrs: {
                          'type': 'url',
                          'class': 'form-control',
                          'id': 'website',
                          'name': 'website',
                          'placeholder': 'https://yourwebsite.com',
                        }),
                      ]),
                      $Div(attrs: {
                        'class': 'mb-3'
                      }, children: [
                        $Label(attrs: {
                          'for': 'experience',
                          'class': 'form-label'
                        }, children: [
                          $Text('Years of Experience: '),
                          $Span(
                              attrs: {'id': 'experienceValue'},
                              children: [$Text('5')])
                        ]),
                        $Input(attrs: {
                          'type': 'range',
                          'class': 'form-range',
                          'id': 'experience',
                          'name': 'experience',
                          'min': '0',
                          'max': '20',
                          'value': '5',
                        }),
                      ]),
                      $Div(attrs: {
                        'class': 'form-check mb-3'
                      }, children: [
                        $Input(attrs: {
                          'type': 'checkbox',
                          'class': 'form-check-input',
                          'id': 'newsletter',
                          'name': 'newsletter',
                        }),
                        $Label(attrs: {
                          'for': 'newsletter',
                          'class': 'form-check-label'
                        }, children: [
                          $Text('Subscribe to our newsletter')
                        ]),
                      ]),
                      $Div(attrs: {
                        'class': 'form-check mb-4'
                      }, children: [
                        $Input(attrs: {
                          'type': 'checkbox',
                          'class': 'form-check-input',
                          'id': 'terms',
                          'name': 'terms',
                          'required': 'true',
                        }),
                        $Label(attrs: {
                          'for': 'terms',
                          'class': 'form-check-label'
                        }, children: [
                          $Text('I agree to the '),
                          $A(attrs: {
                            'href': '#',
                            'class': 'text-decoration-none'
                          }, children: [
                            $Text('Terms of Service')
                          ]),
                        ]),
                      ]),
                      $Div(attrs: {
                        'class': 'd-grid gap-2'
                      }, children: [
                        $Button(attrs: {
                          'type': 'submit',
                          'class': 'btn btn-primary'
                        }, children: [
                          $Text('Submit Form')
                        ]),
                        $Button(attrs: {
                          'type': 'reset',
                          'class': 'btn btn-outline-secondary'
                        }, children: [
                          $Text('Reset Form')
                        ]),
                      ]),
                    ]),
                  ]),
                ]),
              ]),
            ]),
            $Div(attrs: {
              'class': 'alert alert-info mt-4'
            }, children: [
              $P(attrs: {
                'class': 'mb-0'
              }, children: [
                $B(children: [$Text('Form Validation:')]),
                $Text(
                    ' This form showcases various HTML5 input types with built-in validation: '),
                $Code(children: [$Text('email')]),
                $Text(', '),
                $Code(children: [$Text('url')]),
                $Text(', '),
                $Code(children: [$Text('tel')]),
                $Text(', '),
                $Code(children: [$Text('date')]),
                $Text(', '),
                $Code(children: [$Text('range')]),
                $Text(', and '),
                $Code(children: [$Text('required')]),
                $Text(' attributes.')
              ]),
            ]),
          ]),

          // Tables Section
          $Section(attrs: {
            'id': 'tables',
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Table Elements')]),
            $Div(attrs: {
              'class': 'card'
            }, children: [
              $Div(attrs: {
                'class': 'card-body'
              }, children: [
                $H5(attrs: {
                  'class': 'card-title text-primary mb-4'
                }, children: [
                  $Text('Popular Programming Languages (2024)')
                ]),
                $Div(attrs: {
                  'class': 'table-responsive'
                }, children: [
                  $Table(attrs: {
                    'class': 'table table-striped table-hover'
                  }, children: [
                    $Thead(children: [
                      $Tr(children: [
                        $Th(
                            attrs: {'scope': 'col'},
                            children: [$Text('Rank')]),
                        $Th(
                            attrs: {'scope': 'col'},
                            children: [$Text('Language')]),
                        $Th(
                            attrs: {'scope': 'col'},
                            children: [$Text('Popularity %')]),
                        $Th(
                            attrs: {'scope': 'col'},
                            children: [$Text('Primary Use')]),
                        $Th(
                            attrs: {'scope': 'col'},
                            children: [$Text('Year Created')]),
                      ]),
                    ]),
                    $Tbody(children: [
                      $Tr(children: [
                        $Td(children: [
                          $Span(
                              attrs: {'class': 'badge bg-primary'},
                              children: [$Text('1')])
                        ]),
                        $Td(children: [
                          $B(children: [$Text('JavaScript')])
                        ]),
                        $Td(children: [$Text('69.7%')]),
                        $Td(children: [$Text('Web Development')]),
                        $Td(children: [$Text('1995')]),
                      ]),
                      $Tr(children: [
                        $Td(children: [
                          $Span(
                              attrs: {'class': 'badge bg-primary'},
                              children: [$Text('2')])
                        ]),
                        $Td(children: [
                          $B(children: [$Text('Python')])
                        ]),
                        $Td(children: [$Text('51.8%')]),
                        $Td(children: [$Text('Data Science, AI')]),
                        $Td(children: [$Text('1991')]),
                      ]),
                      $Tr(children: [
                        $Td(children: [
                          $Span(
                              attrs: {'class': 'badge bg-primary'},
                              children: [$Text('3')])
                        ]),
                        $Td(children: [
                          $B(children: [$Text('Dart')])
                        ]),
                        $Td(children: [$Text('6.02%')]),
                        $Td(children: [$Text('Flutter, Web Apps')]),
                        $Td(children: [$Text('2011')]),
                      ]),
                      $Tr(children: [
                        $Td(children: [
                          $Span(
                              attrs: {'class': 'badge bg-primary'},
                              children: [$Text('4')])
                        ]),
                        $Td(children: [
                          $B(children: [$Text('Java')])
                        ]),
                        $Td(children: [$Text('40.2%')]),
                        $Td(children: [$Text('Enterprise, Android')]),
                        $Td(children: [$Text('1995')]),
                      ]),
                    ]),
                  ]),
                ]),
                $Small(attrs: {
                  'class': 'text-muted'
                }, children: [
                  $I(children: [
                    $Text(
                        'Data source: Stack Overflow Developer Survey 2024')
                  ]),
                ]),
              ]),
            ]),
          ]),

          // Media Section
          $Section(attrs: {
            'id': 'media',
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Media & Visual Elements')]),
            $Div(attrs: {
              'class': 'row g-4'
            }, children: [
              $Div(attrs: {
                'class': 'col-lg-4'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Progress Indicators')]),
                    $Div(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Label(
                          attrs: {'class': 'form-label small'},
                          children: [$Text('HTML Skills')]),
                      $Div(attrs: {
                        'class': 'progress'
                      }, children: [
                        $Div(attrs: {
                          'class': 'progress-bar bg-primary',
                          'role': 'progressbar',
                          'style': 'width: 90%',
                          'aria-valuenow': '90',
                          'aria-valuemin': '0',
                          'aria-valuemax': '100'
                        }, children: [
                          $Text('90%')
                        ]),
                      ]),
                    ]),
                    $Div(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Label(
                          attrs: {'class': 'form-label small'},
                          children: [$Text('CSS Skills')]),
                      $Div(attrs: {
                        'class': 'progress'
                      }, children: [
                        $Div(attrs: {
                          'class': 'progress-bar bg-success',
                          'role': 'progressbar',
                          'style': 'width: 85%',
                          'aria-valuenow': '85',
                          'aria-valuemin': '0',
                          'aria-valuemax': '100'
                        }, children: [
                          $Text('85%')
                        ]),
                      ]),
                    ]),
                    $Div(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Label(
                          attrs: {'class': 'form-label small'},
                          children: [$Text('Dart Skills')]),
                      $Div(attrs: {
                        'class': 'progress'
                      }, children: [
                        $Div(attrs: {
                          'class': 'progress-bar bg-warning',
                          'role': 'progressbar',
                          'style': 'width: 95%',
                          'aria-valuenow': '95',
                          'aria-valuemin': '0',
                          'aria-valuemax': '100'
                        }, children: [
                          $Text('95%')
                        ]),
                      ]),
                    ]),
                  ]),
                ]),
              ]),
              $Div(attrs: {
                'class': 'col-lg-8'
              }, children: [
                $Div(attrs: {
                  'class': 'card h-100'
                }, children: [
                  $Div(attrs: {
                    'class': 'card-body'
                  }, children: [
                    $H5(
                        attrs: {'class': 'card-title text-primary mb-4'},
                        children: [$Text('Interactive Elements')]),
                    $Details(attrs: {
                      'class': 'mb-3'
                    }, children: [
                      $Summary(
                          attrs: {'class': 'btn btn-outline-primary'},
                          children: [$Text('Click to expand details')]),
                      $Div(attrs: {
                        'class': 'mt-3 p-3 bg-light rounded'
                      }, children: [
                        $P(children: [
                          $Text(
                              'This content is hidden by default and can be toggled using the '),
                          $Code(children: [$Text('\$Details')]),
                          $Text(' and '),
                          $Code(children: [$Text('\$Summary')]),
                          $Text(
                              ' tags. It\'s perfect for FAQs, documentation, and collapsible content.'),
                        ]),
                        $Ul(attrs: {
                          'class': 'list-unstyled'
                        }, children: [
                          $Li(attrs: {
                            'class': 'mb-1'
                          }, children: [
                            $Span(
                                attrs: {'class': 'text-success me-2'},
                                children: [$Text('✓')]),
                            $Text('Semantic HTML')
                          ]),
                          $Li(attrs: {
                            'class': 'mb-1'
                          }, children: [
                            $Span(
                                attrs: {'class': 'text-success me-2'},
                                children: [$Text('✓')]),
                            $Text('Accessible by default')
                          ]),
                          $Li(attrs: {
                            'class': 'mb-1'
                          }, children: [
                            $Span(
                                attrs: {'class': 'text-success me-2'},
                                children: [$Text('✓')]),
                            $Text('No JavaScript required')
                          ]),
                        ]),
                      ]),
                    ]),
                  ]),
                ]),
              ]),
            ]),
          ]),

          // Code Examples Section
          $Section(attrs: {
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Code Examples')]),
            $Div(attrs: {
              'class': 'card'
            }, children: [
              $Div(attrs: {
                'class': 'card-body'
              }, children: [
                $H5(
                    attrs: {'class': 'card-title text-primary mb-4'},
                    children: [$Text('Htmler Usage Example')]),
                $P(children: [
                  $Text(
                      'Here\'s how you can create elements using Htmler tags:'),
                ]),
                $Div(attrs: {
                  'class': 'code-block'
                }, children: [
                  $Code(children: [
                    $Text('''// Creating a button with Htmler

$Button(attrs: { 'type': 'submit', 'class': 'btn btn-primary', }, children: [ $Text('Click me!') ])

// Creating a card layout $Div(attrs: {'class': 'card'}, children: [ $Div(attrs: {'class': 'card-body'}, children: [ $H5(attrs: {'class': 'card-title'}, children: [ $Text('Card Title') ]), $P(attrs: {'class': 'card-text'}, children: [ $Text('Card content goes here...') ]), ]), ])'''), ]), ]), ]), ]), ]),

          // Jinja Integration Section
          $Section(attrs: {
            'class': 'mb-5'
          }, children: [
            $H2(
                attrs: {'class': 'section-title'},
                children: [$Text('Jinja Integration')]),
            $Div(attrs: {
              'class': 'card'
            }, children: [
              $Div(attrs: {
                'class': 'card-body'
              }, children: [
                $H5(
                    attrs: {'class': 'card-title text-primary mb-4'},
                    children: [$Text('Dynamic Content with Jinja')]),
                $P(children: [
                  $Text('Current language: '),
                  $B(children: [JJ.$var('language')]),
                ]),
                $P(children: [
                  $Text('Current year: '),
                  $B(children: [JJ.$var('year')]),
                ]),
                $Hr(),
                $H6(children: [$Text('Conditional Rendering')]),
                JJ.$if('user', then: [
                  $Div(attrs: {
                    'class': 'alert alert-success'
                  }, children: [
                    $Text('Welcome back, '),
                    $B(children: [JJ.$var('user.name')]),
                    $Text('!'),
                  ]),
                ], otherwise: [
                  $Div(attrs: {
                    'class': 'alert alert-info'
                  }, children: [
                    $Text('Please '),
                    $A(
                        attrs: {'href': '/login', 'class': 'alert-link'},
                        children: [$Text('log in')]),
                    $Text(' to continue.'),
                  ]),
                ]),
              ]),
            ]),
          ]),
        ]),
      ]),

      // Footer
      $Footer(attrs: {
        'class': 'footer py-5'
      }, children: [
        $Div(attrs: {
          'class': 'container'
        }, children: [
          $Div(attrs: {
            'class': 'row'
          }, children: [
            $Div(attrs: {
              'class': 'col-lg-8 mx-auto text-center'
            }, children: [
              $H3(
                  attrs: {'class': 'text-white mb-4'},
                  children: [$Text('Htmler Framework')]),
              $P(attrs: {
                'class': 'mb-4 text-white-50'
              }, children: [
                $Text('Building the future of web development with '),
                $Span(
                    attrs: {'class': 'text-white fw-medium'},
                    children: [$Text('Dart Finch Framework')]),
                $Text(' & '),
                $Span(
                    attrs: {'class': 'text-white fw-medium'},
                    children: [$Text('Htmler Library')]),
              ]),
              $Div(attrs: {
                'class':
                    'd-flex gap-3 justify-content-center flex-wrap mb-4'
              }, children: [
                $A(attrs: {
                  'href': '#',
                  'class': 'btn btn-outline-light btn-sm'
                }, children: [
                  $Text('Documentation')
                ]),
                $A(attrs: {
                  'href': '#',
                  'class': 'btn btn-outline-light btn-sm'
                }, children: [
                  $Text('GitHub')
                ]),
                $A(attrs: {
                  'href': '#',
                  'class': 'btn btn-outline-light btn-sm'
                }, children: [
                  $Text('Community')
                ]),
              ]),
              $Hr(attrs: {'class': 'my-4 border-secondary'}),
              $P(attrs: {
                'class': 'small text-white-50 mb-0'
              }, children: [
                $Text(
                    '© ${DateTime.now().year} Finch Framework. Made with ❤️ for developers.'),
              ]),
            ]),
          ]),
        ]),
      ]),

      // Bootstrap JavaScript
      $Script(attrs: {
        'src':
            'https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js',
        'integrity':
            'sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz',
        'crossorigin': 'anonymous'
      }, children: []),

      // Additional JavaScript for interactivity
      $Script(children: [
        $Raw('''
            document.addEventListener('DOMContentLoaded', function() {
              // Range input update
              const experienceRange = document.getElementById('experience');
              const experienceValue = document.getElementById('experienceValue');
              if (experienceRange && experienceValue) {
                experienceRange.addEventListener('input', function() {
                  experienceValue.textContent = this.value;
                });
              }
            });
          ''')
      ]),

      // Comment for demonstration
      $Comment($Text(
          'This professional HTML was generated entirely using Htmler tags with Bootstrap 5.3!')),
    ]),
  ])
]);

return rq.renderTag(tag: htmlTag, pretty: false);

} }