Lightroom Plugin Development: Adding a URL Handler to a Lightroom Plugin
NOTE: Images with an icon next to them have been artificially shrunk to better fit your screen; click the icon to restore them, in place, to their regular size.

This post is of interest only to Lightroom plugin developers.

Round about Lightroom 3.2, Adobe added support for intercepting “lightroom://” URLs, but have not documented it yet, so I'll do so here. It's particularly useful as part of an OAuth-authentication procedure.

What

You can have your plugin automatically respond to certain “lightroom://” URLs if they are formatted correctly, and if you add appropriate support to your plugin.

URL Form

After registering the appropriate handler in you plugin, as described below, the handler will be invoked when your system browser receives a URL of the form:

lightroom://your.plugin.id

The “your.plugin.id” is the LrToolkitIdentifier in Info.lua. For example, the id for my Flickr plugin is “info.regex.lightroom.export.flickr2”, so it can be set to handle URLs such as:

lightroom://info.regex.lightroom.export.flickr2/blah-blah-blah
lightroom://info.regex.lightroom.export.flickr2?this=blah&that=blah
lightroom://info.regex.lightroom.export.flickr2#foobar

etc.

How

Create a .lua file that returns a table along the lines:

return {
   URLHandler = function(url)
       -- The url string sometimes actually have a double quote as
       -- the first and last byte, so strip just in case.
       url = url:gsub('^"(.*)"$', "%1")

       -- Work with url here...
.
.
.
.
.
   end
}

Wrapping the function in a one-element table seems like an odd level of indirection, but that's how it works.

You then add a reference to that file in your Info.lua, as “URLHandler”. If the file is named “MyUrlHandler.lua”, for example, the reference in Info.lua would look like:

return {
   LrToolkitIdentifier = "info.regex.lightroom.export.flickr2",
   LrPluginName        = "jf Flickr",
   LrPluginInfoUrl     = "http://regex.info/blog/lightroom-goodies/flickr",

   LrSdkVersion        = 3.4,
   LrSdkMinimumVersion = 3.4,
.
.
.
.
.
   URLHandler = "MyUrlHandler.lua",
}

Within the URLHandler function, you can access parts of the URL (e.g. in an OAuth situation, the token) and stuff into global variables, and perhaps shut down a dialog that had been open by calling LrDialogs.stopModalWithResult(...).

That last bit seems to be unfortunately necessary... I've found that the handler is not properly invoked in some rare OS/browser combinations, so I feel that to cover all my bases, the plugin must open a dialog to tell the user to paste in their token; if the handler ends up working, the plugin can immediately shut down that dialog so the user is not bothered with it. Usually, that's exactly what happens, and it happens so quickly that the user never even sees the dialog.

I don't think Adobe's plugins do this, so maybe the problem has been on my end, but I thought I'd mention it because this is what my plugins do.


All 11 comments so far, oldest first...

Hot tip – many possibilities…

— comment by Rob Cole on January 17th, 2012 at 5:37pm JST (12 years, 3 months ago) comment permalink

For those trying this out, you will need to check whether the URL supplied to your handler is surrounded in double quotes. I don’t think it always is so its worth explicitly checking before you try to process the URL received.

Good point, Matt, thanks, I should have mentioned that. I’ll go back and update the post to include it. —Jeffrey

— comment by Matt Dawson on January 18th, 2012 at 7:02pm JST (12 years, 3 months ago) comment permalink

I take it this is for one-way communication only, right? i.e. no way for plugin to respond and have it be heard(?)

I’m not quite sure what you mean… a plugin can open dialogs, launch applications, and cause web pages to load, so that’s one way to be heard… —Jeffrey

— comment by Rob Cole on January 19th, 2012 at 4:49am JST (12 years, 3 months ago) comment permalink

Well, if you issue an http “get”, then you can read a response. So, if a web-app issued a lightroom://… url, would it possible to know if the plugin is disabled, and hence the url fell on deaf ears? Would it be possible for a web-app to issue a lightroom url that requests a bunch of info from a plugin for use in the web-app?

From SF, CA, USA

