You are probably familiar with ordinary HTML tags. jAlbum also provides a set of special tags that can be used in your template files to help you with various tasks. These tags are executed as the album is generated and are not added to the final web page, only their resulting web code is added to the generated pages.

Testing for variable existence

Not all jAlbum variables are available at all times. If a variable is unavailable, it will show up empty or unexpanded (in the case of the $variable syntax) in the generated page. To prevent this from happening when one can't be certain if a variable exists, test for existence with the following construct. The example adds a link to the next slide in a slide show if there are more slides, if not, the text "at last page" is displayed instead:

<ja:if exists="nextPage">
    <a href="${nextPage}">Next</a>
    At last page

This example test for existence of camera flash information:

<ja:if exists="flash">
    Flash used: ${flash}
    No flash information found

You can also ‘not exists’ to test for the absence of the variable.

General testing

Any condition can be tested with the following syntax:

<ja:if test="true">This will be included</ja:if>
<ja:if test="false">This will NOT be included</ja:if>
<ja:if test="${booleanVariable}">Test a boolean variable</ja:if>
<ja:if test="${variable}" value="4711">Test for a certain value</ja:if>
<ja:if not test="${variable}" value="4711">Test for any but a certain value</ja:if>
<ja:if test="<%=expression%>">General expression test (slower but flexible)</ja:if>
<ja:if test="<%= engine.isHighQualityScaling() %>">
    These images have been scaled with the high quality setting

<ja:if test="<%= fileCategory.name().equals("webLocation") %>">…</ja:if> You can test for a range of valid Categories

<ja:if category="webPage, image, video">...</ja:if>

Switch tests

If you wish to take several different actions depending on several different values of a variable the ja:switch tag can be more convenient to use than the ja:if tag. This example should tell it all. The ja:default tag is optional:

<ja:switch test="${variable}">
    <ja:case value="one">Uno</ja:case>
    <ja:case value="two">Dos</ja:case>
    <ja:case value="three">Tres</ja:case>
    <ja:default>Otra numero</ja:default>

Page inclusion

It is common to want headers/footers/navigation bars or other web elements added to the generated album so that the album better fits to the existing site. This is easily done with the include tag:

<ja:include page="C:\mysite\header.inc" />
<ja:include page="header.inc">This text will show if the page does not exist</ja:include>

The page attribute can either be an absolute file path or a relative path. If it is relative, jAlbum will first search the image directory, then the current skin directory and finally the common "includes" directory.

Note, the path search above applies to .htt templates. When used in other templates, such as .css, the path is relative to the template unless explicitly stated, for example for an include file in the project's root folder
<ja:include page="${rootImageDirectory}/mycss.css" />

To include pages relative to the output directory, use scriptlets like this:

<ja:include page="<%=new File(outputDirectory, "header.inc")%>" />

Included pages may contain variables, scriptlets and other include tags. This example includes a text file carrying the same base name as an image. Image "foo.jpg" will get text from file "foo.txt" etc. This allows for simple comment inclusion or for adding special html to some images:

<ja:include page="<%= new File(imageDirectory, label+".txt") %>" />

There is also a "root" attribute, that tells jAlbum that the included page is to be found in the root image directory, like this:

<ja:include root page="commonHeaderForProject.inc" />

There is also the "once" attribute to the include tag. This makes sure that the page is included one time only. This is suitable for including scriptlets with common code definitions. By only evaluating these scriptlets once, big speed gains can be achieved. Here's an example:

<ja:include once page="commonScripts.inc" />

Picture tag

For skins to support srcset variants, the skin property supportsVariants=true must be set. Furthermore, ordinary "img" tags can be fitted with a srcset attribute that lists the variants. jAlbum provides two new variables for the contents of the srcset attribute: imageSrcset and thumbSrcset. However, that syntax doesn't allow for fallback to JPEG. To achieve fallback, one needs to wrap "img" tags with the html "picture" element and list the variants using "source" elements. These "source" elements need to provide a "type" attribute providing the mime type for that source as well as a srcset attribute listing the relevant variants for that type. This is where the "ja:picture" element is of use. Where you want to use an srcset for an image use

  <img src="${imagePath}" width="${imageWidth}" height="${imageHeight}" alt="${title}">

This will be expanded on 'Make album' to, for example, depending on what image variants are included.

  <source type="image/webp" srcset="ImgName-1200w.webp 1200w"/>
  <source type="image/jpeg" srcset=
    "ImgName-1800w.jpg 1800w, 
    ImgName.JPG 600w"/>
  <img src="ImgName.JPG" width="600" height="800" alt="ImgName">

During development you may want to check what image is actually being used by the browser. For jAlbum 24 to 28.1 If you set jAlbum's debug level to FINEST and force-remake the album your images will have their sizes embedded as text in the images. For jAlbum after 28.1 you need to pass -DdebugVariants=true on jAlbum's command line or open the system console and issue

System.setProperty("debugVariants", "true");

Then do a force-remake album.

Adding widget support

By adding the widget tag to a page, you control where jAlbum is to insert widgets into the generated code.

<ja:widget pageType="slide|index" />

