Developing a Dynamic Vimeo Search Widget

$URLMapContent.title

Developing a Dynamic Vimeo Search Widget Posted: 03.16.2015

This article will walk you through how to build a dynamic Vimeo widget in dotCMS. We will use the Vimeo API to search for videos on Vimeo and Dojo to set the fields in our Content Type. In this article you will learn how to search asynchronously for Vimeo videos, parse the JSON response and get the attributes you need such as video URL, author, play length, thumbnail, etc., and set those values in your widget.

Before we get started, lets first download the completed example files:

Creating the Widget Content Type [ Open Content Type Screen Shot ]

  1. Click on the Content Type tab in the authoring environment of dotCMS.
  2. Click the Add New Content Type button
  3. Make sure you select the "Widget" type and name your Widget Content Type before saving it.
  4. Now you will need to create the following fields/data types in your new Widget Content Type.
Name Field Type
Search Custom Field
Author Text
Length Text
Thumbnail Text
Thumbnail2 Text
Published Text
URL Text

NOTE: if you name your fields differently from the example shown, you’ll need to change the variable names in the JavaScript function setFields.

Creating the Custom Search field (vimeo-search.vtl)

When creating custom fields the first thing I like to do is to create a blank VTL file on my desktop. I then upload the VTL to the dotCMS server I’m working on. In this example, I created a VTL file called vimeo-search.vtl and uploaded it to the /application/vtl/custom-fields/ folder on the dotCMS 3.0 starter. Once the VTL file is on the server, it needs to be included in the custom field called "Search".

  1. Go to the widget you just created and click on the pencil icon next to the “Search” label.
  2. Insert the dotParse code into the Value field. In this example, the dotParse code would look like this
#dotParse("/application/vtl/custom-fields/vimeo-search.vtl")
NOTE: if you have saved your VTL in a different directory you will need to change the pathing.

Now that we have our VTL on the server and it is included in our custom field, we need to connect to the server through WebDav (if you can’t use webdav, you can edit the VTL through the dotCMS authoring interface). Open the VTL file (vimeo-search.vtl) in your preferred text editor (I use Aptana). NOTE:  To learn more about WebDav visit: http://dotcms.com/docs/latest/WebDAV


Creating the Search Box

Now we need to create the search box so that our users can filter by keywords. Here is the code we need.

<input name="searchStr" id="inputSearchStrId" type="text" dojoType="dijit.form.TextBox" style="width:400px;" placeHolder="Search for Videos on Vimeo" />
<button dojoType="dijit.form.Button" onClick="searchClicked()" iconClass="searchIcon">Search</button

This will create a Dojo text box and button. We included the search icon in the button and have taken advantage of the Dojo placeHolder feature in the text box as well. When the user clicks the search button it will call the JavaScript function "searchClicked".

We should also create two more DIVs that will be used later in this article.

The first DIV we need to create will be used to display our results. In this example I used a Dojo dialog box for my results.

<div id="videoResultsDiv" dojoType="dijit.Dialog" style="display: none">
  <div id="myResults"></div>
</div>

The Second DIV will display a thumbnail of the video that will allow the user to preview the video before saving.

<div class="imageWrapper">
  <a href="#" onClick="playVideo()" class="playButton"></a>
  <div id="thumbnailImage"></div>
</div>

Creating the function for the Dynamic Search Request

Setting up a dynamic search request with the Vimeo API:

function searchClicked() {
  // You need to request a Vimeo token, more info: https://developer.vimeo.com/api/authentication
  var vimeoToken = "XXXXXXXXXXXXXXXXXXXX";
  var mySearch = document.getElementById("inputSearchStrId").value;
  if (mySearch.length < 1) {
    alert("Please Enter Search Term");
    document.getElementById('inputSearchStrId').focus();
  } else {
    var url = 'https://api.vimeo.com/videos?query=' + mySearch + '&access_token=' + vimeoToken;

    var reqArgs = {
      url: url,
        headers: {
        "X-Requested-With": ""
      },
      load: function(data) {
        showMyVideos(JSON.parse(data));
      },
      error: function(error) {
        alert('Something is wrong with Vimeo\'s API, try again later');
      }
    }
    dojo.xhrGet(reqArgs);
  }
}
You need to request a Vimeo token, more info: https://developer.vimeo.com/api/authentication
  1. Get the value of the search box (inputSearchStrId)
  2. Make sure the user has typed something into the search box. If they have not, prompt them with an Alert.
  3. Once we have the search string we can create the JavaScript element that will return the JSON data
  4. We then need to attach the script to the current page. This will submit an asynchronous search request.
  5. After the JSON data is returned, we call a function showMyVideos() to parse the results (we had to parse the data into a JSON object because it came in as a string)
  6. You can see this function also opens the Dojo dialog called (videoResultsDiv) we created earlier. This is where we will push the results once we have parsed the data.

Parsing the Results

The search request (searchClicked) will call asynchronously showMyVideos(JSON.parse(data)) when the results are returned. Now we need to parse and output the attributes we need from the response data. Here is the code we use to do that:

