Ember and Cloudinary
Recently I discovered Cloudinary, if you don’t know them I suggest you check them out at https://cloudinary.com/. They offer a multitude of libraries, including Ruby on Rails, PHP and a full featured jQuery plugin with upload support.
A new client asked if I could implement gallery functionality in their EmberJS app. I already implemented company logo uploads using Cloudinary so adding gallery functionality shouldn’t be to big of a problem. I decided to use the jQuery plugin as a base. My first try of simply including the jquery plugin into my EmberJS template failed. Why? Well those Handlebar templates are located in script tags and since they’re not part of the body on jQuerys dom ready they’re ignored without any errors to show for.
So how do we get around this problem? Well the simple answer is using the didInsertElement callback on the Ember.View object (no worries I’ll get into more details). This callback is called when an EmberView is rendered and inserted into the dom. Good place to do plugin init work. So for most plugins you’re good. Just wrap the part of your dom in an data-template-name and attach an Ember.View instance to it.
However not every jQuery plugin works that way, many use the data-* attributes to initialize. A much cleaner way of integrating Javascript based functionality into the dom. The Cloudinary jQuery plugin works like this. So after a little doubting I just decided to read the source code of the Cloudinary jQuery plugin and see if I could locate where the piece of jQuery that matched those input elements was located and if it would be wrapped in a nice method I could call. I located the piece of code that does the search and calls the init method on the result of the selector. It wasn’t wrapped in a nice method so I just had to duplicate the selector in my Ember.View. Not a really big deal to be honest. Alright, so how did I do it? I found the init code in jquery.cloudinary.js on line 23 (subject to change over time)
1
$("input.cloudinary-fileupload[type=file]").cloudinary_fileupload();
Easy enough! So lets create a Handlebar template with a data-template-name attribute
1
2
3
4
5
6
<script data-template-name="gallery-upload" type="text/x-handlebars">
<form>
<?php echo cl_image_upload_tag('image_id',
array("callback" => get_cors_location())); ?>
</form>
</script>
Yes I’m mixing in the php helper here. The PHP helper just generated an input field with all your specific Cloudinary config in it (incidentally something I wasn’t going to share with you guys anyway). The get_cors_location() function returns the url of the cors html file. Just read up on the getting started documentation from Cloudinary for your programming language when this all means nothing to you. Okay! Almost there, now create your Ember.View.
1
2
3
4
5
6
7
8
App.GalleryUpload = Ember.View.create(
{
templateName: 'gallery-upload',
didInsertElement: function() {
this.$("input.cloudinary-fileupload[type=file]")
.cloudinary_fileupload();
}
});
Also just a small piece of code. As explained earlier the only thing of real importance here is the jquery selector and subsequent call to the cloudinary_fileupload() function. This is the part that will make the file input field generated by the PHP helper above into a Cloudinary upload field. Last step is including your view in the right place for your application.
1
view App.GalleryUpload
Reload your Ember app in your browser and you’ll see an upload form. Just pick a random image and the only thing you have to do is select it or drag it onto the form. When you keep your debugging console open you’ll see it does a post to Cloudinary and uploads your file. How easy is that! When you inspect to form when the upload is done you’ll see that an extra hidden input was added with the url to your asset on Cloudinary.
For more details please read the jQuery plugin documentation on the Cloudinary website http://cloudinary.com/documentation/jquery_image_upload
Suggestions, tips or flames? Please leave a comment. ♯browser ♯cloudinary ♯frontend ♯jquery ♯html5 ♯javascript ♯coding ♯ember