If you omit this tag, jAlbum will automatically add a placeholder for widgets just before the closing body tag, unless the user has selected to switch off widget support or if you specify autoWidgetInjection=false as a property of the skin.properties file of your skin.

Customising widgets If you want to change the colours or icons used there are several posts in the forums on this topic, for example:



Album of albums and a common widget


Making space for the widget bar


Iterator tags

Iterators are powerful tags that are central to album skins. They "iterate" or repeat over files or folders of an album. For each iteration or lap, the contents of an iterator is added to the generated page, but before that happens variables are expanded to the relevant values for that specific file and scripts are executed.

Before we continue, here is a minimal iterator example that prints the filenames of the files on the current index page:

    ${fileName} <br>

When used without the "start" attribute on an index page, the fileiterator only iterates over the files that apply to that web page, so if you've set jAlbum to display 4x4 thumbnails per index page, the fileiterator will iterate over 16 images at a time.

The fileiterator has a number of optional attributes to control the iteraton:

  • category - iterate over specified categories. Categories include image, folder, video, audio, webLocation and other, usage is category="image, video" - Note the category 'webPage' is not iterated over.
  • include - same as category above.
  • exclude - exclude specified categories.
  • dirs - Iterate over directories / folders only
  • nodirs - Don't iteratate over directories / folders
  • start - Starting image number where "0" is the very first image. Relative values like "-1" or "+1" refer to previous or next file (slide.htt only)
  • count - Number of iterations to perform
  • step - How to move between iterations. Defaults to "1". Accepts negative numbers to move backwards

The fileiterator is safe in the regard that one cannot refer outside a set of files. Doing so will simply ignore that iteration.

Here is an example that can be added to a slide page. It prints a set of seven small thumbnails that are relative to the current image:

<ja:fileiterator start="-3" count="7">
    <a href="${closeupPath}"><img class="image" src="${thumbPath}" width="<%=thumbWidth/3%>" height="<%=thumbHeight/3%>" border="0" alt="${title}"></a>

There is also a tag element that iterates over hidden objects and custom pages, otherwise it is the same same behavior as ja:fileiterator

<ja:iterator> </ja:iterator>

This can, for example, be used to easily create navigation menus of web pages and folders for your album.

<div class="menu">
<ja:iterator category="webPage,folder" start="0">
  <a href="${closeupPath}">${title}</a>

The ‘start’ is required for versions prior to 17.3, as earlier versionsj default to "paging" which is only relevant for ‘index’ pages.

For index pages one can also use the older rowiterator and coliterator tags. These are practical to use together with tables. The content of the outer "row iterator" is repeated for each row of images and the content of the inner "column iterator" is repeated for each image. Image specific variables only exists within the column iterator:

<!-- Iterate through images and produce an index table -->
        <tr valign="bottom">
          <a href="${closeupPath}">
            <ja:if exists="iconPath">
              <!-- No frames around icons like folders and movie files -->
              <img src="${iconPath}" width="${thumbWidth}" height="${thumbHeight}" border="0">
              <br >
              <img class="image" src="${thumbPath}"
               width="${thumbWidth}" height="${thumbHeight}" border="0"><br>

Enter tag


The enter tag instructs jAlbum to 'see' folder variables within <fileIterator> loops, normally they are not available.

Normally when in a file iterator within "index.htt", the hierarchy of variable scopes looks like this (from outer to inner):

Global variables

Page variables

Current object variables

When using the enter tag the hierarchy of variable scopes is:

Global variables

Current folder variables

Page variables

Current object variables

The safe way to test if the currently iterated object is a folder is to either write:

<ja:if test="${fileCategory}" value="folder">

or use a shorter "test for category":

<ja:if category="folder">

For example, if you have a top level Folder called A and it contains two subfolders, B and C. Now, when you ask for folderTitle you will get the folder title for the inner folders (B and C) as they hide the corresponding "folderTitle" from the outer context (A).

You can use fileTitle to obtain the titles of folders B and C without having to use the 'enter' tag.


You may naturally use the classic html comment syntax, but if you wish to write a comment that shouldn't even make it to the generated pages, use this syntax:

<%-- This comment won't appear in the generated pages --%>

Bypassing scriptlets

If you are generating album pages containing scriptlets that are to be processed by an ASP or JSP engine instead of jAlbum, you need to tell jAlbum to ignore those scriptlets and pass them on to the generated pages. This is done like this:

    <% This could be some ASP code %>

Linking correctly

jAlbum tries to allow flexible linking of images. The user interface allows three types of linkings:

  • Link to original images from index pages or slide pages
  • Link to original images via scaled down slide page
  • Link to scaled down images only

When designing a template, it's important that you use correct variables and existence tests in order for the linking to make sense. The code above shows an example of correct linking from an index page to a slide page or image by using the $closeupPath variable. For the slide page template, the linking should be like this:

<!-- Image, maybe with link to original -->
<ja:if exists=originalPath>
  <a href="${originalPath}">
    <img src="${imagePath}" width="${imageWidth}" height="${imageHeight}"
     border="0" alt="Original image">
  <img src="${imagePath}" width="${imageWidth}" height="${imageHeight}">

Creating a custom user interface

Page templates, such as About.htt and Contact.htt. make use of the

<ja:ui> </ja:ui>

You can read more about creating a user interface here.