function showMyVideos(results) {
  dijit.byId('videoResultsDiv').show();
  var entries = results.data || [];
  var html = ['<ul>'];
  for (var i = 0; i < entries.length; i++) {
    var entry = entries[i];
    var title = entry.name;
    var lnk = entry.link;
    var published = entry.created_time.replace("+", ".");
    var length = formatDuration(entry.duration);
    var by = entry.user.name;
    var picSm = entry.pictures.sizes[0].link;
    var picLg = entry.pictures.sizes[entry.pictures.sizes.length - 1].link;
    var passVar = " ' " + lnk + " ' , ' " + picSm + "' , '" + picLg + "' , '" + title + "' , '" + by + "' , '" + length + "' , '" + published + " ' ";
    html.push('<li onclick=\"setFields(', passVar , ');\"><span style=\"background:url(', picSm, ') no-repeat;\"></span><b>' , title , '</b><br><b>Author: </b>', by ,'<br><b>Length: </b>', length, '<br><b>Published: </b>', published , '<br><b>Views: </b>', playCount ,'</li>');
  }
  html.push('</ul>');
  document.getElementById('myResults').innerHTML = html.join('');
}

We can traverse the JSON data like you traverse objects, arrays etc., much the same way that variables are used in Java. This is because JSON is embedded into the JavaScript language. Were the response in XML, you would have to implement a parser yourself.

The last thing this function does is join the parsed results to the div (myResults).


Capturing the User's Selection

Now we need to populate the variables in our Widget Content Type based on the user’s selection. In the function above (showMyVideos), we attached an onClick event to each <li> that will call the (setFields) function and pass it the variables we parse from the JSON object. This is what that function looks like:

function setFields(lnk, picSm, picLg, title, by, length, published){
  dijit.byId('videoResultsDiv').hide();
  dojo.byId("widgetTitle").value=title;
  dojo.byId("author").value=by;
  dojo.byId("length").value=length;
  dojo.byId("thumbnail").value=picSm;
  dojo.byId("thumbnail2").value=picLg;
  dojo.byId("published").value=published;
  dojo.byId("url").value=lnk;
  dojo.byId("inputSearchStrId").value="";
  dojo.style(dojo.byId("thumbnailImage"), "background", "url(" + picLg + ") center center no-repeat");
}
NOTE: The last line of the function sets the background image of the thumbnailImage Div

The Finishing Touches

We're almost done! Lastly, we need to write the function that will create a dialog window and play the video. This will take a little JavaScript string formatting because the data provided by the Vimeo API does not include the correct URL for the embed video url. However, no worries, the code is very simple.

We need to change our URL string from this: https://vimeo.com/32796535

To This: https://player.vimeo.com/video/32796535

So we grab the url string:

var y = dojo.byId("url").value;

And then we remove the whole Vimeo basic url:

var videoId = y.replace("https://vimeo.com/", "");

And finally, just create a new url string that we'll use in the iframe:

var videoEmbdedUrl = "https://player.vimeo.com/video/" + videoId;

Now we need to programmatically create a Dojo dialog window that will play the video and pass it the url (y). We need to do this programmatically because we need to destroy the element from the DOM on close. If you close it or hide it, without destroying the element from the DOM, the video will continue to play even though it is hidden from view.

Here is the complete function:

function playVideo() {
  var y = dojo.byId("url").value;
  if (y.length < 1) {
    document.getElementById('inputSearchStrId').focus();
  } else {
    var videoId = y.replace("https://vimeo.com/", "");
    var videoEmbdedUrl = "https://player.vimeo.com/video/" + videoId;
    var videoPlayer = new dijit.Dialog({
      title: "dotCMS Player",
      content: "<iframe src='" + videoEmbdedUrl + "?color='ffffff' width='500' height='281' frameborder='0' webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>",
      loadingMessage: "Loading..."
    });
    videoPlayer.show();
    videoPlayer.connect(videoPlayer, 'onHide', function() {
      setTimeout(function() { videoPlayer.destroyRecursive(); }, 0);
    });
  }
}

Conclusion

If you’re using the new dotCMS starter that came with dotCMS 3.0+ versions, you can add this code to the the Widget Code field. This will allow you to place your video in any container on your site using the PrettyPhoto jQuery plugin that ships with the starter.

<div class="feat-video">
  <a href="$url" class="hoverVideo prettyPhoto" title="$!{widgetTitle}" style="width:100%">
    #if ($UtilMethods.isSet($thumbnail2))
      <img src="$!{thumbnail2}" alt="$!{widgetTitle}" style="width:98%;margin:0 6px 0 0;"/>
    #else
      $!{widgetTitle}
    #end
  </a>
</div>

Now it's time to enjoy your Vimeo videos on your dotCMS instance!



New report from Digital Clarity Group notes that a majority of digital marketing teams don’t or can’t use all the software capabilities they have, creating “shelfware” or “underused” software. Gain fresh perspective on the challenges facing digital marketers. Download Now.