What is andalina?
andalina is a zero-dependency, development-time composition tool designed to enforce the DRY (Don't Repeat Yourself) principle for HTML authoring. It is not a framework for serving web applications; it is a template parser for HTML/XHTML that runs directly in the browser.
The Problem We Solve:
This addresses a classic Developer Experience (DX) problem: the handoff friction between Front-End (FE) and Back-End (BE) teams. Often, when the FE team delivers raw HTML, the BE team has to rewrite or "clean up" the HTML to ingest it or wrap it in their server-side logic (JSF, ASP, Laravel, PHP, Django, JSP, Thymeleaf, Blade, Jinja2, etc.). This leads to massive BE/FE misalignment during the development phase.
The Vision:
Our vision is to solve this misalignment by providing a simple, unified, language-agnostic template language. By using andalina, the FE team delivers structured, modular components that perfectly map to server-side component boundaries. The BE team can now easily integrate these templates without rewriting the HTML. This vision is built upon four core pillars:
- Zero-Dependency: andalina runs entirely in the browser. No Node.js build pipelines, no Webpack, and no server-side rendering required.
- Simple & Easy to Learn: andalina uses only 5 core tags. It is incredibly easy to pick up, even for absolute beginners.
- Standard HTML/XHTML: There is no need to learn a new programming language or complex framework. It's just the HTML you already know!
- Single Source of Truth: Front-End developers can fix bugs in exactly one place. No more repeating code across 20 files—andalina handles the repetition for you.
How to Use
1. Download Andalina
First, download the latest version of Andalina from the Download Page (or our GitHub Repository). The downloadable archive (.zip) includes:
andalina.js: The core zero-dependency client-side template engine.andalina.config.json: Optional configuration file for customizing template paths and behavior.
2. Add to Your HTML Document
Place andalina.js in your project directory and simply drop the script tag into the <head> of your HTML document. Ensure you include the defer attribute so Andalina executes after the DOM is ready:
3. Run a Local Development Server
file://). You must run your project through a local
development server (like VS Code's "Live Server" extension) for andalina to work!
<an-repeat>
Used to loop content dynamically.
Attributes:
times(Required): An integer specifying how many times to repeat the content block.index-as(Optional, Default: "$index"): The variable name used to access the current loop iteration index inside the block.
Example:
Rendered HTML:
<an-include>
Used to inject static HTML partials directly into your page.
Attributes:
src(Optional): The exact path to the HTML/XHTML file you want to include.name(Optional): The name of the include fragment (resolves to[includesPath]/[name][extension]).Note: You must provide eithersrcorname.
Example:
1. The Partial (head-content.html)
2. The Call (index.html)
Rendered HTML:
<an-component>
Used to import reusable components and pass dynamic properties via attributes. Variables
inside the component are defined using
<an-attribute>.
Attributes:
src(Optional): The exact path to the component HTML/XHTML file.name(Optional): The name of the component (resolves to[componentsPath]/[name][extension]).Note: You must provide eithersrcorname.- Dynamic Attributes: Any other attribute you add will be passed to the component as a property.
Inside the component file, define your component using Andalina's Structured Syntax: wrap the file in an <an-component-def> container, specify metadata in an <an-attributes> block, and place your markup inside an <an-body> block.
Inside <an-attributes>, use <an-attribute> to define the props. It accepts:
name(Required): The name of the property.default-value(Optional): A fallback value if the prop is not passed.mandatory(Optional): Set to "true" to log a warning if the prop is missing.
Example:
1. The Component (user-card.html)
2. The Call (index.html)
Rendered HTML:
<an-layout>
A structural wrapper that can be nested inside an <an-template> or within
another layout. It provides a reusable shell (like a sidebar grid or a card container) and
uses <an-place> slots to accept content from children.
Like components, layouts use Andalina's Structured Syntax: wrap the file in an <an-layout-def> container, specify optional metadata in an <an-attributes> block, and place your structural markup inside an <an-body> block.
Attributes:
src(Optional): The exact path to the layout HTML/XHTML file.name(Optional): The name of the layout (resolves to[layoutsPath]/[name][extension]).Note: You must provide eithersrcorname.
Example:
1. The Grid Layout (dashboard-layout.html)
2. The Calling Page (admin.html)
Rendered HTML:
<an-template>
The root tag used in your final page to wrap your content inside a complete HTML/XHTML
document template. Unlike an <an-layout> (which acts as a structural
partial), a template provides the full, standard structure of a webpage, including the
<html>, <head>, and <body> tags.
Attributes:
src(Optional): The exact path to the template page HTML/XHTML file.name(Optional): The name of the template page (resolves to[templatesPath]/[name][extension]).Note: You must provide eithersrcorname.
Example:
1. The Root Template (master.html)
2. The Calling Page (index.html)
Rendered HTML:
<an-code>
Used to inject unparsed source code directly from a file, perfectly formatted and safely escaped for documentation blocks.
highlight.js or Prism.js, you must ensure it only runs
after your <an-code> blocks have been fully fetched and injected.
For a detailed explanation of this async race condition and how to fix it, please see the Third-Party JS Compatibility section.
Attributes:
src(Required): The exact path to the source code file. IfcodesPathis configured, it resolves relative to that directory.
Example:
1. The Source Code (js/app.js)
2. The Call (index.html)
Configuration
Define the global behavior in andalina.config.json:
Properties:
showRenderedHtml:{enabled, disabled}. Enables or disables the output of the final rendered HTML into the Developer Tools Console.debug:{enabled, disabled}. Enables or disables the output of detailed debugging information during the rendering process.preventFOUC:{enabled, disabled}. Prevents Flash of Unstyled Content by hiding the page body until rendering completes.propStart: The starting string for properties. Defaults to{{. It can be any string, but it must be different from thepropEndvalue.propEnd: The ending string for properties. Defaults to}}. It can be any string, but it must be different from thepropStartvalue.prefix: A custom prefix for Andalina tags. Defaults toan. It can be any string (e.g.,an,andalina,aa).componentsPath: The directory path where your component files are stored.layoutsPath: The directory path where your layout files are stored.templatesPath: The directory path where your templates files are stored.includesPath: The directory path where your HTML fragment and include files are stored.codesPath: The directory path where your source code snippet files are stored.extension: The default file extension to be used for components, layouts, pages, and includes when referring to them by name only. It can be any string, but it must start with a dot (e.g.,.html,.xhtml).
Example:
Page Scope Configuration: You can override the global configuration directly on a specific page by adding data attributes to the andalina script tag.
Show Rendered HTML
Since andalina runs client-side and dynamically manipulates the DOM, viewing the page source
in your browser (Right Click > View Page Source) will only show your
<an-> tags, not the final rendered HTML.
If you need to inspect or copy the completely rendered HTML, you can enable the
showRenderedHtml configuration globally in andalina.config.json, or
on a
single page using data-show-rendered-html="enabled":
When enabled, andalina will print the Final Rendered HTML directly into your Developer Tools Console! You can easily inspect it or copy-paste it.
Debugging
When working with complex nested templates, it's easy to lose track of what andalina is
fetching. To help with this, you can enable debug mode.
Enable Debug Mode:
You can turn on debug mode globally in your andalina.config.json, or on a single
page using the script attribute: data-debug="enabled".
When enabled, andalina will print a beautiful, structured trace directly to your browser's Developer Tools Console, showing exactly which files were fetched, how long the network request took, and the properties passed to each component.
Third-Party JS Compatibility
Because andalina dynamically fetches and injects HTML into the DOM asynchronously, it can cause race conditions with third-party JavaScript libraries (such as sliders, lightboxes, or UI frameworks) that attempt to scan the DOM immediately on page load.
The Solution:
You must initialize your third-party libraries after you are sure the asynchronous
fetching has completed. A reliable way to handle this is by awaiting the component injections
or using a Promise.all approach if you are manually fetching content.
Example: Safe Initialization