JSON data

Are you familiar with JSON, Ajax, jQuery and Javascript? You can create skins that uses JavaScript to read files with JSON data about the album, instead of having to learn the jAlbum specific Tags and Variables in index.htt and slide.htt. There is a developer API to help skin development.

JSON based skins may need to have certain jAlbum settings set in order to guarantee the data is complete. In the advanced settings, general tab, process subdirectories should be on, process only updated subdirectories off and Include subdirectories in index pages on. These can be forced using engine setter methods - see AlbumBean API, e.g. engine.setSubdirs(true); engine.setUpdatedDirsOnly(false); engine.setIncludeDirectories(true); Their original settings can be saved in init.bsh using the engine.is calls and restored, in finally.bsh.

There are three methods of generating the Json data, you can generate data files, you can embed the Json data in the html pages of your albums or you can write the data to a JavaScript file. Each method has advantages and disadvantages.

Writing the data to .json files in each folder allows the skin designer to incrementally load those files as needed, which could be essential for very large albums, those with thousands of images. Having each page load all of the data could result in a large processing overhead and a high data rate during loading. The downside is that many browsers will not load locally stored .json files, so you cannot preview the albums in several browsers without uploading the album first. Also, some servers may not be configured to recognise .json files and thus resulting in broken albums.

Embedding the data in each page avoids the preview and server issues above but suffers from loading all of the data for every page. So this method is more suited for small sized albums.

Writing the data to a JavaScript file means all of the data is loaded for each page but this technique lets you easily embed the album in another site, without the need of iFrames.


Contents

Creating Json files

Add an empty data-config.json file to the root of the skin and jAlbum will generate all the JSON files you need:

  • In the root of the final album a tree.json file is added, containing all folder data for the entire album.
  • For each folder in the final album a number of dataN.json files will be added, where N is the paging number, starting with 1.

You can control the paging and enhance the content of the Json data by editing the data-config.json file. For example:

{"paging":0,
 "include": [
  "label",
  "gpsLocation",
 ]
}

Setting "paging" to 0 results in a single data1.json file containing data on all the items in each folder, setting it to 1 creates, say, data1.json through to data10.json for a folder contains 10 items with each file having data for each item.

Using "include" lets you add jalbum or skin variables that are not included in the 'standard' Json set.

jAlbum will then generate these files (depending on the metadata in the images). Create an album with the image "Clock.jpg" in the root and one folder called "Nature" with "Horses.jpg": JSON-album-example.jpg

tree.json:

{
  "path": "JSON-example",
  "folders": [
    {
      "path": "Nature",
      "counters": {
        "total": 1,
        "images": 1,
        "files": 1
      },
      "thumb": {
        "path": "Nature\/thumbs\/Horses.jpg",
        "width": 232,
        "height": 160
      },
      "name": "Nature",
      "fileDate": "2015-02-12T15:57:07.0Z"
    }
  ],
  "counters": {
    "total": 2,
    "images": 1,
    "folders": 1,
    "files": 1
  },
  "name": "JSON-example",
  "comment": "Minimal JSON album.",
  "fileDate": "2015-02-12T15:57:27.0Z"
}


data1.json:

{
  "path": "JSON-example",
  "deepCounters": {
    "total": 3,
    "images": 2,
    "folders": 1,
    "files": 2
  },
  "counters": {
    "total": 2,
    "images": 1,
    "folders": 1,
    "files": 1
  },
  "album": {
    "description": "Minimal JSON album."
  },
  "objects": [
    {
      "path": "Clock.jpg",
      "image": {
        "path": "slides\/Clock.jpg",
        "width": 900,
        "height": 668
      },
      "creator": "Laza",
      "thumb": {
        "path": "thumbs\/Clock.jpg",
        "width": 216,
        "height": 160
      },
      "fileSize": 78560,
      "name": "Clock.jpg",
      "rating": 4,
      "fileDate": "2013-07-02T12:56:42.0Z",
      "category": "image",
      "title": "Clock",
      "camera": {
        "aperture": 4.5,
        "exposureTime": "1\/50s",
        "originalDate": "2009-08-09T15:46:18.0Z",
        "cameraModel": "Canon EOS 1000D",
        "focusDistance": "0.26m",
        "focalLength35mm": "29.2mm",
        "cameraMake": "Canon",
        "isoEquivalent": 400,
        "flash": "Flash did not fire, auto",
        "focalLength": "18.0mm"
      }
    },
    {
      "path": "Nature",
      "deepCounters": {
        "total": 1,
        "images": 1,
        "files": 1
      },
      "counters": {
        "total": 1,
        "images": 1,
        "files": 1
      },
      "thumb": {
        "path": "Nature\/thumbs\/Horses.jpg",
        "width": 232,
        "height": 160
      },
      "name": "Nature",
      "fileDate": "2015-02-12T15:57:07.0Z",
      "category": "folder"
    }
  ],
  "name": "JSON-example",
  "comment": "Minimal JSON album.",
  "fileDate": "2015-02-12T15:57:27.0Z"
}

