h5p

package module
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 22, 2026 License: MIT Imports: 9 Imported by: 0

README

H5P Kit

Go CI Go Lint Go SAST Go Report Card Docs Visualization License

A toolkit for creating, editing, and validating H5P quiz content. Includes a Go SDK for server-side operations and a TypeScript Editor for browser-based quiz editing.

Component Language Package
Go SDK Go github.com/grokify/h5pkit
Quiz Editor TypeScript @grokify/h5p-editor

Go SDK Features

  • Full H5P Package Support - Create and extract .h5p ZIP files
  • Type-Safe Schema Implementation - Official H5P content type schemas
  • Question Set Builder - Fluent API for building interactive content
  • Validation - Built-in H5P compliance validation
  • Multiple Question Types - Support for various H5P content types
  • JSON Serialization - Complete marshaling/unmarshaling support

TypeScript Editor Features

  • Visual Quiz Editor - React component for browser-based quiz creation
  • Multiple Question Types - Multiple Choice, True/False, Fill in the Blanks
  • Undo/Redo - Full history support for editing operations
  • Theming - Light and dark mode with CSS custom properties

Quick Start

Go SDK
go get github.com/grokify/h5pkit
package main

import (
    "fmt"
    "log"
    "github.com/grokify/h5pkit"
)

func main() {
    // Create answers
    answers := []h5p.Answer{
        h5p.CreateAnswer("Paris", true),
        h5p.CreateAnswer("London", false),
        h5p.CreateAnswer("Berlin", false),
    }

    // Build question set
    questionSet, err := h5p.NewQuestionSetBuilder().
        SetTitle("Geography Quiz").
        SetProgressType("textual").
        SetPassPercentage(60).
        AddMultipleChoiceQuestion("What is the capital of France?", answers).
        Build()

    if err != nil {
        log.Fatal(err)
    }

    // Export to JSON
    jsonData, _ := questionSet.ToJSON()
    fmt.Printf("Generated H5P content:\n%s\n", string(jsonData))
}
TypeScript Editor
pnpm add @grokify/h5p-editor react react-dom
import { QuizEditor, H5PQuiz } from '@grokify/h5p-editor';
import '@grokify/h5p-editor/styles.css';

function App() {
  const handleSave = (quiz: H5PQuiz) => {
    console.log('Quiz:', quiz);
  };

  return <QuizEditor onSave={handleSave} />;
}

Documentation

Full Documentation

Architecture

h5pkit/
├── schemas/          # Official H5P content type schemas
├── semantics/        # Universal H5P semantics format
├── ts/               # TypeScript editor (@grokify/h5p-editor)
├── builder.go        # Fluent API for content creation
├── questionset.go    # Core question set functionality
└── h5p_package.go    # Complete H5P package management

Testing

go test ./...

Standards Compliance

This library implements the official H5P specifications:

Contributing

See our Contributing Guide for detailed information.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Answer

type Answer struct {
	Text     string `json:"text"`
	Correct  bool   `json:"correct"`
	Feedback string `json:"feedback,omitempty"`
}

Legacy types - use schemas.MultiChoiceParams instead Kept for backward compatibility, will be deprecated

func CreateAnswer

func CreateAnswer(text string, correct bool) Answer

func CreateAnswerWithFeedback

func CreateAnswerWithFeedback(text string, correct bool, feedback string) Answer

type BackgroundImage

type BackgroundImage struct {
	Path      string     `json:"path"`
	Mime      string     `json:"mime"`
	Copyright *Copyright `json:"copyright,omitempty"`
}

type Content

type Content struct {
	QuestionSet *QuestionSet `json:"questionSet,omitempty"`
	Params      interface{}  `json:",omitempty"`
}
type Copyright struct {
	Title   string `json:"title,omitempty"`
	Author  string `json:"author,omitempty"`
	License string `json:"license,omitempty"`
	Version string `json:"version,omitempty"`
	Source  string `json:"source,omitempty"`
}

