Sample scripts

This section will show examples on how scripts can enhance your album in really cool ways. The examples here makes use of the huge library of ready-made java classes that Sun has provided for free and are directly accessible. To better understand the examples and to assist in the writing of your own scripts we strongly recommend that you first read through skin documentation, then bookmark the jAlbum API and Java API from Sun and use them to look up classes and their methods. If you are new to Java it's recommended that you look at these tutorials first and that you then concentrate on the "java.lang", "java.util" and "java.io" packages. They are the ones that are most commonly used. Remenber that you can turn to the forum to get help and to help others!

Contents

Extra slide pages for original images

When clicking on an image in a slide show, you may get to the original image, but it is not displayed in a html page of its own. The downside of this is that the surroundings for the image doesn't match the skin (usually displayed on white background) and you have to use the back navigation button to return. Take a look at the new "Smart" skin in the extras section that addresses this issue by some lines of BeanShell scripting. The skin has an extra template file called "originalslide.htt". The following simple adjustment to the "slide.htt" file will make sure that the "originalslide.htt" file gets processed if needed:

<%-- Image, maybe with link to original --%>
<ja:if exists="originalPath">
    <%-- Create a slide page for the original image too and link to that one  --%>
    <%-- instead of linking to an image --%>
    <%
        String originalPage = originalPath;  // Default if no extra template page
        File template = new File(skinDirectory, "originalslide.htt");
        if (template.exists()) {
            originalPage = label+"_orig"+engine.getPageExtension();
            engine.processTemplateFile(template,
            new File(outputDirectory,"slides/"+originalPage));
        }
    %>
    <a href="<%=originalPage%>">
        <img src="${imagePath}" />
    </a>
</ja:if>

Adding voice annotations

Many digital cameras allow you to add voice annotations to images. The camera usually puts a wav file next to the image bearing the same base name as the image. This script will make JAlbum look for these wav files and insert a BGSOUND tag if there is an annotation. Put the script just after the body tag of a slide.htt file.

<!-- add and play voice annotations (.wav files) if they exist -->
<%
  import se.datadosen.util.IO;
  File sound = new File(imageDirectory, label+".WAV");
  if (sound.exists()) {
    // Make a copy if needed
    String soundPath;
    if (!outputDirectory.equals(imageDirectory) && engine.isCopyOriginals()) {
      IO.copyFile(sound.getAbsolutePath(), outputDirectory, true);
      soundPath = "../" + sound.getName();
    }
    else soundPath = IO.relativePath(sound, new File(outputDirectory, "slides"));
    out.println("<BGSOUND SRC=\"" + soundPath + "\">");
  }
%>

Multilevel (breadcrumb) parent links

You might have an album with many nested folders (animals/mamals/cats...). In this case it helps a lot to have all folder names displayed like this: animals » mamals » cats (being in the "cats" folder), with links to each parent folder. Copy and paste the scriptlet below for this effect:

<%!
  void makeBreadcrumbs(AlbumObject folder, String prefix) {
    if (folder == null) {
      return;
    }
    makeBreadcrumbs(folder.getParent(), "../");
    String title = folder.getTitle();
    if ("".equals(title)) title = folder.getName();
    out.println("<a href=\"" + prefix + firstIndexPage + "\">" + title + "</a> » ");
  }

  void makeBreadcrumbs() {
    makeBreadcrumbs(currentFolder, "");
  }
%>

<% makeBreadcrumbs()%> <%-- sample call from index.htt --%>

<% makeBreadcrumbs(currentFolder, "../")%> <%-- sample call from slide.htt --%>

Reading captions/comments from separate text files

Some people wonder if it is possible to have jAlbum insert the contents of a text file having the same base name as an image but with ".txt" extension, for example "hiking.jpg" will get text from "hiking.txt". This is simple to do with the following scriptlet:

<!-- Extract text from textfiles carrying the same base name as this image -->
<ja:include page="<%= new File(imageDirectory, label+".txt") %>" />


Counting objects

You can write code to first collect counters for all categories in one count operation and then obtain the number of items for each category by using the count categories utility. The categories you can get counts for are audio, image, video, webPage, webLocation, folder and other

<%
//Ways of getting the counters

//Counters for the current folder
CategoryCounters counters = JAlbumUtilities.countCategories(currentFolder, false);

//Counters for the root folder 
CategoryCounters counters = JAlbumUtilities.countCategories(rootFolder, false);

//Counters for the whole project, true uses recursion to count subfolder contents
CategoryCounters counters = JAlbumUtilities.countCategories(rootFolder, true);

//Examples for get the counts
Integer imageCount = counters.getCount(Category.image);
Integer webPageCount = counters.getCount(Category.webPage);
%>

Traversing the project

The standard way of traversing a nested structure such as a jAlbum project is to use recursion, which can seem non intuitive. Since jAlbum 15 an easier to grasp method has been available, the 'get descendants' API call. An example of using this is shown below, it generates a sorted unique list of keywords used throughout the project.

Set keywords = new TreeSet();
for (AlbumObject ao : rootFolder.getDescendants()) {
  keywords.addAll(ao.getKeywordSet());
}

Other examples are

// Count all but hidden and excluded objects
rootFolder.getDescendants().size();
 
