🚀 Andalina is evolving fast! Star or Watch our repository to get instantly notified about new features and releases.

Documentation

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: Mandatory configuration file for defining paths and framework-safe data binding delimiters.

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

Important Note: Because andalina uses the Fetch API to load templates dynamically, modern browsers will block it due to CORS restrictions if you open the HTML/XHTML file directly (e.g., file://). You must run your project through a local development server (like VS Code's "Live Server" extension) for andalina to work!

<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 either src or name.

Example:

1. The Partial (head-content.html)

2. The Call (index.html)

Rendered HTML:


<an-data>

Used to fetch external JSON data and store it in memory for your templates to use.

Attributes:

  • src (Required): The URL or path to the JSON endpoint/file.
  • name (Required): The variable name to store the fetched data in.

Example:

Example 2 (Global Data Binding & Arrays):

Any data fetched using <an-data> becomes globally available to the entire document. You can inject specific strings or nested objects directly into your HTML or component attributes anywhere on the page, without needing a loop!

Rendered HTML (Example 2):

<an-repeat>

Used to loop content dynamically. You can either repeat a specific number of times, or iterate over data fetched with <an-data>.

Attributes:

  • times (Optional): An integer specifying how many times to repeat the content block. (Used for simple numeric loops).
  • data (Optional): The name of the data array fetched via <an-data> to iterate over.
  • item (Optional, Default: "item"): The local variable name used to access the current object in the data array.
  • index-as (Optional, Default: "$index"): The variable name used to access the current loop iteration index.

Example 1 (Simple numeric loop):

Rendered HTML (Example 1):

Example 2 (Looping over fetched data):

Rendered HTML (Example 2):

<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 either src or name.
  • 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 either src or name.

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 either src or name.

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.

Syntax Highlighting Warning: If you are using a code highlighter like 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. If codesPath is configured, it resolves relative to that directory.

Example:

1. The Source Code (js/app.js)

2. The Call (index.html)

<an-if> / <an-else>

Evaluate a conditional block. You can use native JavaScript expressions inside the condition against your <an-data> sources.

Attributes:

  • condition (Required on an-if): The JavaScript expression to evaluate. Must resolve to a truthy or falsy value.

Example:

<an-if condition="store.isOpen && user.name !== ''">
   <p>Welcome to the store!</p>
</an-if>
<an-else>
   <p>Sorry, we are closed.</p>
</an-else>

JS Expressions in Bindings

In Andalina v1.6.0+, standard double-curly bindings fully support native JavaScript expressions, array methods, and fallbacks.

<!-- Fallbacks -->
<p>Welcome, {{ user.name || 'Guest' }}!</p>

<!-- Math & Logic -->
<p>Total Price with Tax: {{ price * 1.2 }}</p>
<p>Discount: {{ price > 100 ? '20%' : '5%' }}</p>

<!-- an-comment: -->

Andalina provides a specialized HTML comment syntax for development notes that are automatically stripped out when you compile your project using the Andalina Builder.

Syntax:

<!-- an-comment: Your note here -->

Example:

<!-- an-comment: This is a note for developers that won't appear in the final HTML -->
<div>Visible Content</div>

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.
  • debugUI: {true, false}. When debug is enabled, this toggles the floating visual component tree overlay. Defaults to true.
  • preventFOUC: {enabled, disabled}. Prevents Flash of Unstyled Content by hiding the page body until rendering completes.
  • propStart: (Mandatory) The starting string for properties (e.g. {{).
  • propEnd: (Mandatory) The ending string for properties (e.g. }}).
  • prefix: A custom prefix for Andalina tags. Defaults to an. 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 Issue: If a third-party library runs before andalina has finished injecting your components, the library won't find the elements and will fail to initialize.

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

Andalina Builder

The Andalina Builder is a powerful VS Code Extension that performs AOT (Ahead of Time) Transpilation. It seamlessly converts your raw Andalina project directly into static SSG files or native Enterprise framework views.

Features:

  • GUI Configuration: Manage your build targets natively in VS Code without editing JSON files manually.
  • Multi-Target Transpilation: With a single click, convert your Andalina UI into:
    • Static HTML (Flat SSG)
    • JavaServer Faces (JSF) [Experimental] (Outputs a Maven Web App structure with Composite Components and Facelets Templating)
    • Laravel Blade [Experimental] (Uses @component, @slot, @extends)
    • Django [Experimental] (Uses {% include %}, {% block %}, {% extends %})
    • Thymeleaf [Experimental] (Uses th:replace, th:fragment, th:each)
  • Advanced Architecture Support: Resolves <an-component>, <an-layout>, <an-template>, and <an-inject> tags directly into native server-side equivalents.
  • Production Cleanup: Safely strips Andalina-specific scripts, styles, <an-data>, and <!-- an-comment --> tags from your final production artifacts.
  • Asset Copying: Automatically copies your images, CSS, and JS files to the target directory.
  • Auto Build on Save: Optionally watch your source files and automatically rebuild when changes are detected.

How to Use:

1. Install the Andalina Builder extension in VS Code.
2. Look for the Andalina Build view in your VS Code Explorer sidebar.
3. Click the + icon to add a new Action.
4. Specify your Source Folder and Target Folder.
5. Check off one or more Target Platforms (e.g. Static HTML, JSF, Blade, etc.).
6. Click the play button on your Action in the sidebar to build your artifacts!