type Extensions

type Extensions struct {
	H5PGo *H5PGoExtension `json:"h5pGo,omitempty"`
}

Extensions provides a namespace for vendor-specific extensions to H5P content. Standard H5P parsers will ignore unknown fields, making this safe for interoperability. Each vendor should use their own key within the Extensions map.

func NewExtensions

func NewExtensions() *Extensions

NewExtensions creates a new Extensions struct with an initialized H5PGoExtension

type FeedbackRange

type FeedbackRange struct {
	From int    `json:"from"`
	To   int    `json:"to"`
	Text string `json:"text"`
}

func CreateFeedbackRange

func CreateFeedbackRange(from, to int, text string) FeedbackRange

type FileReference

type FileReference struct {
	Path string `json:"path"`
}

type H5PGoExtension

type H5PGoExtension struct {
	// Section identifies the section/category this question belongs to
	// Example: "1. Overview & Fundamentals", "3. Vector RAG"
	Section string `json:"section,omitempty"`

	// Topic provides a more specific topic within a section
	// Example: "RAG Fundamentals", "Chunking Strategies"
	Topic string `json:"topic,omitempty"`

	// Tags provide flexible categorization with multiple labels
	// Example: ["rag", "retrieval", "inference-time"]
	Tags []string `json:"tags,omitempty"`

	// Difficulty indicates the question difficulty level
	// Suggested values: "easy", "medium", "hard"
	Difficulty string `json:"difficulty,omitempty"`

	// QuestionNumber provides explicit ordering within a question set
	QuestionNumber int `json:"questionNumber,omitempty"`

	// LearningObjective describes what the question tests
	// Example: "Understand the difference between RAG and fine-tuning"
	LearningObjective string `json:"learningObjective,omitempty"`

	// Source indicates where the question content originated
	// Example: "PRESENTATION.md", "Chapter 3"
	Source string `json:"source,omitempty"`

	// Custom allows arbitrary additional metadata as key-value pairs
	Custom map[string]interface{} `json:"custom,omitempty"`
}

H5PGoExtension contains h5p-go specific metadata for questions. These fields are not part of the official H5P specification but provide useful organization and categorization capabilities.

func NewH5PGoExtension

func NewH5PGoExtension(section string, questionNumber int) *H5PGoExtension

NewH5PGoExtension creates a new H5PGoExtension with the given section and question number

func (*H5PGoExtension) WithDifficulty

func (e *H5PGoExtension) WithDifficulty(difficulty string) *H5PGoExtension

WithDifficulty sets the difficulty and returns the extension for chaining

func (*H5PGoExtension) WithLearningObjective

func (e *H5PGoExtension) WithLearningObjective(objective string) *H5PGoExtension

WithLearningObjective sets the learning objective and returns the extension for chaining

func (*H5PGoExtension) WithSource

func (e *H5PGoExtension) WithSource(source string) *H5PGoExtension

WithSource sets the source and returns the extension for chaining

func (*H5PGoExtension) WithTags

func (e *H5PGoExtension) WithTags(tags ...string) *H5PGoExtension

WithTags sets the tags and returns the extension for chaining

func (*H5PGoExtension) WithTopic

func (e *H5PGoExtension) WithTopic(topic string) *H5PGoExtension

WithTopic sets the topic and returns the extension for chaining

type H5PPackage

type H5PPackage struct {
	PackageDefinition *PackageDefinition `json:"-"`
	Content           *Content           `json:"-"`
	Libraries         []*Library         `json:"-"`
}

func LoadH5PPackage

func LoadH5PPackage(filePath string) (*H5PPackage, error)

func NewH5PPackage

func NewH5PPackage() *H5PPackage

func (*H5PPackage) AddLibrary

func (pkg *H5PPackage) AddLibrary(lib *Library)

func (*H5PPackage) CreateZipFile

func (pkg *H5PPackage) CreateZipFile(outputPath string) error

func (*H5PPackage) SetContent

