Skip to content

AppML Templates — Customizing HTML Output with Themes and Layouts

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you will learn about AppML Templates. We cover key concepts, practical examples, and best practices to help you master this topic.

AppML templates let you override the default HTML output with custom layouts, branding, and styling, turning generated data interfaces into polished, branded applications.

What You'll Learn

You will create custom templates for AppML views, override default layouts, apply CSS themes, and build a consistent brand experience across your generated applications.

Why It Matters

Default AppML views are functional but generic. Custom templates let you match your brand colors, layout, and component styles while keeping the automatic data binding and CRUD functionality.

Real-World Use

DodaZIP's configuration portal uses custom AppML templates styled to match the Durga Antivirus Pro design system. Users cannot tell the AppML-generated pages are running on a different framework.

flowchart LR
    A[AppML View] --> B{Template Resolver}
    B --> C[Custom Template]
    B --> D[Default Template]
    C --> E[Branded HTML]
    D --> F[Standard HTML]
    style A fill:#1e293b,color:#fff
    style C fill:#0f172a,color:#fff

Template Directory Structure

Custom templates are stored in the templates directory of your AppML installation.

templates/
  default/
    list.html
    detail.html
    grid.html
    form.html
  custom/
    list.html
    detail.html
  my-theme/
    list.html
    detail.html

Each template is an HTML file with placeholders where AppML injects data.

Custom List View Template

Create a custom template for list views with a header and custom table structure.

<div class="appml-list">
  <div class="list-header">
    <h2>{{view.title}}</h2>
    <div class="list-actions">
      {{search}}
      {{add_button}}
    </div>
  </div>
  <table class="data-table">
    <thead>
      <tr>
        {% for column in columns %}
        <th>{{column.header}}</th>
        {% endfor %}
        <th>Actions</th>
      </tr>
    </thead>
    <tbody>
      {% for row in rows %}
      <tr>
        {% for column in columns %}
        <td>{{row[column.field]}}</td>
        {% endfor %}
        <td class="actions">
          {{row.edit_button}}
          {{row.delete_button}}
        </td>
      </tr>
      {% endfor %}
    </tbody>
  </table>
  {{pagination}}
</div>

Expected output: A custom-styled data table with a branded header, search bar, and action buttons.

Reference the custom template in the view definition:

<view type="list" table="employees" template="custom/list.html">
  ...
</view>

Custom Detail View Template

Create a two-column form layout for detail views.

<div class="appml-detail">
  <h2>{{view.title}}</h2>
  <form class="two-column-form" method="post">
    <div class="form-column">
      {% for field in fields[:half] %}
      <div class="form-group">
        <label>{{field.label}}</label>
        {{field.input}}
        {{field.error}}
      </div>
      {% endfor %}
    </div>
    <div class="form-column">
      {% for field in fields[half:] %}
      <div class="form-group">
        <label>{{field.label}}</label>
        {{field.input}}
        {{field.error}}
      </div>
      {% endfor %}
    </div>
    <div class="form-actions">
      {{save_button}}
      {{cancel_button}}
    </div>
  </form>
</div>

Expected output: A two-column form layout with evenly distributed fields.

Global Theme Template

Override the default layout wrapper for consistent branding across all views.

<!DOCTYPE html>
<html>
<head>
  <title>{{page.title}} - DodaTech Admin</title>
  <link rel="stylesheet" href="/static/css/admin-theme.css">
  {{head_extra}}
</head>
<body>
  <nav class="sidebar">
    <div class="brand">
      <img src="/static/img/logo.svg" alt="DodaTech">
    </div>
    {{navigation}}
  </nav>
  <main class="content">
    {{flash_messages}}
    {{content}}
  </main>
  {{scripts}}
</body>
</html>

Expected output: Every AppML page renders inside the branded layout with sidebar navigation.

Configure the global template in appml.config.json:

{
  "theme": {
    "layout": "templates/admin/layout.html"
  }
}

Conditional Rendering

Templates support conditional sections for showing or hiding elements based on data.

<div class="status-badge {{row.status | lower}}">
  {{row.status}}
</div>
{% if row.priority == 'high' %}
  <span class="priority-flag">Requires attention</span>
{% endif %}

Expected output: Status badges with color classes based on the status value. High-priority items show an additional flag.

Common Mistakes

  1. Editing default templates directly: Changes to default templates are lost during AppML updates. Always create custom templates in a separate directory.

  2. Forgetting to include required placeholders: Omitting {{pagination}}, {{search}}, or {{flash_messages}} breaks functionality. Always include core placeholders.

  3. Hardcoding database field names in templates: Use the field references from the model instead. Hardcoded names break when the model changes.

  4. Not testing templates with different data states: A template that works with 10 records may break with empty data sets. Test with zero records and error states.

  5. Overengineering templates with complex logic: Templates handle presentation, not business logic. Complex conditions belong in the controller layer.

Practice Questions

  1. Where are custom AppML templates stored?

In a templates directory relative to the AppML runtime, organized into subdirectories by theme name.

  1. How do you reference a custom template in a view definition?

Use the template attribute on the view element: template="custom/list.html".

  1. What placeholder renders the search box in a list view template?

The {{search}} placeholder.

  1. How do you create a global theme applied to all views?

Configure the layout template in appml.config.json under the theme section.

  1. What happens to custom templates when you update AppML?

Default templates are overwritten. Custom templates in separate directories are preserved.

Challenge

Create a complete custom theme for an AppML application that includes a sidebar navigation, branded header, custom list view with striped rows, and a two-column detail form. Apply the theme globally to all views.

Frequently Asked Questions

Can I use CSS frameworks like Tailwind in AppML templates?

Yes. Include the CSS framework link in your layout template and use the framework's classes in your view templates.

Does AppML support template inheritance?

Yes. Templates can extend a base layout using the {% extends %} tag, similar to Jinja2 or Django templates.

Can I use JavaScript in AppML templates?

Yes. Include script tags in your templates. AppML also provides hooks for custom JavaScript initialization.

How do I preview custom templates during development?

Point your browser to the AppML view URL with a ?template=preview parameter to see the template without cached versions.

Can I share templates across multiple AppML applications?

Yes. Store templates in a shared directory and configure the template path in each application's configuration.

Mini Project

Design a complete branded dashboard theme for an inventory management system. Include a custom list template with product images, a detail template with tabs for different information sections, and a grid template for category browsing.

What's Next

Continue to AppML Forms to learn how to customize form layouts, add validation, and create complex data entry interfaces.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro