-
Notifications
You must be signed in to change notification settings - Fork 32
Wistia widget #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Wistia widget #88
Changes from all commits
aa87bfc
2088afe
38d08bd
75d3f1f
1c2b35b
5680d84
a153eb6
203762b
ba04c32
e29a223
6a38cc1
b13a0e7
1ba3aa6
e5b6569
b35346f
8e3c1d3
249531f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,4 @@ node_modules | |
gh-pages | ||
dist | ||
custom.mk | ||
.idea |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
.env |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
The MIT License (MIT) | ||
|
||
Copyright (c) 2015 Contentful | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
Wistia Widget | ||
------------- | ||
|
||
The wistia widget loads videos from a [project](http://wistia.com/doc/projects) on [wistia](http://wistia.com/) into the Contentful UI. A video can be easily previewed, selected and then stored as part of your content. In this example widget we store the video embed URL in Contentful so the video can be embedded easily. | ||
|
||
 | ||
|
||
### Requirements | ||
|
||
- Contentful | ||
- a space to use the widget and the space id | ||
- an api key for Contentful's Mangement API | ||
- Wistia | ||
- an account with [wistia](http://wistia.com/) | ||
- an API key from wistia, preferably with read-only permissions only | ||
- Local machine | ||
- npm installed and configured on your system | ||
|
||
### Installation | ||
|
||
- Clone the repository or download the repo as a [zip](https://github.com/contentful/widget-sdk/archive/master.zip) | ||
```bash | ||
git clone [email protected]:contentful/widget-sdk.git | ||
``` | ||
- Navigate into widget folder | ||
```bash | ||
cd examples/wistia | ||
``` | ||
- Install dependencies | ||
```bash | ||
npm install | ||
``` | ||
- Create a configuration file with your credentials for Contentful | ||
```bash | ||
touch .env | ||
echo "SPACE_ID={YOUR-SPACE-ID}" >> .env | ||
echo "CONTENTFUL_MANAGEMENT_ACCESS_TOKEN={YOUR-MANAGEMENT-TOKEN}" >> .env | ||
|
||
``` | ||
and replace space ID, management token and port accordingly. | ||
|
||
### Upload the widget to Contentful | ||
|
||
- Compile the bundle (index.html) which we are going to upload to our space | ||
```bash | ||
npm run bundle | ||
``` | ||
- Create the widget in your space on Contentful | ||
```bash | ||
npm run widget:create | ||
``` | ||
|
||
### Update the widget | ||
|
||
- Make sure to update your bundle with webpack | ||
- Update the widget in your space on Contentful | ||
```bash | ||
npm run bundle | ||
npm run widget:update | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Insert |
||
``` | ||
|
||
### Local development | ||
|
||
- Start a local server (replace your port if needed) | ||
```bash | ||
python -m SimpleHTTPServer 3030 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I will remove the widget:serve as it is not working correctly with the html plugin I use with webpack. |
||
``` | ||
- Tell contentful to render the widget from your local machine | ||
```bash | ||
npm run bundle | ||
npm run widget:dev | ||
``` | ||
|
||
### Using the widget in the Contentful App | ||
|
||
Next, we will enable the widget in the Contentful App for a “Short text” field so that you can see it in action. | ||
|
||
In your space, choose any Content Type with a “Short text” field or create a new one. Then open the “Settings” dialog for a field and switch to the appearance tab. A widget with the name “Wistia video widget” should be visible at the end of the list. (Note that you need to reload the app after you uploaded a widget.) Select the widget from the list and save the Content Type. Finally you can open an entry for that Content Type and see the widget rendered. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
{ | ||
"name": "wistia", | ||
"version": "1.0.0", | ||
"description": "Vistia Widget for contentful", | ||
"main": "./src/app.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"bundle": "webpack", | ||
"widget:create": "better-npm-run widget:create", | ||
"widget:update": "better-npm-run widget:update", | ||
"widget:dev": "better-npm-run widget:dev" | ||
}, | ||
"betterScripts": { | ||
"widget:create": { | ||
"command": "contentful-widget create --space-id $SPACE_ID" | ||
}, | ||
"widget:update": { | ||
"command": "contentful-widget update --space-id $SPACE_ID --force" | ||
}, | ||
"widget:dev": { | ||
"command": "contentful-widget update --space-id $SPACE_ID --force --src 'http://localhost:3030/index.html'" | ||
} | ||
}, | ||
"author": "[email protected]", | ||
"license": "ISC", | ||
"devDependencies": { | ||
"babel-core": "^6.7.2", | ||
"babel-loader": "^6.2.4", | ||
"babel-preset-es2015": "^6.6.0", | ||
"better-npm-run": "0.0.8", | ||
"contentful-widget-cli": "^1.1.3", | ||
"contentful-widget-sdk": "^0.1.1", | ||
"css-loader": "^0.23.1", | ||
"ejs-loader": "^0.2.1", | ||
"html-webpack-plugin": "^2.10.0", | ||
"style-loader": "^0.13.1", | ||
"webpack": "^1.12.14" | ||
}, | ||
"dependencies": { | ||
"axios": "^0.9.1" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import Wistia from './components/wistia'; | ||
import '../../../dist/cf-widget-api.css'; | ||
import './css/styles.css'; | ||
|
||
// Id of project in Wistia. | ||
const WISTIA_PROJECT_ID = 'on2x2ho05v'; | ||
// URL to wistia's api including our read-only API key. | ||
const WISTIA_API_URL = 'https://api.wistia.com/v1/medias.json?api_password=1317a87dbf0a' + | ||
'869f2a7e025c3e2c0c984208c0bc6107dd041108fd3ba2ae782d'; | ||
let sdk = require('contentful-widget-sdk'); | ||
sdk.init(function (widget) { | ||
let wistia = new Wistia(widget, WISTIA_PROJECT_ID, WISTIA_API_URL); | ||
}); | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
import axios from 'axios'; | ||
|
||
export default function (widget, projectId, url) { | ||
|
||
// DOM elements. | ||
const containerEl = document.querySelector('.thumbnails-container'); | ||
const thumbnailsEl = document.querySelector('.thumbnail-items-container'); | ||
const errorEl = document.querySelector('.error'); | ||
const preloaderEl = document.querySelector('.preloader'); | ||
const inputEl = document.getElementById('wistia-video-id'); | ||
let activeThumbnailEl; | ||
|
||
widget.field.onValueChanged(onValueChanged); | ||
|
||
// Resize iframe in Contenful UI. | ||
widget.window.updateHeight(); | ||
|
||
axios.get(url, { | ||
params: { | ||
project_id: projectId | ||
} | ||
}) | ||
.then(response => { | ||
preloaderEl.style.display = 'none'; | ||
containerEl.style.display = 'block'; | ||
|
||
const ejsTemplate = require('ejs!./../templates/video-browser.ejs'); | ||
|
||
thumbnailsEl.innerHTML = ejsTemplate({ | ||
'data': response.data | ||
}); | ||
|
||
// Pass value from Contentful to input element. | ||
inputEl.value = widget.field.getValue(); | ||
|
||
const thumbnailEls = document.querySelectorAll('.thumbnail .btn'); | ||
|
||
for (let i = 0; i < thumbnailEls.length; i++) { | ||
thumbnailEls[i].addEventListener('click', onThumbnailClick); | ||
if (inputEl.value && thumbnailEls[i].dataset.videoId == inputEl.value) { | ||
thumbnailEls[i].classList.add('active'); | ||
} | ||
} | ||
}) | ||
.catch(response => { | ||
preloaderEl.style.display = 'none'; | ||
errorEl.style.display = 'block'; | ||
console.error(response); | ||
}); | ||
|
||
/** | ||
* Calls the callback every time the value of the field is changed by some external event | ||
* (e.g. when multiple editors are working on the same entry). | ||
* @param val The newly changed value. | ||
*/ | ||
function onValueChanged(val) { | ||
inputEl.value = val; | ||
} | ||
|
||
function onThumbnailClick(event) { | ||
if (activeThumbnailEl) { | ||
activeThumbnailEl.classList.remove('active'); | ||
} | ||
event.currentTarget.classList.add('active'); | ||
|
||
const embedId = event.currentTarget.dataset.videoId; | ||
|
||
// Show value in view. | ||
inputEl.value = embedId; | ||
|
||
activeThumbnailEl = event.currentTarget; | ||
|
||
widget.field.setValue(embedId); | ||
} | ||
} | ||
|
||
|
||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
html, body { | ||
height: 440px; | ||
overflow: hidden; | ||
} | ||
.preloader, .error, .thumbnails { | ||
display: none; | ||
} | ||
.thumbnail iframe { | ||
min-height: 120px; | ||
min-width: 200px; | ||
width: 100%; | ||
} | ||
.thumbnail h5 { | ||
max-height: 25px; | ||
overflow: hidden; | ||
} | ||
.thumbnail .btn.active { | ||
pointer-events: none; | ||
} | ||
.thumbnail .btn .active, .thumbnail .btn.active .nonactive { | ||
display: none; | ||
} | ||
.thumbnail .btn .nonactive, .thumbnail .btn.active .active { | ||
display: inline; | ||
} | ||
.thumbnail .btn.active { | ||
pointer-events: none; | ||
} | ||
.container-fluid { | ||
margin: 0; | ||
padding: 0; | ||
} | ||
.panel-body { | ||
max-height: 400px; | ||
overflow: scroll; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<div class="row"> | ||
<div class=" col-xs-12"> | ||
<h3><%= data[0].project.name %></h3> | ||
</div> | ||
<% data.forEach(item => { %> | ||
<div class="col-xs-6 col-sm-4"> | ||
<a href="#"> | ||
<div class="thumbnail"> | ||
<!-- Actual video player --> | ||
<iframe src="https://fast.wistia.net/embed/iframe/<%= | ||
item.hashed_id %>"></iframe> | ||
<div class="caption"> | ||
<h5><%= item.name.length > 35 ? item.name.substr(0, 35) + '...' : item.name %></h5> | ||
<!-- Button to pass selected video to component. --> | ||
<a class="btn btn-primary" role="button" | ||
data-video-id="<%= item.hashed_id %>"><span | ||
class="nonactive">Use video</span><span class="active">Active</span></a> | ||
</div> | ||
</div> | ||
</a> | ||
</div> | ||
<% }); %> | ||
</div> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
<!DOCTYPE html> | ||
<html> | ||
<head> | ||
<meta http-equiv="Content-type" content="text/html; charset=utf-8"/> | ||
<title><%= htmlWebpackPlugin.options.title %></title> | ||
<link rel="stylesheet" | ||
href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" | ||
integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" | ||
crossorigin="anonymous"> | ||
</head> | ||
<body> | ||
<div class="preloader">Loading</div> | ||
<div class="error">Something went wrong loading your videos</div> | ||
<div class="thumbnails-container"> | ||
<div class="container-fluid"> | ||
<div class="panel panel-default"> | ||
<!-- Title of the widget panel. --> | ||
<div class="panel-heading"> | ||
<!-- Inject title from webpack config --> | ||
<h3 class="panel-title"><%= htmlWebpackPlugin.options.title %></h3> | ||
</div> | ||
<div class="panel-body"> | ||
<!-- Input element to render field value. --> | ||
<div class="row"> | ||
<div class=" col-xs-12"> | ||
<div class="input-group"> | ||
<span class="input-group-addon" id="basic-addon3">Wistia video id</span> | ||
<input type="text" class="form-control" id="wistia-video-id" | ||
aria-describedby="basic-addon3"> | ||
</div> | ||
</div> | ||
</div> | ||
<!-- Video tiles in a grid. --> | ||
<div class="thumbnail-items-container"> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
<script><%= compilation.assets[htmlWebpackPlugin.files.js[0].substr(htmlWebpackPlugin.files.publicPath.length)].source() %></script> | ||
</body> | ||
</html> | ||
|
||
|
||
|
||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add some information on how to setup a Content Type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should add that part to the main readme. I checked and we actually do not explain anywhere how to assign a widget to a field...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do in the “getting started” rating widget
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.