func (pkg *H5PPackage) SetContent(content *Content)

func (*H5PPackage) SetPackageDefinition

func (pkg *H5PPackage) SetPackageDefinition(def *PackageDefinition)

type Library

type Library struct {
	Definition  *LibraryDefinition `json:"-"`
	Semantics   interface{}        `json:"-"`
	MachineName string             `json:"-"`
	Files       map[string][]byte  `json:"-"`
}

type LibraryDefinition

type LibraryDefinition struct {
	Title          string              `json:"title"`
	MachineName    string              `json:"machineName"`
	MajorVersion   int                 `json:"majorVersion"`
	MinorVersion   int                 `json:"minorVersion"`
	PatchVersion   int                 `json:"patchVersion"`
	Runnable       bool                `json:"runnable"`
	Author         string              `json:"author,omitempty"`
	License        string              `json:"license,omitempty"`
	Description    string              `json:"description,omitempty"`
	PreloadedJs    []FileReference     `json:"preloadedJs,omitempty"`
	PreloadedCss   []FileReference     `json:"preloadedCss,omitempty"`
	DropLibraryCss []FileReference     `json:"dropLibraryCss,omitempty"`
	Dependencies   []LibraryDependency `json:"preloadedDependencies,omitempty"`
}

type LibraryDependency

type LibraryDependency struct {
	MachineName  string `json:"machineName"`
	MajorVersion int    `json:"majorVersion"`
	MinorVersion int    `json:"minorVersion"`
}

type MultiChoiceQuestion

type MultiChoiceQuestion struct {
	Library    string                     `json:"library"`
	Params     *schemas.MultiChoiceParams `json:"params"`
	Extensions *Extensions                `json:"extensions,omitempty"`
}

MultiChoiceQuestion represents a typed H5P MultiChoice question

func NewMultiChoiceQuestion

func NewMultiChoiceQuestion(params *schemas.MultiChoiceParams) *MultiChoiceQuestion

NewMultiChoiceQuestion creates a new typed MultiChoice question

func NewMultiChoiceQuestionWithExtensions

func NewMultiChoiceQuestionWithExtensions(params *schemas.MultiChoiceParams, ext *H5PGoExtension) *MultiChoiceQuestion

NewMultiChoiceQuestionWithExtensions creates a new typed MultiChoice question with h5p-go extensions

func (*MultiChoiceQuestion) ToQuestion

func (mcq *MultiChoiceQuestion) ToQuestion() *Question

ToQuestion converts a MultiChoiceQuestion to a generic Question

func (*MultiChoiceQuestion) WithExtensions

func (mcq *MultiChoiceQuestion) WithExtensions(ext *H5PGoExtension) *MultiChoiceQuestion

WithExtensions adds extensions to an existing MultiChoiceQuestion and returns it for chaining

type PackageDefinition

type PackageDefinition struct {
	Title                 string              `json:"title"`
	Language              string              `json:"language"`
	MainLibrary           string              `json:"mainLibrary"`
	EmbedTypes            []string            `json:"embedTypes"`
	License               string              `json:"license,omitempty"`
	DefaultLanguage       string              `json:"defaultLanguage,omitempty"`
	Author                string              `json:"author,omitempty"`
	PreloadedDependencies []LibraryDependency `json:"preloadedDependencies"`
	EditorDependencies    []LibraryDependency `json:"editorDependencies,omitempty"`
}

type Question

type Question struct {
	Library    string      `json:"library"`
	Params     interface{} `json:"params"`
	Extensions *Extensions `json:"extensions,omitempty"`
}

type QuestionSet