Nature/data1.json:

{
  "path": "Nature",
  "deepCounters": {
    "total": 1,
    "images": 1,
    "files": 1
  },
  "counters": {
    "total": 1,
    "images": 1,
    "files": 1
  },
  "thumb": {
    "path": "Nature\/thumbs\/Horses.jpg",
    "width": 232,
    "height": 160
  },
  "album": {
    "description": "Minimal JSON album."
  },
  "objects": [
    {
      "path": "Horses.jpg",
      "image": {
        "path": "slides\/Horses.jpg",
        "width": 900,
        "height": 621
      },
      "thumb": {
        "path": "thumbs\/Horses.jpg",
        "width": 232,
        "height": 160
      },
      "fileSize": 167212,
      "name": "Horses.jpg",
      "rating": 4,
      "fileDate": "2013-07-02T13:08:20.0Z",
      "category": "image",
      "title": "Horses",
      "camera": {
        "aperture": 4.5,
        "exposureTime": "1\/800s",
        "originalDate": "2012-12-27T12:20:49.0Z",
        "cameraModel": "XZ-1",
        "focusDistance": "155.0m",
        "focalLength35mm": "77.0mm",
        "cameraMake": "OLYMPUS IMAGING CORP.",
        "isoEquivalent": 100,
        "flash": "Flash did not fire, auto",
        "focalLength": "16.6mm"
      }
    }
  ],
  "name": "Nature",
  "fileDate": "2015-02-12T15:57:07.0Z"
}

The format of these files are in reality compact and are prettified here for readabiliity.

If you use jQuery you can now read for example tree.json using

$.ajax({
	type: "GET",
	dataType: 'json',
	url: 'tree.json'
})
.done(function(data) {/* Process the data here! */});

Some browsers (for example Google Chrome) unfortunately blocks Ajax calls if previewing the local album. Either switch to another browser or Google on how to set the Google Chrome --allow-file-access-from-files flag. Using the built in browser in jAlbum will also work. And if you publish your album to a webserver it will work using any modern browser.


Embed Json data

If you have previously used a data-config.json file you should delete it as it is not required for this method.

In init.bsh, add the following code

jm = new JSONMaker(engine);
jm.setIncludes(new String[] { "label", "gpsLocation" }); //Optional additional variables to be included
dataTree = jm.getTreeAsString(rootFolder);

If you wish to switch off the recursive behavior of the generated tree, i.e. so it only lists objects in the current folder, call setMakeTree(false); prior to calling getTreeAsString().

This will generate a full JSON formatted data tree to the variable "dataTree". Now, this variable is only known during album-build time. You therefore need to pass it to a client-side javascript variable. To do so, in your .htt files, add the following:

<script>dataTree = ${dataTree};</script>

Now, just continue referring to javascript code snippets, like this:

<script>fileCount = dataTree.counters.files</script>

These snippets can now simply refer to the dataTree variable via jQuery for instance.

If you wish to switch off the recursive behavior of the generated tree, i.e. so it only lists objects in the current folder, call setMakeTree(false); prior to calling getTreeAsString().

You can also call getTree() which delivers an object tree that can be manipulated on the Java side (in init.bsh). When you're happy with the manipulation, call toJSONString() on the object returned by getTree().

Jason data in a JavaScript file

See Single page web album for details.

Sample skin

You can try MinimalJSON.jaskin to get started with these techniques.