One of the most common requests I receive is to tweak an existing H5P content type because it lacks certain features or doesn’t quite meet specific requirements. While it’s possible to add custom scripts to achieve what you need, sometimes it’s easier to directly modify the content type’s code.
The first step is to contact the maintainer of the H5P content type in question. Although someone else could potentially make the necessary changes, they can only suggest it to the maintainer. Ultimately, it’s up to the maintainer to decide whether to include any fixes or new features in the original code. So, even if you make changes and use them yourself, there’s no guarantee they’ll be incorporated into the main project.
Therefore, it’s crucial to reach out to the original maintainer first and discuss your proposed changes. They’ll let you know if they’re interested in adding your feature and any requirements you should fulfill. Once you’ve got the green light, you can proceed to make the changes and submit a pull request—a request to merge your new code into the original codebase. The maintainer will then review your code, possibly ask for some adjustments, and merge it if everything looks good before releasing it.
If the maintainer doesn’t approve of your proposed changes, you have two main options, each with its own advantages and disadvantages. You can “fork” the H5P content type, essentially creating your own separate version. Alternatively, you can “patch” your code while still keeping the option open for a pull request.
Forking
Forking means to take the current snapshot of a content type and create a copy (clone) that can be tweaked to suit your needs by renaming it internally. This method allows you to change whatever you want without the need to be considerate of someone else. Your changes will not affect existing content, because for H5P your fork/clone is like a different content type. You can further develop it as you please.
However, one downside is that you will not automatically benefit from bug fixes or additions to the original content type that you cloned from. In some cases those may be added manually quite easily, but the more the original and the clone grow apart from another, the more difficult it gets. Along these lines: You will need to maintain your fork yourself. If it has dependencies to other content types, for instance uses sub content types, you will need to update the dependencies to later versions with bug fixes and new features yourself. Also keep in mind: Once you start forking one content type, you may quickly end up forking other content types, too.
For instance, let’s assume that you forked Mark the Words. You can use Mark the Words in Column. But just because your fork is based on the original Mark the Words, it does not automatically pop up as an option in Column – as mentioned, for H5P it’s like a completely different content type. So you will need to fork Column, too. And then you may want it in Course Presentation as well, so you need to fork Course Presentation. And so on and on … This can get out of hand quickly, and you may end up with lots of forks.
Another downside that may not be obvious is having a clone that is not substantially different from the original. That could become an issue if you’re also using the latter. For instance, your users might be able to choose from the regular Image Hotspots and an alternate version that has one extra feature. Which one should they use? Your version, because it has that one extra feature? The original one, because it may have been improved meanwhile? Things get even more complicated if there are many variants of a content type created by different organizations and if people share content – users may not only face one alternative to Image Hotspots, but multiple ones. And they may not even be aware that with uploading your clone they’d install it on their platform. This may not be relevant to you, because you might have a closed platform and your content will never leave it, but otherwise you should think about this issue.
One minor thing to keep in mind at least: If you have existing content that should be migrated to your fork, some database tweaking will be required once, but it is possible to do that. The procedure will vary based on the platform that you are running H5P on. Reversing that process in case you change your mind later may not be so simple however, because you would most likely lose your new features.
Patch / Pull Request
The option of patching the code and using a pull request starts the same way as forking does: You create a clone of an existing content type. The difference is that you don’t rename it internally. To H5P this will not be a new content type. You are technically changing the existing once, yet only on your local platform. You can do all the changes that you want to just like described above, but you should be very careful, because updates to the original content type would overwrite your changes – and updates to content types can come along with updates to other content types, so you may not even be aware that you’re upgrading. For instance, if you changed Multiple Choice and avoided updating it by hook or by crook, you might still update it accidentally by updating Course Presentation or Interactive Video or some other content type that can use Multiple Choice. You would have to patch in your changes again and again. Of course, that’s not desirable. The way out of this situation is to offer your changes to the maintainer of the original content type (which probably is H5P Group, the company that provides the H5P core team). If they decide that it’s a good addition, they can pull your changes – that’s why your offer is called a “pull request”.
The advantage of this approach is that you can easily benefit from bug fixes or new features that others have added to the content type. You just need to update it from the H5P servers.
Also, when the maintainer of a content type accepts your changes, he/she somehow takes over the responsibility for problems with it. Let’s say later on someone finds a bug in your changes. In that case it would be decent behavior if you fix it, but strictly speaking it’s the maintainers problem then.
Here’s a downside now: The aforementioned responsibility transfer may explain why maintainers of H5P content types may be reluctant to accept pull requests. Other reasons for reluctance might be that your change covers a special case that may be crucial for your use case – but not relevant to other people at all – yet increasing overall complexity. That’s why you would want to make sure beforehand that the maintainer would accept your changes. Even then, she/he might ask for changes, not be able to deal with your pull request in a timely fashion, etc. You may be stuck with your local clone, not being able to update the content type (without patching again) for quite a while – and even run into mild trouble in some cases if the maintainer requests changes that you had not expected.
Therefore, if you prefer to go the “patch / pull request” route over creating a fork, you should really make sure that the maintainer is okay with your changes beforehand – especially if the changes have impact on the user experience – and possibly also discuss how the changes could or should be achieved.