I updated the Photo Browser to create the browsing tree from Adobe Lightroom keywords. This post is only of interest if you are interested in some of the ‘nuts and bolts’ of the website.
Overview of the problem and solution
The problem is that adding a node to the browser tree requires manually editing a file. I want to add a lot of nodes at once (about 180 of them), but I don’t want to do this manually. It’s time consuming, boring, tedious, and mistake prone.
As an example, to see the results of this update, do the following. Select the ‘Photo Browser’ tab on the website. In the browser, expand the Bird node. You will now see all the Bird families, for example the ‘Wood Warblers’ node. Prior to this change you could click on ‘Wood Warblers’ to see all Wood Warbler pictures. You can still do that. But the change is that now you can expand the Wood Warblers node to see all of the species under it. You can select any species to see all the photos of that species (e.g. select ‘Yellow-rumped Warbler’).
For bird pictures, the photo browser shows the hierarchy of the taxonomy. For example, under Bird (i.e. the ‘class’) there is a node for each Family (e.g. Hummingbirds or Wood Warblers). When you click on Hummingbirds you see the pictures of ALL species of Hummingbirds.
The browser tree only went down to the Families. There are about 38 of them, and I added them to the JSON over time as I got pictures from each family. Now I have about 180 different species. I wanted to show them in the tree, but I didn’t want to type them all in the JSON file by hand.
The solution that I implemented was to export the Keyword hierarchy from Adobe Lightroom (where I have all my photos), and write a program to automatically generate the JSON file from Keyword file.
The best solution to solve this would be to upgrade my plugin (Tag Gallery Page) to read the Lightroom keyword file, and produce the JSON file. Even better, I could write a Lightroom plugin to automatically update the Tag Gallery Page plugin on my website based on the keywords (I’ve never written a Lightroom plugin, but I know it can be done because I use one called ‘Dossier De Presse’).
However, that would take much more time that I have for this. Also, there wouldn’t be much use for it, since Tag Gallery Page is only used by me. There are two reasons that others aren’t interested in this plugin: it doesn’t have the bells and whistles to make it user friendly; it only works with the old version of Nextgen Gallery (since the new version broke it).
So I took the easy way out and wrote a C++ program that runs on my desktop computer. The steps to use the program are the following:
- Open Lightroom and export the Keywords to a file. This is done by selecting ‘Metadata -> Export Keywords’ in Lightroom.
- Run PhotoBrowserJson (from a shortcut on the desktop). This creates the JSON file needed to build the photo browser.
- Download the JSON file to my website using FileZilla.
PhotoBrowserJson uses a ‘.in’ file called PhotoBrowserJson.in which specifies where to find the Keywords file, and where to put the output JSON file.
When PhotoBrowserJson is run, an editor pops up with the Keyword hierarchy, and for each keyword, there are three parameters:
- A user friendly caption that is shown on the browser. The default is just the keyword. For example, if the keyword is ‘Dark-eyed Junco’, then the default is fine. If the keyword is ‘Diurnal Raptors’, then the friendly caption is ‘Diurnal Raptors (Hawks, Eagles, etc)’.
- A boolean variable indicating if the node should be skipped. This is for Keywords that I have in Lightroom, but I don’t want to show it on the website. The default is set to ‘0’, indicating not to skip the node. If this is set to ‘1’, then the node is not included in the browser tree.
- A boolean variable indicating if the node should be selectable. If it is selectable, then clicking on it shows a photo gallery. If not, then clicking on it does nothing. The default is set to ‘1’. For example, I made the top level ‘Birds’ node not selectable by setting the boolean to 0. I think that selecting the ‘Bird’ level isn’t useful because it creates a huge gallery.
The user edits this file as desired, and saves it. When he closes the program, the JSON file is created. Changes from the last session are remembered by the program.
I realize this is crude and old fashioned and doesn’t have a nice GUI, install wizard, registry variables, etc, but it is all I had time to do.
This section has some program details. It is of little interest to anybody but me 🙂 .
There is a GalleryNode object for each node in the browser tree. This object has information about the node (e.g. the level in the hierarchy, the keyword associated with it, the descriptive text associated with it, a pointer to the parent node), and a list of GalleryNode objects for each of its sub-nodes. The constructor of this object reads the Keywords file and recursively creates and populates all of the nodes in the browser tree, so the entire tree can be traversed from the top level, or Master, node. For example, the constructor calls ‘readNodeWithSubnodes()’. This reads the current line to get the Keyword. The level of the keyword is computed by the number of tabs. It also gets sub-nodes, if there are any. For each subnode, it calls ‘readNodeWithSubnodes’ again. This happens recursively down the tree hierarchy. So, calling readNodeWithSubnodes once at the top level objects creates the entire tree. The constructor for the Master GalleryNode object also allows the user to edit the file with the browser customizations. The customizations are implemented with a C++ standard library ‘map’, which maps the keyword to the three parameters used to customize the browser (as described above).
The constructor for the Master node first reads the Keywords file and creates the hierarchy. Then it reads the file with the customizations, and writes it out again with any new keywords that were added. It then allows the user to change the customizations by popping up an editor with the file. The user saves his customizations and closes the editor. The constructor then reads the customization file again to update the modification map with the changes that the user made.
The main program then calls a member function to modify the browser hierarchy. This function walks through the tree and applies the modifications from the modification ‘map’.
Finally, a member function is called to write out the JSON file.
Both of those functions (the one to modify the browser tree and the one to write the JSON file) go recursively through the browser tree the same way the constructor does, as described above.
- The main problem is that the Keywords in Lightroom aren’t synchronized with the Tags in the Nextgen Gallery. When I download a photos from Lightroom to the website, all of the Keywords are used as Tags on the photos. So they start out synchronized. However, if I change Keywords in Lightroom, then I have to manually change the tags on the photographs on the website. Fortunately, Nextgen has a nice GUI to bulk change tags. Also, so far I haven’t changed tags much.
- I did’t start using Lightroom when I started the web site, so there may be some differences in the tags. I think I’ve fixed them all, but may still find some.
- I don’t publish all my photos on the website, so there may be some keywords on Lightroom that don’t have photos on the website. This shows up on the photo browser as a ‘dead’ node; when you click on the node you don’t get a gallery, since there are no pictures with that tag. I can fix this by ‘skipping’ that Keyword, as I described above (the modify map and boolean indicating to skip a node). However, there may be some that I missed.