// Count all but excluded objects
rootFolder.getDescendants(IncludeOption.HIDDEN).size();

Note, if not using Beanshell/Java you will need to first use

var IncludeOption = Java.type("se.datadosen.jalbum.IncludeOption");

For more information an examples see this forum post by jAlbum's creator - of which the above is an extract of.

Theme images

From jAlbum 15 skins can easily create theme images for any folder, see explore/folder properties pane. By default theme image support is disabled, to enable it you need to provide a string variable called ‘folderImageSize’ with width and height dimension i.e. 1000x300 would be an image 1000px wide and 300px high.

Note, if you want to use an alternative variable name to folderImageSize you can do so by adding themeImageSizeName=yourtFolderImageSizeVariableName to the skin.properties file

The folderImageSize variable can be added to the SkinModel file as

public String folderImageSize = “1000x300”;

Or in onload.bsh as

public JTextField folderImageSize = new JTextField("1000x300");

In order to correctly update the displayed crop area, following user changes in the skin’s GUI, you need to set your skin component first and then the themeImageDim, for example:

new StateMonitor() {
	public void onChange() {	
		String[] parts = folderImageSize.getText().split("x");
		if(parts.length > 1) {
			int widthValue = Integer.parseInt(parts[0]);
			int heightValue = Integer.parseInt(parts[1]);
			engine.setThemeImageDim(new Dimension(widthValue, heightValue));
   		}
	}
}.add(folderImageSize).done();

Also by default the theme image will be based on the image selected for the folder thumbnail. If you want your skin to support separate thumbnail and theme images in the skin.properties file add

separateThemeImage=true

To produce the theme images there are two methods, let jAlbum make the theme images for you or take control and produce them yourself.

Method 1: jAlbum control: To init.bsh add

engine.setThemeImageProcessor(new ThemeImageProcessor());

In your skin's index.htt, where you want to include the theme image add, for example as a CSS background image for an ID of 'themeImage'

<ja:if exists="themePath">
  .themeImage {
     background: url(${themePath}) center top no-repeat;
  }
</ja:if>

If you want other names or locations for the generated theme images you can create a subclass of the ThemeImageProcessor. In the example below the theme image is called ja_theme.jpg and it is put in the slides directory instead of the root of the current directory.

ThemeImageProcessor custom = new ThemeImageProcessor() {
  public String getThemePath(AlbumObject folder) {
    return engine.getSlideDirectory() + "/ja_theme.jpg";
  }
};
 
engine.setThemeImageProcessor(custom);

Note:There are three variables produced by jAlbum ${themePath}, ${themeWidth} and ${themeHeight}


Method 2: skin control: in postdir.bsh add

//Import required resources
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.logging.Level;
import net.jalbum.filters.CropFilter;
import se.datadosen.jalbum.AlbumImage;
import se.datadosen.jalbum.AlbumObject;
import se.datadosen.jalbum.EmbeddedProperties;
import se.datadosen.jalbum.JAlbum;
import se.datadosen.jalbum.JAlbumUtilities;

 //Get the theme image dimensions, jAlbum uses themeImageSizeName variable to get the dimensions
Dimension themeDim = engine.getThemeImageDim();
//Create an album object for the current folder’s theme image
AlbumObject theme = JAlbumUtilities.getThemeObject(currentFolder);
//Ensure dimension are set and an image object exists to work on
if (themeDim != null && theme != null) {
    File themeFile = new File(outputDirectory, "ja_theme.jpg");
    //Use builtin routines to compare the image to be used and the image generated, create/update the generated image only if required
    //for example crop focus changes or a different image selected
    EmbeddedProperties existing = new EmbeddedProperties(themeFile);
    EmbeddedProperties current = new EmbeddedProperties();
    current.put("themeSrc", theme.getPathFrom(currentFolder));
    current.put("themeDim", themeDim.width + "x" + themeDim.height);
    if (!engine.isAppendImages() || JAlbumUtilities.isDirty(themeFile, theme) || !existing.equals(current)) {
    //log information to the console, only visible when logging level is set to FINE in preferences/general
        JAlbum.logger.log(Level.FINE, "Regenerating theme image ja_theme.jpg (" + themeDim.width + "x" + themeDim.height + ") for folder {0} ", currentFolder);
        //Create the theme image using the dimension set and cropped as shown in the folder properties pane
        AlbumImage ai = new AlbumImage(theme);
        CropFilter cf = new CropFilter();
        double ratio = (double) themeDim.width / themeDim.height;
        int width = ai.getBufferedImage().getWidth();
        int height = ai.getBufferedImage().getHeight();
        Dimension bounds = new Dimension(width, (int) (width / ratio));
        if (bounds.height > height) {
                bounds = new Dimension((int) (height * ratio), height);
        }
        cf.setBounds(bounds);
        ai = ai.applyFilter(cf, (Map) theme.getVars());
        ai = ai.scaleToFit(themeDim);
        ai.saveImage(themeFile);
        current.write(themeFile);
    }
}

You can of course change the location and file name of the theme image by modifying the above code. For more information on the above code see: All that is left to do is include the theme image in your skin's pages, it is recommended you add the theme image as a 'background image'.

Skin properties API

JAlbumUtilities-getThemeObject()

EmbeddedProperties

setThemeImageDim()