type QuestionSet struct {
	ProgressType       string           `json:"progressType,omitempty"`
	PassPercentage     int              `json:"passPercentage,omitempty"`
	BackgroundImage    *BackgroundImage `json:"backgroundImage,omitempty"`
	Questions          []Question       `json:"questions"`
	ShowIntroPage      bool             `json:"showIntroPage,omitempty"`
	StartButtonText    string           `json:"startButtonText,omitempty"`
	Introduction       string           `json:"introduction,omitempty"`
	Title              string           `json:"title,omitempty"`
	ShowResultPage     bool             `json:"showResultPage,omitempty"`
	Message            string           `json:"message,omitempty"`
	SolutionButtonText string           `json:"solutionButtonText,omitempty"`
	OverallFeedback    []FeedbackRange  `json:"overallFeedback,omitempty"`
}

func FromJSON

func FromJSON(data []byte) (*QuestionSet, error)

func (*QuestionSet) ToJSON

func (qs *QuestionSet) ToJSON() ([]byte, error)

func (*QuestionSet) Validate

func (qs *QuestionSet) Validate() error

type QuestionSetBuilder

type QuestionSetBuilder struct {
	// contains filtered or unexported fields
}
Example
builder := NewQuestionSetBuilder()

answers := []Answer{
	CreateAnswer("Paris", true),
	CreateAnswer("London", false),
	CreateAnswer("Berlin", false),
	CreateAnswer("Madrid", false),
}

feedbackRanges := []FeedbackRange{
	CreateFeedbackRange(0, 50, "You need more practice!"),
	CreateFeedbackRange(51, 80, "Good job!"),
	CreateFeedbackRange(81, 100, "Excellent work!"),
}

questionSet, err := builder.
	SetTitle("Geography Quiz").
	SetProgressType("textual").
	SetPassPercentage(60).
	SetIntroduction("Welcome to our geography quiz!").
	SetStartButtonText("Start Quiz").
	AddMultipleChoiceQuestion("What is the capital of France?", answers).
	AddOverallFeedback(feedbackRanges).
	Build()

if err != nil {
	log.Fatal(err)
}

jsonData, err := questionSet.ToJSON()
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Generated H5P Question Set:\n%s\n", string(jsonData))

loadedQuestionSet, err := FromJSON(jsonData)
if err != nil {
	log.Fatal(err)
}

err = loadedQuestionSet.Validate()
if err != nil {
	log.Fatal(err)
}

fmt.Printf("Question set validated successfully!\n")
fmt.Printf("Number of questions: %d\n", len(loadedQuestionSet.Questions))
fmt.Printf("Pass percentage: %d%%\n", loadedQuestionSet.PassPercentage)

func NewQuestionSetBuilder

func NewQuestionSetBuilder() *QuestionSetBuilder

func (*QuestionSetBuilder) AddMultipleChoiceQuestion

func (b *QuestionSetBuilder) AddMultipleChoiceQuestion(question string, answers []Answer) *QuestionSetBuilder

func (*QuestionSetBuilder) AddOverallFeedback

func (b *QuestionSetBuilder) AddOverallFeedback(ranges []FeedbackRange) *QuestionSetBuilder

func (*QuestionSetBuilder) Build

func (b *QuestionSetBuilder) Build() (*QuestionSet, error)

func (*QuestionSetBuilder) SetBackgroundImage

func (b *QuestionSetBuilder) SetBackgroundImage(path, mime string) *QuestionSetBuilder

func (*QuestionSetBuilder) SetIntroduction

func (b *QuestionSetBuilder) SetIntroduction(introduction string) *QuestionSetBuilder

func (*QuestionSetBuilder) SetPassPercentage

func (b *QuestionSetBuilder) SetPassPercentage(percentage int) *QuestionSetBuilder

func (*QuestionSetBuilder) SetProgressType

func (b *QuestionSetBuilder) SetProgressType(progressType string) *QuestionSetBuilder

func (*QuestionSetBuilder) SetStartButtonText

func (b *QuestionSetBuilder) SetStartButtonText(text string) *QuestionSetBuilder

func (*QuestionSetBuilder) SetTitle

func (b *QuestionSetBuilder) SetTitle(title string) *QuestionSetBuilder

Directories

Path Synopsis
cmd

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL