This project is a re-implementation of the H5P-Editor-PHP-library and H5P-PHP-library for Nodejs. It is written in TypeScript but can be used in JavaScript just as well.
Please note that even if most functionality of H5P seems to work, there are parts which haven't been implemented yet or which might be faulty. This is particularly true for security concerns. For a more comprehensive list of what works and what doesn't, check out the corresponding documentation page. The interfaces have reached some level of stability, but might still change in future major releases. If you have questions or want to contribute, feel free to open issues or pull requests.
An example of how to integrate and use this library with Express can be found in examples.
Make sure you have git
, node
>= 10.16, and npm
installed. If you use Windows, you must use bash (comes with Git for windows) as a command shell (otherwise scripts won't run).
- Clone the repository with git
npm install
npm run build
npm start
You can then open the URL http://localhost:8080 in any browser.
Make sure you have git
and docker
installed.
- Clone the repository with git
docker build -t <your-username>/h5p-nodejs-library .
docker run -p 3000:8080 -d <your-username>/h5p-nodejs-library
You can then open the URL http://localhost:3000 in any browser.
To find out what this library provides for you and what you must implement on your own, check out the architecture overview first.
Install the library by executing
npm install h5p-nodejs-library
Note: The example snippets below use the ES2017 async await language features to simplify dealing with promises. You can still use the traditional .then(()=> {...}) style if you wish so.
After installation, you can import the library in a JavaScript file with
const H5P = require('h5p-nodejs-library');
and instantiate the editor with
const h5pEditor = H5P.fs(
await new H5P.H5PConfig(
new H5P.fsImplementations.JsonStorage(
path.resolve('examples/config.json') // the path on the local disc where the configuration file is stored
)
).load(),
path.resolve('h5p/libraries'), // the path on the local disc where libraries should be stored
path.resolve('h5p/temporary-storage'), // the path on the local disc where temporary files (uploads) should be stored
path.resolve('h5p/content') // the path on the local disc where content is stored
);
and render the editor for content (= the HTML user interface around the actual editor and the editor itself) with a specific content ID with
const page = await h5pEditor.render(contentId);
// send the page to the browser
To use a custom renderer, change it with
h5pEditor.setRenderer(model => /** HTML string **/);
See the documentation page on constructing a H5PEditor
object for more details on how to instantiate the editor in a more customized way.
The H5P client (running in the browser) sends many AJAX requests to the server (this application). While this library provides you with everything required to process the requests in the backend, your implementation must still serve the requests to these endpoints. There is an Express adapter that you can use out-of-the box for this purpose. Check out the documentation on endpoints for details.
This application doesn't include the H5P JavaScript core files for the editor and the player. These are the files that make up the editor and player that the end user interacts with in the browser. The core files must be obtained separately:
- Download the Core Files and place them into a folder called
h5p/core
in your project. - Download the Editor Files and place them into a folder called
h5p/editor
in your project.
You must add a route to your implementation that serves the static files found under h5p/core
and h5p/editor
to the endpoint configured in config.libraryUrl
. The out-of-the-box Express adapter already includes a route for this.
While the AJAX communication between the actual H5P editor client (running in the browser) and the server (this application) can be fully handled by the Express adapter, you must still create custom views for these purposes:
- View that is shown when creating new content
- View that is shown when editing existing content
- View for deleting content
- View that lists existing content
- View that plays content
The reason why you have to do this on your own is that this library is unaware of other data that your system might attach to a piece of content (e.g. access rights, tags). If you want any custom UI elements around the editor and player (which is highly likely), you must put this into the views. Check out the example for how to write custom views.
Several aspects of your H5P server can be customized by creating your own implementation of interfaces and passing them to the constructor of H5PEditor
. That way you can use a database of your choice, cache data in Redis or store user data in an object storage system.
The interfaces that can be implemented are:
IContentStorage
IH5PConfig
ILibraryStorage
ITemporaryFileStorage
IUser
There are already default implementations that you can use:
- The implementations in the
fs
folder store all data in the local file system and are only for demonstration purposes and not suitable to be used in a multi-user environment and not optimized for speed. You might be able to use them in a cluster setup by using a network storage. - There is a implementation of the content storage for MongoDB and S3-compatible storage systems. Check out more information in the documentation page.
- There is a implementation of the temporary file storage for S3-comptaible storage system. Check out more information in the documentation page.
The implementation needs to call several function regularly (comparable to a cronjob):
- Call
H5PEditor.temporaryFileManager.cleanUp()
every 5 minutes. This checks which temporary files have expired and deletes them if necessary. It is important to do this, as temporary files are not automatically deleted when a piece of content is saved. - Call
H5PEditor.contentTypeCache.updateIfNecessary()
every 12 hours. This will download information about the available content types from the H5P Hub. If you don't do this, users won't be shown new content types or updates to existing content types when they become available.
If something goes wrong and a call to the library can't continue execution, it will normally throw either a H5PError
or an AggregateH5PError
(a collection of several errors). Both errors types represent errors that can be sent to the user to be displayed in the client (in the user's language). They don't include the English error message but an error id that you must translate yourself. Error ids and their English translations can be found in assets/translations
. The translation strings follow the format used by i18next, but in theory you can use any localization library.
Calls to the library might also throw regular Error
objects. In this case the error is not caused by the business logic, but by some more basic functionality (file system, other library) or it might be an error that is addressed at the developer (i.e. because function parameters aren't correctly used).
The Express adapter already catches errors, localizes them and returns proper HTTP status codes. Check out the implementation there for a guide how to deal with errors.
This library supports localization. See the respective documentation page for more details.
Make sure you have git
, node
>= 10.16, and npm
installed. If you use Windows, you must use bash (comes with Git for windows) as a command shell (otherwise scripts won't run).
git clone https://github.com/Lumieducation/h5p-nodejs-library
cd h5p-nodejs-library
npm install
You must transpile the TypeScript files to ES5 for the project to work (the TypeScript transpiler will be installed automatically if you run npm install
):
npm run build
After installation, you can run the tests with
npm test
The library emits log messages with debug. To see those messages you have to set the environment variable DEBUG
to h5p:*
. There are several log levels. By default you'll only see the messages sent with the level info
. To get the verbose log, set the environment variable LOG_LEVEL
to verbose (mind the capitalization).
Example (for Linux):
DEBUG=h5p:* LOG_LEVEL=verbose node script.js
Check out the many other npm scripts in package.json for other development functionality.
Lumi tries to improve education wherever it is possible by providing a software that connects teachers with their students. Every help is appreciated and welcome.
Feel free to create pull requests.
h5p-nodejs-library has adopted the code of conduct defined by the Contributor Covenant. It can be read in full here.
We use SemVer for versioning. For the versions available, see the tags on this repository.
This project is licensed under the GNU GENERAL PUBLIC LICENSE v3 License - see the LICENSE file for details
This work obtained financial support for development from the German BMBF-sponsored research project "CARO - Care Reflection Online" (FKN: 01PD15012).
Read more about them at the following websites:
- CARO - https://blogs.uni-bremen.de/caroprojekt/
- University of Bremen - https://www.uni-bremen.de/en.html
- BMBF - https://www.bmbf.de/en/index.html