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:Name | Field Type |
---|---|
Search | Custom Field |
Author | Text |
Length | Text |
Thumbnail | Text |
Thumbnail2 | Text |
Published | Text |
URL | Text |
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".
#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
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>
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); } }
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).
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"); }
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); }); } }
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!
What’s the difference between a headless CMS and a hybrid CMS, and which one is best suited for an enterprise?
Maintaining or achieving a global presence requires effective use of resources, time and money. Single-tenant CMS solutions were once the go-to choices for enterprises to reach out to different market...
What is cloud computing, and what benefits does the cloud bring to brands who are entering into the IoT era?