Skip to content
This repository has been archived by the owner on Feb 17, 2022. It is now read-only.

Latest commit

 

History

History
104 lines (77 loc) · 5.01 KB

README.md

File metadata and controls

104 lines (77 loc) · 5.01 KB

Built With Stencil

Shared Exercise Store

The goal of this project is to build a flexible and easily extendable platform for exercises. Those exercises can then be loaded as web components into exercising apps or on educational websites. By providing high-level components for common exercise types like multiple-choice, even educators with few programming language should be able to create new exercises (introducing those components is a plan for the future).

Creating exercises

This is a guido helping you to integrate new exercises. With the following information and a basic understanding of Stencil you are good to go.

Adding translations

This project uses i18next for translations. There are no global translation files, instead, every exercise has its own translations. This makes sure that the client does not load translations for exercises that are not displayed.

Put the translations inside ${pathToComponentFolder}/locales/${exerciseId}/.

Add your translations folder to the assets of the component so that they will be included in the build.

@Component({
  assetsDirs: ['locales/breadth-first-search']
})

Translations can be nested. If the following json was your translation file, you would reference the string "Hello World!" through "messages.greeting".

{
  "messages": {
    "greeting": "Hello World!"
  }
}

Import i18next-wc so that you can use i18next's web components for translations. Also, you'll need to call loadTranslations in the componentWillLoad method. I decided to load translations within componentWillLoad because this is the first lifecycle method that gets called. Therefore, the loading of the translations will start very early which will reduce loading times. Remember to return or await the Promise returned by loadTranslations so that the compnent knows when the translations are loaded and the component can be displayed. Otherwise, the component might be rendered before the translations are available which would look weird.

In order for every web component using its own translations, laadTranslations will return an isolated (not global) object containing just the translations that the component needs. The component uses it for getting its translations.

Documenting Exercises

Exercises need to be documented so that this project provides metadata about its exercises. In fact, the app SharedExercises uses the generated JSON documentation for storing the exercises' metadata in the database.

  • Use the documentation tag tag to add a comma separated list of tags identifying the subjects of an exercise.
  • Use the documentation tag languages to add a comma separated list with all languages supported by the exercise.

Example Component

The following is a minimal example of an exercise component. You can use as a starting point for creating new exercises.

import {setupTranslations} from '../../../utils/translations';
import i18n from 'i18next';
import 'i18next-wc';

/**
 * @tags example, getting_started
 * @languages english, german
 */

@Component({
  tag: 'exercise-example',
  assetsDirs: ['locales/example']
})
export class Example implements ComponentInterface {
  i18n: i18n;

  async componentWillLoad(): Promise<void> {
    this.i18n = await loadTranslations('example');
  }

  render() {
    return (
        <p>
          <intl-message i18next={this.i18n} label="messages.greeting">
          </intl-message>
        </p>
    );
  }
}

Testing

To test your component run npm install and npm start. This will open the exercise picker component in the browser where you can pick the exercise that should be displayed and manually tested.

Rules and Conventions

  • Tags only use lowercase letters and separate words with an underscore. Example: graph_theory
  • The web components tags are prefixed with "exercise-". Example: "exercise-multiply-two-with-three"