Ah, I see, sorry, I was looking at it from the wrong point of view. No, I don’t see any way for the issuer of the lightroom:// url to get any follow-on information (including even whether Lightroom is installed) without going through all kinds of hoops of passing something like a session ID one way, then waiting for a response on some other avenue agreed upon in advance by the issuer and the plugin. —Jeffrey

— comment by Rob Cole on January 19th, 2012 at 7:29am JST (12 years, 3 months ago) comment permalink

This is the kind of thing that I wish Adobe would touch on/include in their SDK. Hopefully it’s included in Lr4 SDK.

It’s a small thing, but makes things a lot easier for end users.

Thanks, Jeffrey!

— comment by Kyle on January 21st, 2012 at 2:08pm JST (12 years, 3 months ago) comment permalink

Thanks for posting this how-to, Jeffrey! The process worked fine on my Win XP box running Firefox as my default browser. However, when I tried it with Internet Explorer 8, IE complained “Internet Explorer cannot display the webpage”. Do you have any insight into how Lightroom defines itself as a handler for “lightroom://…” URLs so I can see about making this work across-the-board? Is this one of those “…rare OS/browser combinations” you’re talking about (doesn’t seem that rare to me, though 😉 )?

Again, thanks a bunch for documenting this!

-Don

Unfortunately, my “insight” in this area extends to “try reinstalling Lightroom, and I bet it’ll work”. I’d think it should work even after switching default browsers, but perhaps that requires a Lr reinstall. —Jeffrey

— comment by Don McKee on April 7th, 2012 at 2:11am JST (12 years ago) comment permalink

Just to follow up for anyone else happening by, I’ve worked around the problems I was having with IE. I had been having the external site that I was authenticating with respond directly with my “lightroom://…” callback URL (via HTTP 302 redirect). IE didn’t like this and displayed an error page.

I discovered that IE would work correctly if I first directed it to a web page containing a “meta refresh” tag with my “lightroom://…” URL (or a user-clickable link). So, I changed things up to have the external site redirect to a web page on my site containing, among other stuff, one line of PHP script to dynamically build my Lightroom callback URL with the parameters passed from the external site.

Discounting the fact that my plug-in is no longer completely self-contained, this workaround is sort of a Good Thing because my intermediate web page has verbiage and screen shots about dealing with the various application launch dialogs that may be encountered.

-Don

— comment by Don McKee on April 13th, 2012 at 8:01am JST (12 years ago) comment permalink

For those wanting an example of a working plugin which uses a url handler:

http://www.robcole.com/Rob/ProductsAndServices/CookmarksLrPlugin

PS – I haven’t had any problems using the links via IE – I’d be curious if anybody else has success or failure.

Rob

— comment by Rob Cole on April 13th, 2012 at 10:47pm JST (12 years ago) comment permalink

Thank you very much! Exactly what I am looking for. I blame Adobe for not documenting this.

— comment by Kent Peifeng Ke on October 18th, 2014 at 9:23pm JST (9 years, 6 months ago) comment permalink

Adobe documented it in the pdf guide (SDK 5), albeit not very thoroughly – look for ‘URLHandler’.

— comment by Rob Cole on October 19th, 2014 at 11:01am JST (9 years, 6 months ago) comment permalink

Hi,

One question i couldn’t figure out yet: Do you know if there are any default URLHandlers already registered from Lightroom itself?

For example i’d like to have a link that opens a selection of images in LR, if there would be something like a “filter” URL Handler, i wouldn’t even need to develop a plugin and could just use something like “lightroom://filter?stringtofilterby” to open my selection.

Thanks very much for the article!

No, there’s nothing like that, sorry, you’d have to build a plugin. —Jeffrey

— comment by Claudio Rimann on January 15th, 2015 at 11:03pm JST (9 years, 3 months ago) comment permalink
Leave a comment...


All comments are invisible to others until Jeffrey approves them.

Please mention what part of the world you're writing from, if you don't mind. It's always interesting to see where people are visiting from.

IMPORTANT:I'm mostly retired, so I don't check comments often anymore, sorry.


You can use basic HTML; be sure to close tags properly.

Subscribe without commenting