Tag Gallery Page Plugin update: create browser nodes from Adobe Lightroom Keywords

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’).

I created the Tag Gallery Page plugin to provide the capability of viewing photos by browsing a hierarchical tree. I posted about this here: https://www.thelesters.net/2013/wordpress-tag-gallery-page-plugin-using-jstree-and-nextgen-gallery/. The tree built from a file that describes the hierarchy using a notation called Javascript Object Notation (JSON). Up until now, I created this file by hand. Adding a new node to the browser tree required editing the file by copy and pasting an existing node to the correct place in the tree, and then changing some text (the descriptive text that shows up in the browser, and the label used to tag the photos).

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.

PhotoBrowserJson Program

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:

  1. Open Lightroom and export the Keywords to a file. This is done by selecting ‘Metadata -> Export Keywords’ in Lightroom.
  2. Run PhotoBrowserJson (from a shortcut on the desktop). This creates the JSON file needed to build the photo browser.
  3. 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:

  1. 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)’.
  2. 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.
  3. 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.

Program Details

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.

Problems

  1. 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.
  2. 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.
  3. 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.

Update: count leaf nodes

I added a feature to count leaf nodes in the tree, and display the resulting count in parenthesis after the node name. So, what does that mean? I’ll give an example. Consider the following hierarchy in the tree:

Birds (401)


Hummingbirds (25)

Wood Warblers (24)

The numbers in parenthesis says how many leaf nodes under it in the tree. For example, there are 25 species of Humming birds, and a total 401 species of birds (the sum from all the sub-nodes). Which means there are 401 different species that have photographs.

Who cares? I don’t know. I was curious about how many of each, and it was easy to add to my program, so I did it.

For those who are checking, you may find that the numbers don’t always match what’s in the tree. For example, it says ‘Moths (5)’, but there are only 4 species of moths. The number represents the number of photos that I have in my Adobe Lightroom program. This may not match what I decided to display on the website. For example, I have a photo of an unidentified moth in Lightroom that I didn’t put on the website, which is why it says 5 instead of 4.

Program Details: If you were paying attention in the ‘Program Details’ section above, you saw that I call a subroutine to modify the browser hierarchy depending on the users choices (i.e. of nodes to skip or make unselectable). Now, before I call that, I call a new function called ‘CountLeafs’. By the way, if I put this function after the modify browser, then the numbers would match what is on the website (rather than what is in Lightroom).

Share this post:
This entry was posted in Web Development. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • Would you like to receive an email when a new post is added to this site? Click here.

One Trackback

Post a Comment

Your email is never published nor shared. Required fields are marked *

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*
*

  • Would you like to receive an email when a new post is added to this site? Click here.

  • Posts by Month

  • Categories


  • All Posts in Chronological Order: