H5P Guides

Translate libraries

Translating library semantics

Being able to translate your content is essential for reaching out to everyone. That is why translating content in H5P is made easy - all you need to do is include a language file in the language folder of your library. The different steps for creating and placing this language file is explained in the following three steps:

  1. Make a language file from your semantics.json file.
  2. Rename the new file with the correct language code, and place the file in the correct folder.
  3. Translate the strings in the file.

The H5P framework will take care of the rest!

Create translation

Creating the languages file from the semantics file can be done in two ways.

  1. Use the H5PCLI tool to create the language file for you.
  2. Create the language file manually from the library semantics.json file.

Using the H5PCLI tool

The H5PCLI is the H5P Command Line Interface, this tool is made with library developers in mind, trying to make their life easier. For a complete overview of the CL, and the mindset of becoming a faster and more efficient H5P developer you should check out the H5P CLI guide.

Once you have the H5P CLI you can translate the file by typing 

h5p create-language-file h5p-summary nb

Since the CLI takes care of the language file naming convention and placement you can proceed straight to translating the content of your new file!

Create the language file from semantics.json

Making a language file that is ready to be translated from semantics.json is achieved by following three quick steps.

  1. Copy the semantics.json file from your library
  2. Remove all fields that do not need translation
  3. Encompass the content in a semantics object.
Copy the semantics.json file

The simplest step. Make a new file and copy the complete content of semantics.json to this file.

Remove all fields that do not need translation

 A field definition in semantics.json looks like the following:

{
  "label": "Textfield",
  "name": "textField",
  "type": "text",
  "widget": "textarea",
  "placeholder": "This is an answer: *answer*.",
  "description": "Marked words are added with two asterix (*) around the word."
}

name, type and widget are not displayed to the end user, but needed only by the editor, so they should be left untouched.

Following is the complete list of fields that can and should be translated:

  • Label
  • Placeholder
  • Description
  • Default

All other fields should be removed from the new language file, which would result in our example looking like this:

{
  "label": "Textfield",
  "placeholder": "This is an answer: *answer*.",
  "description": "Marked words are added with two asterix (*) around the word."
}
Enclose the content in a semantics object

The H5P Editor looks for a "semantics" object in the language file, which must match the structure of your semantics.json file. This step is completed by simply adding an outer object with a field called semantics. This fields should contain the modified semantics.json file from last step.

Using Fill in the Blanks as an example, its prepared language file would look like this:

{
  "semantics": [
    {
      "label": "Task image",
      "description": "An optional image to display above the task."
    },
    {
      "label": "Task description",
      "description": "A guide telling the user how to answer this task."
    },
    {
      "label": "Text blocks",
      "entity": "text block",
      "field": {
        "label": "Line of text",
        "description": "Blanks are added with an asterix (*) in front and behind the correct word/phrase. Alternative answers are separated with a forward slash (/). You may add a textual tip, using a colon (:) in front of the tip. Example: H5P content may be edited using a *browser/web-browser:Something you use every day*."
      }
    },
    {
      "label": "Feedback text",
      "description": "Feedback text, variables available: @score and @total. Example: 'You got @score of @total possible points'"
    },
    {
      "label": "Text for \"Show solutions\" button"
    },
    {
      "label": "Text for \"Retry\" button"
    },
    {
      "label": "Text for \"Check\" button"
    },
    {
      "label": "Text for \"Not filled out\" message"
    },
    {
      "label": "Behavioural settings.",
      "description": "These options will let you control how the task behaves.",
      "fields": [
        {
          "label": "Enable \"Retry\""
        },
        {
          "label": "Enable \"Show solutions\" button"
        },
        {
          "label": "Automatically check answers after input"
        },
        {
          "label": "Case sensitive",
          "description": "Makes sure the user input has to be exactly the same as the answer."
        },
        {
          "label": "Require all fields to be answered before the solution can be viewed"
        },
        {
          "label": "Put input fields on separate lines"
        }
      ]
    }
  ]
}

For an advanced reference example, you can see the semantics.json of Image Hotspot Question and the corresponding Norwegian language file

Name and place of translation

Next up is giving the language file a proper name and placing it in the correct folder for the editor to find it.

The naming convention of languages we use is the two-character ISO-639-1 standard. A list containing language codes for this standard can be found at Wikipedia.

When you have found what language you wish to translate to you will simply rename the language.json file to <language-code>.json.

The file should then be placed in the language folder immediately within your library. If this folder does not exist it must be created.

Let the translation begin

This step is quite straightforward, but naturally the most time consuming. This is where you will be doing the actual translations.

When you have finished the translation you are done! The editor will take care of loading the correct language file as long as you have your language configured correctly on your server.

Translating editor widgets

Editor widgets are handled quite similarly to semantics.json translation. However, there are some key issues that the developer has to take care of in these cases.

Editor translates semantics

When using semantics from the main library in a widget they have to be processed inside the widget. The semantic chunks can be processed and used by using H5PEditor.processSemanticsChunk, in these cases the editor will take care of the translations from semantics, as long as you have translated the semantics in your library, as described for the semantics.json file.

Widget translates strings

When not using text strings from semantics.json as UI texts, the developer has to use the H5PEditor.t function, which is only available in the editor.

All UI texts should be translatable in an editor widget, so they have to be included in the H5PEditor.language object. This is done by creating a property on that object using the machine name of your library as the key. For the H5PEditor.ImageHotspotQuestion editor widget, adding the following to the bottom of the JS file will create the default English texts strings that can be translated:

// Default english translations
H5PEditor.language['H5PEditor.ImageHotspotQuestion'] = {
  libraryStrings: {
    noImage: 'You have not selected an image.',
    done: 'Done',
    remove: 'Remove hotspot',
    rectangle: 'Create rectangle',
    circle: 'Create circle',
    guiDescription: 'Drag and drop the desired figure from the toolbar to create a new hotspot.'
  }
};

Similarly to the library translations a "language" folder must be created within the editor library and the translation files must be named <language-code> .json, see section above. The content of the file will be the same JavaScript object appended to the H5PEditor.language array in the code above. Here is the content of the Norwegian language file for the example above:

{
  "libraryStrings": {
    "noImage": "Du må velge et bilde før du kan plassere målfelt.",
    "done": "Ferdig",
    "remove": "Slett målfelt",
    "rectangle": "Lag rektangel",
    "circle": "Lag sirkel",
    "guiDescription": "Dra og slipp en figur for å lage et nytt hotspot. Dobbel-klikk en hotspot for å velge innstillinger. Dra en hotspot for å bevege den. Dra nede til høyre på hotspoten for å endre størrelsen."
  }
}

To get a string with correct translation in your JavaScript code, invoke H5PEditor.t with the editor library's machine name and the key of the string like this:

H5PEditor.t('H5PEditor.ImageHotspotQuestion', 'noImage');