SLB 2.0: Beta 7
Simple Lightbox 2.0 is coming along nicely. It’s been in beta for a while, but thanks to our brave testers, it has improved by leaps and bounds in each release.
Beta 7 is a turning point for SLB in multiple ways.
Git Out
SLB has recently been migrated over to Git, which I’m very happy about. Among other things, Git facilitates a workflow that allow easy experimentation and fast iteration. Working on new features is far more controlled and manageable as a result.
SLB’s entire Git repository has also been published on GitHub. GitHub makes it easy to collaborate on projects using things like forking and pull requests. I initially published SLB’s Master branch to give users easy access to new releases. Later, I bit the bullet and also published SLB’s Development branch. It’s a little uncomfortable putting my raw code out there for you to see, but it’s ideal for anyone who wants to test the bleeding edge or wants to get involved in development.
All of this was actually possible since Beta 5; the big difference starting with Beta 7 is that I’ve optimized my workflow so that I can prepare releases far more easily. For example, Beta 7 has been released, but it’s not done. There are several new features planned for this phase, but I did not want to wait until they were all done before you had access to them. As a result, Beta 7 is being released in multiple stages. Once a new feature is done, it’s heading out into the big world for all to test it. Young features are impatient– they don’t want to wait for their brother and sister features to be ready.
What this means for you: More frequent updates. (Why didn’t you just say that? Geez.)
Content Handlers
One of the major features of SLB 2.0 is support for multiple content types. Why should images have a monopoly on lightboxes? What about videos, forms, and even tweets?
SLB 2.0 was built from the ground up to support multiple content types, and Beta 7 provides an API for developers to add support for any type of content quickly and easily.
What this means for you: Any type of content can be displayed in a lightbox. (Didn’t I just say that? Really…)
Even SLB’s default content types (e.g. images) use the new Content Handler API:
$handlers->add('image', array( 'match' => 'match_image', 'client_script' => 'handler.image.js' ));
Match
The match
property specifies the callback function used to determine if a link matches this content type. The callback does not have to be anything fancy; for example, here’s the callback to match image links:
/** * Matches image URIs * @param string $uri URI to match * @return bool TRUE if URI is image */ public function match_image($uri) { return ( $this->util->has_file_extension($uri, array('jpg', 'jpeg', 'jpe', 'jfif', 'jif', 'gif', 'png')) ) ? true : false; }
Client Script
The client_script
property specifies a JavaScript file to load in the browser for client-side functionality. This controls things such as how the content is rendered in the lightbox.
The file path provided in client_script
is relative to WordPress’ plugins directory.
The client script code needs to return an object which is added to the content handler. Here’s the client script for images:
(function($) { return { render: function(item) { var dfr = $.Deferred(); //Create image object var img = new Image(); var type = this; //Set load event var handler = function(e) { //Save Data item.set_data(this); //Set attributes var dim = {'width': this.width, 'height': this.height}; item.set_attribute('dimensions', dim); //Build output var out = $('<img />', {'src': item.get_uri()}); //Resolve deferred dfr.resolve(out); }; //Attach event handler if ( img.addEventListener ) { img.addEventListener('load', handler, false); } else if ( img.attachEvent ) { img.attachEvent('onload', handler); } else { handler(img); } //Load image img.src = item.get_uri(); //Return promise return dfr.promise(); } } })(jQuery)
Register
All that’s left is to register the new content type at the appropriate time:
/** * Add custom content handler(s) * @param object $handlers Content Handlers */ public function my_custom_content_handler($handlers) { $handlers->add('handler-id', array ( 'match' => 'match_callback', 'client_script' => 'path-to-handler/handler.handler-id.js' )); } //Hook into content handler initialization add_action('slb_content_handlers_init', 'my_custom_content_handler');
That’s all there is to it! When links are processed on the server, the registered content handlers are cycled through until a match is found and assigned to the link. To make things as fast as possible, only the content handlers that have been matched to a link will be loaded into the browser.
Priorities
Content handlers can also be prioritized so that a handler can be evaluated before other handlers. For example, if you wanted to create a custom handler for Flickr images, then you would want links to be matched against this handler before the standard image content handler.
Setting a content handler’s priority is easy and follows the example of WordPress’ own add_action()
/add_filter()
functions. That is, by default, all handlers have a priority of 10
. If a handler should be evaluated earlier, use a lower number (e.g. 1-9). Conversely, if a handler should be evaluated later, use a higher number (e.g. 11+). All content handlers with the same priority will be evaluated in the order that they were registered.
Basically, content handlers are added like so:
$handlers->add($id, $properties, [$priority]);
Here’s an example of registering a content handler with a high priority:
/** * Register content handler for Flickr images * @param object $handlers Content Handlers */ public function register_flickr_handler($handlers) { $args = array ( 'match' => 'match_flickr', 'client_script' => 'path-to-handler/handler.flickr.js' ); $handlers->add('flickr', $args, 5); } //Hook into content handler initialization add_action('slb_content_handlers_init', 'register_flickr_handler');
The Content Handler API is quite robust and new handlers can easily be added to SLB!
Template Tags
Template tags also get a shiny new API in this update. Adding your own template tags is now easier than ever.
$template_tags->add('tag-name', array( 'client_script' => 'path-to-file/tag.tag-name.js' ));
Client Script
Like content handlers, template tags have a client_script
property that specifies the JavaScript file that will be loaded in the browser to handle a template tag’s client-side functionality. This controls how a template tag is rendered in the browser.
The file path provided in client_script
is relative to WordPress’ plugins directory.
The code in this file returns an object which is added to the template tag. Here’s the client script for the {{item}}
template tag:
(function($) { return { render: function(item, tag) { var dfr = $.Deferred(); var m = 'get_' + tag.get_prop(); var ret = ( this.util.is_method(item, m) ) ? item[m]() : item.get_attribute(tag.get_prop(), ''); if ( this.util.is_promise(ret) ) { ret.done(function(output) { dfr.resolve(output); }); } else { dfr.resolve(ret); } return dfr.promise(); } } })(jQuery);
Register
Once the client script is ready, all that’s left is to register the new content type at the appropriate time:
/** * Add custom template tag(s) * @param obj $tags Template tags collection */ public function my_custom_template_tags($tags) { $tags->add('mytag', array( 'client_script' => 'path-to-file/tag.mytag.js' )); } //Add hook to register custom template tags add_action('slb_template_tags_init', 'my_custom_template_tags');
If that seemed really simple, that’s because it is! In-depth documentation on how to develop custom template tags is forthcoming, but the focus for this release was getting the API in order. Thankfully, the work done the content handler API made this pretty simple to do and much of the code is shared between these APIs.
Themes
The Theme API has also been updated to align with the other component APIs in this release.
$themes->add('theme-id', array ( 'name' => 'Theme Name', 'parent' => 'parent-theme', 'layout' => 'path-to-file/layout.html', 'client_script' => 'path-to-file/client.js', 'client_style' => 'path-to-file/style.css', ));
Name
The name
property defines the theme’s display name. The name is displayed in the theme selection list.
Parent
Themes can optionally have a parent that they inherit the properties of. This makes customizing existing themes incredibly simple. For example, if you want to update the CSS of SLB’s default theme (ID: slb_default
), you would simply add a new theme, but only define the client_style
parameter:
$themes->add('my-child-theme', array ( 'name' => 'My Child Theme', 'parent' => 'slb_default', 'client_style' => 'path-to-file/my-style.css', ));
Layout
The layout
is a file that contains the HTML for the theme’s lightbox. The layout contains standard HTML and template tags that control how an item’s data is displayed when viewed in the lightbox.
Client Script
Like the other components, themes have a client_script
property that specifies the JavaScript file that will be loaded in the browser to handle a theme’s client-side functionality. This controls a theme’s capabilities such as animations, etc.
The file path provided in client_script
is relative to WordPress’ plugins directory.
Client Style
Finally, the client_style
property specifies a CSS file for the theme.
Just like the client_script
property (and all other file paths in these APIs), the file path provided in client_style
is relative to WordPress’ plugins directory.
Register
Theme’s are registered just like other components:
/** * Add custom theme(s) * @param obj $themes Themes collection */ function my_custom_theme($themes) { $themes->add('theme-id', array ( 'name' => 'Theme Name', 'parent' => 'parent-theme', 'layout' => 'path-to-file/layout.html', 'client_script' => 'path-to-file/client.js', 'client_style' => 'path-to-file/style.css', )); } //Add hook to register custom theme add_action('slb_themes_init', 'my_custom_theme');
Simple!
Get the Beta
Want to get access to the next generation of Simple Lightbox and be part of its progress? Get the beta now and leave feedback!
Next Steps
SLB 2.0 Beta 7 was a big update. Simple Lightbox 2.0 is now feature complete and from here we’re going to move straight into release candidates.