Vimeo

The Vimeo integration for Agility CMS allow editors to seamlessly associate Vimeo videos with their Agility content. 

Vimeo integration with Agility CMS

Features

  • Support a content-first methodology by adding metadata for your videos
  • Keep your content and presentation layer separate, no more embedding videos into HTML
  • Access metadata without having to integrate with the Vimeo API
  • Preview your videos directly in Agility
  • Serve your videos efficiently with built-in transcoding and optimizations via Vimeo

How it Works

The Vimeo integration utilizes a custom field which can be added to any Content Model or Page Module. It renders as a field in the content input form and allows editors to enter a Vimeo ID.

Once a Vimeo video is connected, the metadata for the video including its Title, Description, Thumbnail, Author, Duration and Preview are copied and saved as a value of the field in Agility. This means you can override the Title or Description to be different that the Vimeo's source, and display it how you'd like in your digital solution.

Default State (No Video Selected)

How to use Vimeo with Agility CMS

Video Selected

Selecting a Vimeo video in Agility CMS

Overriding/Refreshing the Title or Description

You can update the Title or Description field and those values will be saved in Agility - associated with the Vimeo video. This allows you to retain your own values related to the video. 

Updating the Title or Description will not update the Title and Description in Vimeo itself.

You can also decide to Refresh the Title and Description to pull the latest values from Vimeo by clicking the Refresh button.

Requirements

In order to use this integration, some set up is required.

  • Ensure you have set up Agility CMS instance
  • Install the integration
  • Create Content Models that use the Vimeo custom field
  • Output/render the Vimeo video in your digital solution (i.e. website or app)

Install the Integration

In order to use the Vimeo field, you'll need to register it in your custom fields script file that is connected to your Agility CMS instance.

Log in to your Agility CMS instance and navigate to UI Extensions.

You may or may not already have a Custom Fields Script URL defined. If you have an existing JavaScript file defined, then you'll want to append the following contents to that file:  

var baseUrl = "https://agility.github.io/CustomFields/";
var VimeoVideoFormField = function () {
    var self = this;
  
    self.Label = "Vimeo Video";
    self.ReferenceName = "VimeoVideo";
  
    self.Render = function (options) {
      /// <summary>
      ///  The Render handler for this field.  Create any elements and bindings that you might need, pull down resources.
      /// </summary>
      /// <param name="options" type="ContentManager.Global.CustomInputFieldParams">The options used to render this field.</param>
  
      //set the related fields
      var titleField = "VideoTitle";
  
      //get our base element
      var selector = ".vimeo-video";
      var $pnl = $(selector, options.$elem);
  
      //summary:
      /*
       * -> get the html template to render the selected video (including the iframe)
       *      -> when empty, displays a text field that accepts a video ID
       *      -> template will load an emebed of the video, along with the Title, Description and Thumbnail
       *      -> actions will include: Remove and Refresh
       *
       */
  
      if ($pnl.size() == 0) {
        //pull down the html template and load it into the element
        $.get(baseUrl + "vimeo/vimeo-field.html",
          function (htmlContent) {
            options.$elem.append(htmlContent);
  
            $pnl = $(selector, options.$elem);
  
            //bind our viewmodel to this
            var viewModel = new (function () {
              var self = this;
  
              //our model
              self.defaultBinding = {
                video_id: ko.observable(null),
                title: ko.observable(null),
                description: ko.observable(null),
                html: ko.observable(null),
                thumbnail_url: ko.observable(null),
                duration: ko.observable(null),
                author_name: ko.observable(null),
              };
  
              self.fieldBinding = ko.observable(null);
  
              //init a default if null
              if (
                options.fieldBinding() == null ||
                options.fieldBinding() == ""
              ) {
                var copy = self.defaultBinding;
                self.fieldBinding(copy); //init defaults
              } else {
                //set observables on the existing binding properties
                var existingBinding = ko.mapping.fromJSON(options.fieldBinding());
                self.fieldBinding(existingBinding);
              }
  
              //whenever any sub-property in the fieldBinding changes update the main field binding in the model
              ko.computed(function () {
                return ko.mapping.toJSON(self.fieldBinding);
              }).subscribe(function () {
                var fieldBindingJSON = ko.mapping.toJSON(self.fieldBinding());
                options.fieldBinding(fieldBindingJSON);
              });
  
              self.oEmbedAPI = "https://vimeo.com/api/oembed.json";
  
              self.videoUrlFormat = "https://vimeo.com/##videoKey##";
  
              self.videoUrl = function () {
                //format the request url
                var videoUrl = self.videoUrlFormat.replace(
                  "##videoKey##",
                  self.fieldBinding().video_id()
                );
                return videoUrl;
              };
  
              self.thumbnailUrlSmall = ko.computed(function () {
                //returns a small thumbnail to display in the manager
                var thumb = self.fieldBinding().thumbnail_url();
  
                if (thumb != null) {
                  thumb = thumb.replace("_1280", "_320");
                }
  
                return thumb;
              });
  
              self.formattedDuration = ko.computed(function () {
                //returns a formatted duration
  
                var duration = self.fieldBinding().duration();
  
                if (duration != null) {
                  duration = duration + " (seconds)";
                }
  
                return duration;
              });
  
              self.removeVideo = function () {
                //confirms if user wants to remove video, if so clear all values
                ContentManager.ViewModels.Navigation.messages().show(
                  "Do you wish to remove this Video?",
                  "Remove Video",
                  ContentManager.Global.MessageType.Question,
                  [
                    {
                      name: "Remove",
                      defaultAction: true,
                      callback: function () {
                        self.fieldBinding().title(null);
                        self.fieldBinding().description(null);
                        self.fieldBinding().html(null);
                        self.fieldBinding().thumbnail_url(null);
                        self.fieldBinding().video_id(null);
                        self.fieldBinding().duration(null);
                        self.fieldBinding().author_name(null);
                      },
                    },
                    {
                      name: "Cancel",
                      cancelAction: true,
                      callback: function () {
                        //do nothing...
                      },
                    },
                  ]
                );
              };
  
              self.isVideoSet = ko.computed(function () {
                if (
                  self.fieldBinding().video_id() != null &&
                  self.fieldBinding().html() != null
                ) {
                  return true;
                } else {
                  return false;
                }
              });
  
              self.refreshVideo = function () {
                ContentManager.ViewModels.Navigation.messages().show(
                  "Refreshing will overwrite all Video data in Agility with the latest content from Vimeo. Are you sure you want to refresh the content?",
                  "Refresh Video",
                  ContentManager.Global.MessageType.Question,
                  [
                    {
                      name: "Refresh",
                      defaultAction: true,
                      callback: function () {
                        self.getOEmbed();
                      },
                    },
                    {
                      name: "Cancel",
                      cancelAction: true,
                      callback: function () {
                        //do nothing...
                      },
                    },
                  ]
                );
              };
  
              self.getOEmbed = function () {
                var reqUrl =
                  self.oEmbedAPI + "?url=" + self.videoUrl() + "&callback=?";
                $.getJSON(reqUrl, function (response) {
                  //refresh the bindings
                  self.fieldBinding().title(response.title);
                  self.fieldBinding().description(response.description);
                  self.fieldBinding().html(response.html);
                  self.fieldBinding().thumbnail_url(response.thumbnail_url);
                  self.fieldBinding().video_id(response.video_id);
                  self.fieldBinding().duration(response.duration);
                  self.fieldBinding().author_name(response.author_name);
  
                  //look for a Title field in the input form to copy the title to (really only used for the grid view)
                  if (options.contentItem.Values[titleField]) {
                    options.contentItem.Values[titleField](
                      self.fieldBinding().title()
                    );
                  }
                }).fail(function () {
                  ContentManager.ViewModels.Navigation.messages().show(
                    "Could not retrieve a Vimeo Video with the ID of '" +
                      self.fieldBinding().video_id() +
                      "'. Please ensure you have the correct ID and the video has not been deleted.",
                    "Vimeo Error",
                    ContentManager.Global.MessageType.Info,
                    [
                      {
                        name: "OK",
                        defaultAction: true,
                        callback: function () {
                          //do nothing
                        },
                      },
                    ]
                  );
                });
              };
            })();
  
            ko.applyBindings(viewModel, $pnl.get(0));
          }
        );
      }
    };
  };
  
  ContentManager.Global.CustomInputFormFields.push(new VimeoVideoFormField());

