## Overview

H5P is a file format for content/applications made using modern, open web technologies (HTML5). The format enables easy installation and transfer of applications/content on different CMSes, LMSes and other platforms. An H5P can be uploaded and published on a platform in mostly the same way one would publish a Flash file today. H5P files may also be updated by simply uploading a new version of the file, the same way as one would using Flash.

H5P opens for extensive reuse of code and wide flexibility regarding what may be developed as an H5P.

The system uses package files containing all necessary files and libraries for the application to function. These files are based on open formats.

## Overview of package files

Package files are normal zip files, with a naming convention of <filename>.h5p to distinguish from any random zip file. This zip file then requires a specific file structure as described below.

There will be a file in JSON format named h5p.json describing the contents of the package and how the system should interpret and use it. This file contains information about title, content type, usage, copyright, licensing, version, language etc. This is described in detail below.

There shall be a folder for each included H5P library used by the package. These generic libraries may be reused by other H5P packages. As an example, a multi-choice question task may be used as a standalone block, or be included in a larger H5P package generating a game with quizzes.

## Package file structure

A package contains the following elements:

1. A mandatory file in the root folder named h5p.json
2. An optional image file named h5p.jpg. This is an icon or an image of the application, 512 × 512 pixels. This image may be used by the platform as a preview of the application, and could be included in OG meta tags for use with social media.
3. One content folder, named content. This will contain the preset configuration for the application, as well as any required media files.
4. One or more library directories named the same as the library's internal name.

## h5p.json

The h5p.json file is a normal JSON text file containing a JSON object with the following predefined properties.

Mandatory properties:

- title - Name of the package. Would typically be used as header for a page displaying the package.
- language - Standard language code. Use 'en' for english, 'nb' for norwegian "bokmål". Neutral content use "und".
- machineName - Machine readable name of the library. This is the name that will be used for the library folder in the package too.
- preloadedDependencies - Libraries that must be loaded on init. Specified as a list of objects with machineName, majorVersion and minorVersion. One would normally list all dependencies here to allow the platform displaying the package to merge JS and CSS files before returning the page.
- embedTypes - List of ways to embed the package in the web page. Currently "div" and "iframe" are supported.

Optional properties:

- contentType - Textual description of the type of content.
- description - Textual description of the package.
- author - Name of author.
- license - Code for the content license. Use the following Creative Commons codes: cc-by, cc-by-sa, cc-by-nd, cc-by-nc, cc-by-nc-sa, cc-by-nc-nd. In addition for public domain: pd, and closed license: cr. More may be added later.
- dynamicDependencies - Libraries that may be loaded dynamically during execution.
- width - Width of the package content in cases where the package is not dynamically resizable.
- height - Height of the package content.
- metaKeywords - Suggestion for keywords for the application, as a string. May be used for OG meta tags for social media.
- metaDescription - Suggestion for application metaDescription. May be used for OG meta tags for social media.

### Eksempel på h5p.json:

`{
"title": "Biologi-spillet",
"contentType": "Game",
"utilization": "Lær om biologi",
"language": "nb",
"author": "Amendor AS",
"license": "cc-by-sa",
"preloadedDependencies": [
{
"machineName": "H5P.Boardgame",
"majorVersion": 1,
"minorVersion": 0
}, {
"machineName": "H5P.QuestionSet",
"majorVersion": 1,
"minorVersion": 0
}, {
"machineName": "H5P.MultiChoice",
"majorVersion": 1, "minorVersion": 0
}, {
"machineName": "EmbeddedJS",
"majorVersion": 1,
"minorVersion": 0
} ],
"embedTypes": ["div", "iframe"],
"w": 635,
"h": 500
}`

## The content folder

Contains all the content for the package and its libraries. There shall be no content inside the library folders. The content folder shall contain a file named content.json, containing the JSON object that will be passed to the initializer for the main package library.

Content required by libraries invoked from the main package library will get their contents passed from the main library. The JSON for this will be found within the main content.json for the package, and passed during initialization.

## Library folders

A library folder contains all logic, stylesheets and graphics that will be common for all instances of a library. There shall be no content or interface text directly in these folders. All text displayed to the end user shall be passed as part of the library configuration. This make the libraries language independent.

The root of a library folder shall contain a file name library.json formatted similar to the package's hp5.json, but with a few differences. The library shall also have one or more images in the root folder, named library.jpg, library1.jpg etc. Image sizes 512px × 512px, and will be used in the H5P editor tool.

Libraries are not allowed to modify the document tree in ways that will have consequences for the web site or will be noticeable by the user without the library explicitly being initialized from the main package library or another invoked library.

The library shall always include a JavaScript object function named the same as the defined library machineName (defined in library.json and used as the library folder name). This object will be instantiated with the library options as parameter. The resulting object must contain a function attach(target) that will be called after instantiation to attach the library DOM to the main DOM inside target

### Example

A library called H5P.multichoice would typically be instantiated and attached to the page like this:

`var multichoice = new H5P.multichoice(contentFromJson, contentId);
multichoice.attach($multichoiceContainer);`

