- Notifications
You must be signed in to change notification settings - Fork125
Display H5P content without the need for an H5P server
License
tunapanda/h5p-standalone
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
Display H5P content without the need for an H5P server
Source | Info |
---|---|
yarn | yarn add h5p-standalone |
Release | Download latest version here |
Ensure you have an extracted H5P zip file in your workspace folder first. A simple guide on how to extract an H5P zip file is providedhere
The player can be set up either by directly calling the already built scripts and styles in yourHTML
page or usingES6
syntax.
Download the project latest release zipped source code fromhere
Extract the downloaded zipped code in step 1 above
Copy the contents of the
dist
folder into your workspace staticassets
folder (The folder name does not matter. Remember the location for the next step )Add a
div
element in your HTML page where you want to display the H5P content. Thediv
element should have a uniqueid
attribute as compared to all other elements on the same page.<divid='h5p-container'></div>
Include the H5P standalone main script in your HTML page (modify the path location if the files are not in the assets folder)
<scripttype="text/javascript"src="assets/main.bundle.js"></script>
Call the H5P player by providing arguments on where to find a
div
element and the location of the H5P content.constel=document.getElementById('h5p-container');constoptions={h5pJsonPath:'/h5p-folder',frameJs:'/assets/frame.bundle.js',frameCss:'/assets/styles/h5p.css',}newH5PStandalone.H5P(el,options);
A detailed description of the H5P player arguments are provided under theadvance sectionSimple instruction on how to extract H5P zipped file providedhere
Install the player using yarn
yarn add h5p-standalone
Add an element to attach the player
<divid='h5p-container'></div>
initialize the H5P
import{H5P}from'h5p-standalone';// ES6// const { H5P } = require('h5p-standalone'); AMD// const { H5P } = 'H5PStandalone'; // object destructuringconstel=document.getElementById('h5p-container');constoptions={h5pJsonPath:'/h5p-folder',frameJs:'/assets/frame.bundle.js',frameCss:'/assets/styles/h5p.css',};newH5P(el,options);
A detailed description of the H5P player arguments are provided under theadvance section
The standalone H5P player constructor accepts two arguments.
- A HTML element where the H5P iframe will be embedded as the first argument.
- JSON object with the following options :
- Basic options
Option name | Required | Description |
---|---|---|
h5pJsonPath | Yes | Path to the H5P content folder |
frameCss | Yes | URL to the standalone playerh5p.css |
frameJs | Yes | URL to the standalone playerframe.bundle.js |
id | No | Player unique identifier. Randomly generated by default |
librariesPath | No | Path where the player should find the H5P content libraries. Defaults to same ash5pJsonPath |
contentJsonPath | No | Path where the player should find the H5Pcontent.json file. Defaults to{h5pJsonPath}/content/ , |
frame | No | A boolean on whether to show H5P player frame and buttons |
copyright | No | A boolean on whether display copyright button |
export | No | A boolean on whether display a download button. |
icon | No | A boolean on whether display H5P icon |
downloadUrl | No | A path or a url that returns zipped h5p for download. The link is used by H5Pexport button |
fullScreen | No | A boolean on whether to enable the fullscreen button if the browser supports the feature. Default isfalse |
embed | No | A boolean on whether display embed button. Default isfalse . N.B. Setting this option totrue will require anembedCode below. |
embedCode | unlessembed is true | Embed/Iframe code that user can insert on their site to view the same content. Check some caveats to considerbelow |
customCss | No | Path(s) to custom stylesheet file(s) |
customJs | No | Path(s) to custom script file(s) |
xAPIObjectIRI | No | An identifier for a single unique Activity ~ utilized when generating xAPIobject field. Default is page host+pathname |
- User state & data(kindly refer tothis section)
Option name | Required | Description |
---|---|---|
contentUserData | No | User previous content interaction state data. The data should be in JSON string format |
saveFreq | ifcontentUserData orajax.* is set | How often current user engagement content state should be autosaved (in seconds). Default isfalse . |
postUserStatistics | No | Indicates if H5P should post the results once a finish event is triggered. Default isfalse . ****Requiresajax.setFinishedUrl property to be set |
ajax | No | Object required if you need H5P to manage a learner's state |
ajax.setFinishedUrl | No | Url where H5P should post the results once a finish event is triggered. ****RequirespostUserStatistics to be set to true. |
ajax.contentUserDataUrl | No | Endpoint where H5P can manage current user state. ****Requiresuser property to be set |
user | No | Current user data object. |
user.name | Yes | Used as xAPI actor's name |
user.mail | Yes | User email. Uniquely identifies the xAPI actor |
Note:
- One can use absolute URL for
frameCss
,frameJs
, and for other path options(h5pJsonPath
,librariesPath
, &librariesPath
) - Any path that starts with a forward slash
/
is treated as relative to the site root. - Any path starting with a dot is treated to be in respect to the current page directory.
import{H5P}from'h5p-standalone';constel=document.getElementById('h5p-container');constoptions={id:'exercise-one',frameJs:'./frame.bundle.js',frameCss:'./styles/h5p.css',h5pJsonPath:'/path/to/h5p-folder',contentJsonPath:'/path/to/h5p-folder',//content is on same folder level as h5p.jsonlibrariesPath:'/path/to/shared/libaries',//shared libraries pathframe:true,//required to display copyright, embed, & export buttonscopyright:true,export:false,icon:true,downloadUrl:'/path/to/exercise-one.h5p',fullScreen:true,//enable fullscreen buttonembed:true,embedCode:'<iframe width=":w" height=":h" src="https://replacethiswithyoururl.io" frameBorder="0" scrolling="no" styles="width:100%"></iframe>',customCss:['/path/to/some-css.css','/path/to/some-other-css.css'],// custom stylesheetscustomJs:'/path/to/custom-script.js'// custom script};newH5P(el,options).then(()=>{// do stuff});// Or using the async-await syntax (async wrapper function removed for readability) :awaitnewH5P(el,options);
To render multiple H5Ps, your codemust be async aware.
import{H5P}from'h5p-standalone';constplayer1Options={h5pJsonPath:'/h5p/exercise-one',frameJs:'/assets/frame.bundle.js',frameCss:'/assets/styles/h5p.css',};constplayer2Options={h5pJsonPath:'/h5p/exercise-two',frameJs:'/assets/frame.bundle.js',frameCss:'/assets/styles/h5p.css',};constplayer1=newH5P(document.getElementById('h5p-container-1'),player1Options);player1.then(()=>{returnnewH5P(document.getElementById('h5p-container-2'),player2Options);}).then(()=>{// do stuff});// OR (async wrapper function removed for readability)awaitnewH5P(document.getElementById('h5p-container-1'),player1Options);awaitnewH5P(document.getElementById('h5p-container-2'),player2Options);
To listen forxAPI events emitted by the player, you must wait for the player to finish loading and initializing the required content libraries. You can find more info about xAPI events herehttps://h5p.org/documentation/x-api
- Using
then()
method
constel=document.getElementById("h5p-container");constoptions={h5pJsonPath:"/h5p-folder",frameJs:"/assets/frame.bundle.js",frameCss:"/assets/styles/h5p.css",};newH5PStandalone.H5P(el,options).then(function(){H5P.externalDispatcher.on("xAPI",(event)=>{//do something useful with the eventconsole.log("xAPI event: ",event);});});
- Using
async
function
import{H5PasH5PStandalone}from'h5p-standalone';//you need you an alias due to conflictasyncfunctionmyAwesomePlayer(){constel=document.getElementById("h5p-container");constoptions={h5pJsonPath:"/h5p-folder",frameJs:"/assets/frame.bundle.js",frameCss:"/assets/styles/h5p.css",};awaitnewH5PStandalone(el,options);H5P.externalDispatcher.on("xAPI",(event)=>{//do something useful with the eventconsole.log("xAPI event: ",event);});}//don't forget to call the functionmyAwesomePlayer();
H5P provides two approaches for restoring a user's previous interaction state:
- using data provided with
contentUserData
option. - automatically fetching the data if
ajax.contentUserDataUrl
is provided
For both cases, thesaveFreq
option must be set.
A summary of the previous state restoration process:
- If the
contentUserData
option is available, skip to the 3rd step. - If
contentUserData
is not available butuser.*
andajax.contentUserDataUrl
options were provided, request the data fromajax.contentUserDataUrl
endpoint. - Process the previous state
data
as follows:- where
data[0].state
equalsRESET
, any previous state will be deleted - else, parse
data[0].state
string and pass it to the H5P player instance.
- where
ajax.contentUserDataUrl
may include (contentId,dataType,subContentId) placeholders that will be replaced with respective dataautomagically. Placeholders are prefixed with:
Placeholders are effective when you need to query only current content user data.
ajax.contentUserDataUrl
example:/api/users/123/h5p/:contentId?data_type=:dataType&subContentId=:subContentId
- This library includes an H5P resizer by default in
main.bundle.js
at the moment. But, to allow the iframe width to resize promptly, add CSS style setting the width to 100% i.e.style="width:100%;"
- If you want to allow users to resize the iframe width and height, set them using placeholders provided by H5P i.e.,
width=":w"
andheight=":h"
An example that combines the above points:
<iframewidth=":w"height=":h"src="https://app.wikonnect.org/embed/JJuzs-OAACU"//replace this with your URLframeBorder="0"scrolling="no"styles="width:100%"></iframe>
- Rename the H5P file extension from
.h5p
file to.zip
- Extract the renamed file contents into your workspace
h5p-folder
folder
After modifying the project, build the files: yarn build
to run availableCypress tests: yarn test
About
Display H5P content without the need for an H5P server