H5P-Editor
This project is a port of the H5P-Editor-PHP-library for Nodejs.
Please note that this project is in a very early and experimental stage. 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 can be found in the H5P-Demo project.
Installation
You can install the library with
npm install h5p-editor
Usage
After installation, you can import the library with
const H5PEditor = ;
and instantiate the Editor with
const h5pEditor = urls keyValueStorage config "/path/to/library/directory" "/path/to/content/storage/directory" user translationService;
and render the editor for content with a specific content ID with
h5pEditor ;
To use a custom renderer, change it with
h5pEditor;
Constructor Arguments
The constructor arguments are used to provide data storage services and HTTP paths to the Editor.
urls
An object containing strings used as URL prefixes by the editor
const urls = baseUrl: '/h5p' // path to core files and libraries ajaxPath: '/ajax?action=' // URL prefix for all AJAX requests (see below) libraryUrl: '/h5p/editor/' // path to editor "core files" (see below) filesPath: '/h5p/content' // base path for content files (e.g. images)
keyValueStore
The keyValueStore
object is used by the ContentTypeCache
to persist information about Content Types. It must be able to store arbitrary nested objects.
It must implement the following interface:
const keyValueStore = async { /** store given value under key, * overwriting potential existing values **/ } async { return /** value stored under key **/; }
config
An object holding all configuration parameters as properties. You can find the description of the parameters in src/config.js
.
libraryStorage
The libraryStorage
provides information about installed libraries and installs them.
It must implement the following interface
const libraryStorage = /** * Returns all installed libraries or the installed libraries that have the machine names in the arguments. * @param * @returns {Promise<Library[]>} the libraries installed */ async { return Promise } /** * Get id to an existing installed library. * If version number is not specified, the newest version will be returned. * @param * @returns */ async { return Promise } /** * Returns a readable stream of a library file's contents. * Throws an exception if the file does not exist. * @param * @param * @returns */ async { return Promise } /** * Gets a list of installed language files for the library. * @param * @returns {Promise<string[]>} The list of JSON files in the language folder (without the extension .json) */ async { return Promise } /** * Check if the library contains a file * @param * @param * @return */ async { return Promise } /** * Adds the metadata of the library to the repository. * Throws errors if something goes wrong. * @param * @param * @returns */ async { return Promise } /** * Removes the library and all its files from the repository. * Throws errors if something went wrong. * @param * @returns */ async { return } /** * Adds a library file to a library. The library metadata must have been installed with installLibrary(...) first. * Throws an error if something unexpected happens. * @param * @param * @param * @returns */ async { /** save data in stream into file with filePath * (starting with library folder e.g. 'Foo-1.2') * and resolve(true) when done **/); }
Available implementation
If you store all library information as files in folders under ./h5p/libraries
you can use
const libraryStorage = `h5p/libraries`;
contentStorage
The contentStorage
provides information about installed content and creates it.
It must implement the following interface
const contentStorage = /** * Creates a content object in the repository. Add files to it later with addContentFile(...). * @param * @param * @param * @param * @returns */ async { /** Check if user has write permission and store the information received in the parameters * to the database / disk **/ return Promise } /** * Adds a content file to an existing content object. The content object has to be created with createContent(...) first. * @param * @param * @param * @param * @returns */ async { /** Check if the user has write permission and store the file **/ return Promise } /** * Returns a readable stream of a content file (e.g. image or video) inside a piece of conent * @param * @param * @param * @returns */ { /** Check if the user has read permission for the content type and return a stream **/ return fs } /** * Deletes content from the repository. * Throws errors if something goes wrong. * @param * @param * @returns */ async { /** Check if user has write permission to content and delte the content and all dependent files. **/ return Promise } /** * Generates a unique content id that hasn't been used in the system so far. * @returns */ async { return Promise }
Available implementation
If you store all library information as files in folders under ./h5p/content
you can use
const contentStorage = `h5p/content`;
user
An object containing access control information in the following properties
const user = type: 'local' canCreateRestricted: true canInstallRecommended: true canUpdateAndInstallLibraries: true
translationService
Used to translates literals into the local language. It must implement the following method
const translationService = /** * Gets the literal for the identifier and performs replacements of placeholders / variables. * @param * @param {[key: string]: string} replacements An object with the replacement variables in key-value format. * Incidences of any key in this array are replaced with the corresponding value. Based * on the first character of the key, the value is escaped and/or themed: * - !variable inserted as is * - @variable escape plain text to HTML * - %variable escape text to HTML and theme as a placeholder for user-submitted content * @returns The literal translated into the language used by the user and with replacements. */ { return /** a string **/ }
AJAX Requests
The following URLs assume the urls
const urls = baseUrl: '/h5p' ajaxPath: '/ajax?action=' libraryUrl: '/h5p/editor/' filesPath: '/h5p/content'
Save Content
POST /?contentId=<string>
Saves the new version of a content with given contentId
.
The request will be sent to the URL under which the editor is rendered.
Its body is
params: params: /** new content **/ metadata: /** new metadata **/ library: /** name of library **/
The request data should be passed to saveH5P
h5pEditor
Get Content Information
GET /params?contentId=<string>
Requests information about content. Respond with
h5pEditor
Get Content Type Cache
GET /ajax?action=content-type-cache
Requests available content types. Respond with
h5pEditor
Get Library Data
GET /ajax?action=libraries&machineName=<string>&majorVersion=<int>&minorVersion=<int>&language=<string>
Requests data about a specific library. Respond with
h5pEditor ;
Get Library Overview
POST /ajax?action=libraries
requests overview information about the given libraries. Respond with
h5pEditor
Save Content File
POST /ajax?action=files&contentId=<string>
Sends a file to be saved under the given content ID. The ID can be passed in the query string of the body of the request.
h5pEditor ;
Install Library
POST /ajax?action=library-install&libraryId=<string>
Requests for the given library to be installed. Handle with
h5pEditor
Upload Package
POST /ajax?action=library-upload&contentId=<string>
is used to upload a .h5p
file, and install the containing libraries and content
Handle with
h5pEditor
Core Files
See the example integration for express how to integrate it with express.
You have to provide the H5P core and library files. To do so
- Download the Core Files and place its content in your project.
- Download the Editor Files and place its content in your project.
- Add a route that serves the downloaded files. (See the express-example)
Adapters
We will provide adapters for express and meteor in the future. If you would like to see another adapter, please make a issue.
Content-Type Hub
If you want to use your own Content Type Hub, you can find the protocol you have to implement in hub-protocol.md.
Development & Testing
Prerequisites
Make sure you have git
, node
>= 10.16, and npm
installed.
Installation
git clone https://github.com/Lumieducation/h5p-editor-nodejs-library
cd h5p-editor-nodejs-library
npm install
Run Tests
After installation, your can run the tests with
npm test
Contributing
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.
Get in touch
Versioning
We use SemVer for versioning. For the versions available, see the tags on this repository.
License
This project is licensed under the GNU GENERAL PUBLIC LICENSE v3 License - see the LICENSE file for details
Support
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