## library.json

Mandatory properties:

- title - Human readable name of the library. May be used in the H5P editor and overviews of installed libraries.
- majorVersion - Version major number. (The x in x.y.z). Positive integer.
- minorVersion - Version minor number. (The y in x.y.z). Positive integer.
- patchVersion - Version patch number. (The z in x.y.z). Positive integer. The system will automatically update to the latest patchVersion installed for all packages that use the library with the same major and minor version number. A new patch version must therefore not change any behaviour of the library, only fix errors.
- machineName - Machine readable name for the library. Same as the folder name used.
- preloadedJs - List of path to the javascript files required for the library. At least one file need to be present (the one defining the library object). Paths are relative to the library root folder.

Optional properties:

- author - Author name as text.
- license - Code describing the library license. Use the following creative commons codes: cc-by, cc-by-sa, cc-by-nd, cc-by-nc, cc-by-nc-sa, cc-by-nc-nd. In addition use pd for public domain, and cr for closed source
- description - Textual description of the library.
- preloadedDependencies - Libraries that need to be loaded for this library to work. Specified as a list of objects with machineName, majorVersion and minorVersion for the required libraries.
- dynamicDependencies - Libraries that may be loaded dynamically during library execution. Specified as a list of objects like preloadedDependencies above.
- preloadedCss - List of paths to CSS files to be loaded with the library. Paths are relative to the library root folder.
- w - Width in pixels for libraries that use a fixed width. Mandatory if the library shall be embedded in an iframe (see embedTypes below).
- h - Height in pixels for libraries that use a fixed height. Mandatory if the library shall be embedded in an iframe (see embedTypes below).
- embedTypes - List of possible ways to embed the package in the page. Available values are div and iframe.

### Eksempel på library.json:

`{
"title": "Boardgame",
"description": "The user is presented with a board with several hotspots. By clicking a hotspot he invokes a mini-game.",
"majorVersion": 1,
"minorVersion": 0,
"patchVersion": 6,
"runnable": 1,
"machineName": "H5P.Boardgame",
"author": "Amendor AS",
"license": "cc-by-sa",
"preloadedDependencies": [
{
"machineName": "EmbeddedJS",
"majorVersion": 1,
"minorVersion": 0
}, {
"machineName": "H5P.MultiChoice",
"majorVersion": 1,
"minorVersion": 0
}, {
"machineName": "H5P.QuestionSet",
"majorVersion": 1,
"minorVersion": 0
} ],
"preloadedCss": [ {"path": "css/boardgame.css"} ],
"preloadedJs": [ {"path": "js/boardgame.js"} ],
"w": 635,
"h": 500 }`

## Allowed file types

Files that require server side execution or that cannot be regarded an open standard shall not be used. Allowed file types: js, json, png, jpg, gif, svg, css, mp3, wav (audio: PCM), m4a (audio: AAC), mp4 (video: H.264, audio: AAC/MP3), ogg (video: Theora, audio: Vorbis) and webm (video VP8, audio: Vorbis). Administrators of web sites implementing H5P may open for accepting further formats. HTML files shall not be used. HTML for each library shall be inserted from the library scripts to ease code reuse. (By avoiding content being defined in said HTML).

## API functions

The following JavaScript functions are available through h5p:

- H5P.getUserData(namespace, variable)
- H5P.setUserData(namespace, variable, data)
- H5P.getUserStart(namespace)
- H5P.setUserStop(namespace)
- H5P.deleteUserData(namespace, variable)
- H5P.getGlobalData(namespace, variable)
- H5P.setGlobalData(namespace, variable, data)
- H5P.deleteGlobalData(namespace, variable)

I tillegg er følgende api funksjoner tilgjengelig via ndla:

- H5P.setUserScore(contentId, score, maxScore)

## Best practices

H5P is a very open standard. This is positive for flexibility. Most content may be produces as H5P. But this also allows for bad code, security weaknesses, code that may be difficult to reuse. Therefore the following best practices should be followed to get the most from H5P:

- Think reusability when creating a library. H5P support dependencies between libraries, so the same small quiz-library may be used in various larger packages or libraries.
- H5P supports library updates. This enables all content using a common library to be updated at once. This must be accounted for when writing new libraries. A library should be as general as possible. The content format should be thought out so there are no changes to the required content data when a library is updated. Note: Multiple versions of a library may exists at the same time, only patch level updates will be automatically installed.
- An H5P should not interact directly with the containing web site. It shall only affect elements within its own generated DOM tree. Elements shall also only be injected within the target defined on initialization. This is to avoid dependencies to a specific platform or web page.
- Prefix objects, global functions, etc with h5p to minimize the chance of namespace conflicts with the rest of the web page. Remember that there may also be multiple H5P objects inserted on a page, so plan ahead to avoid conflicts.
- Content should be responsive.
- Content should be WCAG 2 AA compliant
- All generated HTML should validate.
- All CSS should validate (some browser specific non-standard CSS may at times be required)
- Best practices for JavaScript, HTML, etc. should of course also be followed when writing an H5P.