Skip to content

Commit

Permalink
feat: content user data with context (#3011)
Browse files Browse the repository at this point in the history
* feat: added contextId to user data classes

* feat: contextId in H5PPlayer.play

* feat: contextId in h5p-express and docs

* test: added integration tests for contextId

* test: contextId in rest example

* feat(mongo-s3): added contextId to user data storage

* docs: extended docs

* chore: update package lock

* chore: update package lock
  • Loading branch information
sr258 committed Jul 8, 2023
1 parent 971a583 commit 798975e
Show file tree
Hide file tree
Showing 27 changed files with 4,924 additions and 1,771 deletions.
1 change: 1 addition & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* [Performance optimizations](advanced/performance-optimizations.md)
* [Privacy](advanced/privacy.md)
* [Forward proxy support](advanced/proxy.md)
* [Multiple content states per object](advanced/context-ids.md)
- NPM packages
- h5p-mongos3
* [Mongo/S3 Content Storage](packages/h5p-mongos3/mongo-s3-content-storage.md)
Expand Down
73 changes: 73 additions & 0 deletions docs/advanced/context-ids.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Multiple content states per object

You can save multiple user states (= the data a learner entered, e.g. the
attempts in a fill-in-the-blanks activity) for one user - content tuple. This is
a useful feature, if you want to allow your users to have more than one attempt
per content object and if they can return to older ones.

This feature is unique to this H5P NodeJs implementation and not part of the
standard H5P PHP server version.

## Usage

If you want to use this feature, your implementation has to provide a
`contextId` in the `H5PPlayer.render` options:

```js
const html = await h5pPlayer.render(
contentId, // the content id
user, // the current user
'auto', // automatic language detection
{
contextId: '<YOUR CONTEXT ID>'
// you can add more options here as well
}
);
```

Context ids can't be used in the H5P editor, as the user state in the editor is
only used to save things like whether certain info boxes were collapsed.
Multiple contexts wouldn't make sense there.

## Creating contextId

`contextId` is an arbitrary string value that you define in your implementing
system. It is **your** job to keep it unique and to pass it the the `render`
method. Typically it is associated with some other object in your database
anyway (e.g. an attempt object), so you will already have a unique id that you
can use here.

## Using contextIds with old data

It is save to use `contextIds` if you already have user content data in your
system that didn't use contextIds. You can also have user data that has a
`contextId` and other user data that doesn't in the same system.

## Web Components and React

The H5P Player Web Component and React component also support the context id.
You can set the current context id by setting the attribute/property `contextId`
to the desired value. Make sure that you implementation of `loadContentCallback`
accepts `contextId` as the second parameter, that you include it in the request
to the server and that your server passes the contextId to `H5PPlayer.render`.

## Storage support

Both the `FileContentUserDataStorage` and `MongoContentUserDataStorage` support
context ids.

## Trying it out in the examples

The server-side-rendering example supports context ids. You can set the context
id by passing it as a query parameter in the URL, e.g.
`http://localhost:8080/h5p/play/<CONTENTID>?contextId=<CONTEXTID>` where
`<CONTEXTID>` is an arbitrary value you can make up on the fly.

The REST example also supports context ids. You can see the currently used
context id in the user interface after the `#` icon. You can change the current
context id with the button.

## Acknowledgement

The development of this feature was kindly funded by PHWE Systeme GmbH und Co.
KG (https://www.phywe.de/).
33 changes: 26 additions & 7 deletions packages/h5p-examples/mongo+mongos3.env
Original file line number Diff line number Diff line change
@@ -1,18 +1,37 @@
# Example configuration file; rename it to .env
# Example configuration file; rename it to .env to use it

CONTENTSTORAGE=mongos3
# The S3 credentials are shared by all storage classes using S3.
AWS_ACCESS_KEY_ID=minioaccesskey
AWS_SECRET_ACCESS_KEY=miniosecret
AWS_S3_ENDPOINT=http://localhost:9000
AWS_S3_MAX_FILE_LENGTH=100
CONTENT_AWS_S3_BUCKET=testbucket1
TEMPORARYSTORAGE=s3
TEMPORARY_AWS_S3_BUCKET=tempbucket1

# The MongoDB credentials are shared by all storage classes using MongoDB.

MONGODB_URL=mongodb://localhost:27017
MONGODB_DB=testdb1
MONGODB_USER=root
MONGODB_PASSWORD=h5pnodejs

# Set content storage to Mongo + S3
CONTENTSTORAGE=mongos3
CONTENT_AWS_S3_BUCKET=testbucket1
CONTENT_MONGO_COLLECTION=h5p
CACHE=in-memory
LIBRARYSTORAGE=mongo

# Set temporary file storage to S3
TEMPORARYSTORAGE=s3
TEMPORARY_AWS_S3_BUCKET=tempbucket1

# Set library storage to Mongo / S3
LIBRARYSTORAGE=mongos3
LIBRARY_MONGO_COLLECTION=h5plibraries
LIBRARY_AWS_S3_BUCKET=libbucket1

# Set user data storage to Mongo

USERDATASTORAGE=mongo
USERDATA_MONGO_COLLECTION=userdata
FINISHED_MONGO_COLLECTION=finisheddata

# Set the cache to use in-memory cache
CACHE=in-memory
37 changes: 29 additions & 8 deletions packages/h5p-examples/mongo+s3+redis.env
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
# Example configuration file; rename it to .env
# Example configuration file; rename it to .env to use it

CONTENTSTORAGE=mongos3
# The S3 credentials are shared by all storage classes using S3.
AWS_ACCESS_KEY_ID=minioaccesskey
AWS_SECRET_ACCESS_KEY=miniosecret
AWS_S3_ENDPOINT=http://localhost:9000
AWS_S3_MAX_FILE_LENGTH=100
CONTENT_AWS_S3_BUCKET=testbucket1
TEMPORARYSTORAGE=s3
TEMPORARY_AWS_S3_BUCKET=tempbucket1

# The MongoDB credentials are shared by all storage classes using MongoDB.

MONGODB_URL=mongodb://localhost:27017
MONGODB_DB=testdb1
MONGODB_USER=root
MONGODB_PASSWORD=h5pnodejs

# Set content storage to Mongo + S3
CONTENTSTORAGE=mongos3
CONTENT_AWS_S3_BUCKET=testbucket1
CONTENT_MONGO_COLLECTION=h5p

# Set temporary file storage to S3
TEMPORARYSTORAGE=s3
TEMPORARY_AWS_S3_BUCKET=tempbucket1

# Set library storage to Mongo / S3
LIBRARYSTORAGE=mongos3
LIBRARY_MONGO_COLLECTION=h5plibraries
LIBRARY_AWS_S3_BUCKET=libbucket1

# Set user data storage to Mongo

USERDATASTORAGE=mongo
USERDATA_MONGO_COLLECTION=userdata
FINISHED_MONGO_COLLECTION=finisheddata

# Set the cache to use redis and configure its credentials
CACHE=redis
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_DB=0
LIBRARYSTORAGE=mongos3
LIBRARY_MONGO_COLLECTION=h5plibraries
LIBRARY_AWS_S3_BUCKET=libbucket1

# Set the lock to use redis and configure its credentials.
LOCK=redis
LOCK_REDIS_HOST=localhost
LOCK_REDIS_PORT=6379
LOCK_REDIS_DB=1

0 comments on commit 798975e

Please sign in to comment.