If you do not have a Custom Fields Script URL file defined, then create a new JavaScript file (i.e. custom-fields.js) using a text editor and upload this file to any public URL. The easiest way to do this is to upload the file as an Asset in the CMS and reference it by URL.    

Set up a Content Model to use the Vimeo Field

In order to use Vimeo field, you need to have a Content Model or a Page Module in Agility CMS that utilizes this new field type.   

To add the Vimeo Field to any Content Model:

  • Navigate to Models -> Content Models -> {Your Content Model}
  • Click Add Field
    • Field Name: Video
    • Field Type: Custom Field
    • Custom Field Type: Vimeo Video

Next, create some content using your Content Model.

  • Navigate to an instance of your content that is based off your Content Model
  • Click + New
  • Fill out the fieldss
    • On the Video field, enter a Vimeo ID in the Vimeo ID field and click Get Video

Output/Render the Vimeo Video in your Solution

Now that you've set up the field and allow editors to reference Vimeo videos, the next thing you'll need to do is actually output this content in your digital solution (i.e website or app).

Field Value

The value for a Vimeo field will be a JSON string returned from the Content Fetch or GraphQL API.

To use the value, you'll need to parse this into a readable object you can access in your programming langauge. In JavaScript, this can easily be accomplished using the JSON.parse(vimeoFieldValue).

API Response Format

{
  "video_id":572113578,
  "title":"Ride",
  "description":"Hundreds of motorbikes are animated frame by frame in this homage to the iconic motorcycle design and culture of the 1950s and 60s. A rider prepares his bike and departs on an idealised journey into the countryside and into the future.\n\n\"Ride\" is this week's Staff Pick Premiere, read more about it here: https://vimeo.com/blog/post/ride-by-paul-bush/\n\nPaul's website: http://www.paulbushfilms.com/",
  "html":"<iframe src=\"https://player.vimeo.com/video/572113578?h=fec493346d&app_id=122963\" width=\"426\" height=\"240\" frameborder=\"0\" allow=\"autoplay; fullscreen; picture-in-picture\" allowfullscreen title=\"Ride\"></iframe>",
  "thumbnail_url":"https://i.vimeocdn.com/video/1183196783-d62f5191f29b90eca6df87a1bebb7d7b92097b3eb5572edcc0382d3f48b1ba89-d_295x166",
  "duration":346,
  "author_name":"paul bush"
}

Rending a Video Embed

If you want to render a video embed of the Vimeo video, you can use the html property from the value which contains the <iframe> code.