coob documentation
  • 🚀GETTING STARTED
    • ❔What is coob?
    • 📱Examples of courses
    • ⭐Subscription
  • 👩‍💻 Features of the Service
    • Courses
      • Steps
      • Content
      • Publishing Your Course
    • Students
    • Assignments
    • Monetization
    • How to Get Started
  • 🔌Plugin
    • Introduction
    • Plugin Quickstart Guide
  • Import
    • Boost Your Course Creation with Import Features on coob.app
    • Import Course Specification
  • Privacy Policy for coob.app GPT API
Powered by GitBook
On this page
  • Plugins
  • Plugin State File (state.json)
  • Plugin Settings File (settings.json)
  • Plugin Handler File (handler.lua)
  • JS API for Plugins ($_bx)
  • Example of a Hook for Saving Plugin State in edit.html (Plugin Editing)
  • Example of a Hook for Saving Plugin State in view.html (Student's Answer)
  • Deploying the Plugin
  1. Plugin

Plugin Quickstart Guide

Plugins

Plugin Structure Description

Plugins are independent modules that can be connected to a course. There are three types of plugins:

  • View Plugins - display information in the course, such as text, images, videos, etc.

  • Trainer Plugins - allow students to complete exercises like quizzes, tasks, exercises, etc.

  • Assignment Plugins - allow students to complete tasks that need to be reviewed by the teacher.

A plugin is a directory containing the necessary files and folders for its operation. In the root of the plugin, there must be a manifest.json file that describes the plugin's structure.

Example of the manifest.json file for the Single Choose plugin:

{
  "status": "active",
  "version": "1.0",
  "name": "Single Choose",
  "description": "simple single choose",
  "short_description": "simple single choose",
  "icon": "./dist/icon.png",

  "settings" : {
    "answerRequired": true
  },

  "entry": {
    "state": "./dist/state.json",
    "handler": "./dist/handler.lua",
    "settings": "./dist/settings.json",
    "edit": "./dist/edit.html",
    "view": "./dist/view.html"
  }
}
  • status - status of the plugin (active, inactive, deprecated)

  • is_public - whether the plugin is public or private

  • version - plugin version

  • name - name of the plugin

  • description - detailed description of the plugin

  • short_description - brief description of the plugin

  • icon - path to the plugin icon

  • settings - plugin settings

  • settings.answerRequired (boolean) - whether an answer is required

  • settings.assignmentApproveRequired (boolean) - whether teacher approval is required for the student's answer

  • entry - plugin files

  • entry.state - state file for the plugin

  • entry.handler - plugin handler file

  • entry.settings - plugin settings file

  • entry.edit - HTML file for editing the plugin

  • entry.view - HTML file for displaying the plugin

Plugins can contain additional files and folders necessary for their operation and the compilation of key HTML files (edit and view).

Technical Requirements for Plugins:

  • Plugins can be written in any language that can transpile to JavaScript (TypeScript, CoffeeScript, Babel, etc.).

  • Plugins should be compiled into a single file (e.g., using Webpack) — one edit.html and one view.html.


Plugin State File (state.json)

Each plugin must have a state file where the current state of the plugin is stored. The state file should contain a JSON object that describes the state variables of the plugin. The plugin's interface is generated based on the state file.

Example of the Single Choose plugin state file:

{
  "question": "",
  "options": []
}

Plugin Settings File (settings.json)

Each plugin can have a settings file where its settings are stored. This file is separate from the state file because settings may be used to configure the plugin but do not affect its state.

Example of the Single Choose plugin settings file:

{
  "JSONSchema": {
    "properties": {
      "isIgnoreErrorAnswer": {
        "type": "boolean",
        "title": "Ignore error answer",
        "default": false
      },
      "completedMessages": {
        "type": "object",
        "title": "Messages",
        "properties": {
          "success": {
            "title": "Success message",
            "type": "string",
            "default": "You did a great job!"
          },
          "wrong": {
            "title": "Wrong message",
            "type": "string",
            "default": "Sorry, you are wrong."
          }
        }
      }
    }
  },
  "UISchema": {
    "isIgnoreErrorAnswer": {
      "ui:widget": "checkbox",
      "ui:help": "If checked, the answer will be ignored if an error occurs."
    }
  }
}

The settings file is a JSON Schema object that describes the structure of the dynamic form in react-jsonschema-form (https://rjsf-team.github.io/react-jsonschema-form/).


Plugin Handler File (handler.lua)

Each "trainer" plugin must have a handler file that describes the logic of the plugin. Based on the plugin state and the input data (student’s response), the output data (result of the answer check) is generated. The Lua programming language is used.

Example of the Single Choose plugin handler file:

function main()
    local message = "Answer is required"

    -- Check and set default values for components
    local options = bx_state.component.options or {}
    local answer = bx_state.request.answer
    local settings = bx_state.component._settings or {}
    local isIgnoreErrorAnswer = settings.isIgnoreErrorAnswer or false
    local completedMessages = settings.completedMessages or {
        success = "Correct answer!",
        wrong = "Incorrect answer. Please try again."
    }

    -- Check if the answer is provided
    if not answer then
        return false, message
    end

    -- Increment the answer index, assuming the answer is an index
    answer = answer + 1

    -- Check if the answer index is valid
    if not options[answer] then
        return false, "Answer is invalid"
    end

    local messageType = "wrong"
    local isCorrect = false
    -- Check if the answer is correct
    if options[answer].isCorrect then
        isCorrect = true
        message = completedMessages.success
        messageType = "success"
    else
        -- Check if there is an explanation for the wrong answer
        if not options[answer].explanation or options[answer].explanation == "" then
            message = completedMessages.wrong
        else
            message = options[answer].explanation
        end

        -- Check if wrong answers should be ignored
        if isIgnoreErrorAnswer then
            return true, "[" .. messageType .. "]:" .. message
        end
    end

    return isCorrect, message
end
  • bx_state - global variable containing the plugin state and input data (student's answer)

    • bx_state.request - input data (student's answer)

    • bx_state.component - plugin state

    • bx_state.component._settings - plugin settings


JS API for Plugins ($_bx)

Plugins can use the JS API to interact with the platform.

Example of using $_bx API:

$_bx.onReady(() => {
    let language = $_bx.language();
});

This API offers several methods for interacting with the platform. The full list includes checking the current component state, saving states, submitting answers, showing messages, and more.


$_bx.onReady(callback: Function)

Executes the callback function after the platform has fully loaded. This is useful for initializing logic once all interface elements are loaded.

$_bx.onReady(() => {
    let language = $_bx.language();
});

$_bx.isCorrect(): boolean

Checks if the user provided a correct answer.

let isAnswerCorrect = $_bx.isCorrect();

$_bx.getComponentID(): string

Returns the ID of the current component.

let componentID = $_bx.getComponentID();

$_bx.setSaveButtonEnabled(value: boolean): void

Enables or disables the save button based on the passed value.

$_bx.setSaveButtonEnabled(true);

$_bx.isSaveButtonEnabled(): boolean

Checks if the save button is enabled. By default, the button is enabled if not specified.

let isSaveButtonActive = $_bx.isSaveButtonEnabled();

$_bx.event(): Object

Returns an object for working with events.

let eventEmitter = $_bx.event();

$_bx.mode(): string

Gets the current display mode of the platform ("light" or "dark").

let currentMode = $_bx.mode();

$_bx.language(): string

Returns the current interface language. The default is "en" if no language is specified.

let currentLanguage = $_bx.language();

$_bx.isSyllabus(): boolean

Checks if the component is part of the course syllabus.

let isSyllabusComponent = $_bx.isSyllabus();

$_bx.parseMessage(): {type: string, content: string}

Parses a message and returns an object containing the message type and its content. Supported types include: success, feedback, wrong, info.

let messageDetails = $_bx.parseMessage();

$_bx.isPendingApproval(): boolean

Checks if an answer is pending approval.

let pendingApproval = $_bx.isPendingApproval();

$_bx.isDark(): boolean

Checks if the platform is in dark mode.

let isDarkMode = $_bx.isDark();

$_bx.isLight(): boolean

Checks if the platform is in light mode.

let isLightMode = $_bx.isLight();

$_bx.isAnswerRequired(): boolean

Checks if an answer is required from the user.

let answerRequired = $_bx.isAnswerRequired();

$_bx.isAssignmentRequired(): boolean

Checks if completing an assignment is required by the user.

let assignmentRequired = $_bx.isAssignmentRequired();

$_bx.hasAnswer(): boolean

Checks if the user has provided an answer.

let hasAnswer = $_bx.hasAnswer();

$_bx.answerMessage(): string

Returns the message containing the user's answer.

let answerMsg = $_bx.answerMessage();

$_bx.getResponseId(): string

Returns the ID of the response.

let responseId = $_bx.getResponseId();

$_bx.getUser(): Object

Returns an object with the user's data.

let user = $_bx.getUser();

$_bx.getState(): Object

Returns the current state of the component.

let state = $_bx.getState();

$_bx.getSettings(key: string | null): Object | undefined

Returns the component's settings. If a key is provided, it returns the settings associated with that key.

let settings = $_bx.getSettings('theme');

$_bx.get(key: string): any

Returns the state value associated with the provided key.

let value = $_bx.get('user.name');

$_bx.push(key: string, value: any): void

Updates the state for the specified key and triggers corresponding events.

$_bx.push('user.name', 'John Doe');

$_bx.clean(key: string): void

Clears the state value for the specified key.

$_bx.clean('user.name');

$_bx.saveState(): Promise

Saves the current state of the component.

await $_bx.saveState();

$_bx.fixView(): void

Deprecated method for fixing the view. Use refreshHeight instead.

$_bx.fixView();

$_bx.contentLoaded(): void

Notifies that the content has been loaded.

$_bx.contentLoaded();

$_bx.showMessageBox(variant: string, message: string): void

Displays a message to the user with the specified style variant.

$_bx.showMessageBox('success', 'Your answer was correct!');

$_bx.showModal(title: string, message: string): void

Displays a modal window with a title and message.

$_bx.showModal('Notice', 'This is an important message.');

$_bx.dangerouslyShowModal(title: string, html: string): void

Displays a modal window with HTML content (no JavaScript).

$_bx.dangerouslyShowModal('Alert', '<b>Important:</b> Please read carefully.');

$_bx.showSuccessMessage(message: string): void

Displays a success message to the user.

$_bx.showSuccessMessage('Your changes were saved successfully.');

$_bx.showErrorMessage(message: string): void

Displays an error message to the user.

$_bx.showErrorMessage('An error occurred while saving.');

$_bx.showWarningMessage(message: string): void

Displays a warning message to the user.

$_bx.showWarningMessage('Be careful with your changes.');

$_bx.showInfoMessage(message: string): void

Displays an informational message to the user.

$_bx.showInfoMessage('Please review the instructions.');

$_bx.showAbout(): void

Displays a dialog with information about the component.

$_bx.showAbout();

$_bx.isShowSettings(): boolean

Checks if the settings dialog should be displayed.

let showSettings = $_bx.isShowSettings();

$_bx.showSettings(): void

Displays the settings dialog for the component.

$_bx.showSettings();

$_bx.sendMessage(message: string): void

Sends a message to the parent frame.

$_bx.sendMessage(JSON.stringify({ type: 'update', data: { key: 'value' } }));

$_bx.reset(): void

Resets the component's state and closes the dialog.

$_bx.reset();

$_bx.uploadFile(blob: Blob, onProgress: Function, originalFileName: string): Promise<Object>

Uploads a file and tracks the upload progress.

$_bx.uploadFile(fileBlob, (progress) => console.log(progress), 'myfile.txt')
    .then((response) => console.log(response.fileURL));

Example of a Hook for Saving Plugin State in edit.html (Plugin Editing)

$_bx.event().on("before_save_state", (v) => {
    if (this.state.options.length === 0) {
        $_bx.showErrorMessage(userMessages.addOption);
        return;
    }

    if (this.state.options.filter((option) => option.isCorrect).length === 0) {
        $_bx.showErrorMessage(userMessages.selectCorrect);
        return;
    }

    if (this.state.options.filter((option) => option.isCorrect).length > 1) {
        $_bx.showErrorMessage(userMessages.selectOnlyOne);
        return;
    }

    if (this.state.options.length > 10) {
        $_bx.showErrorMessage(userMessages.addAtMost);
        return;
    }

    if (!this.validateOptions()) {
        $_bx.showErrorMessage(userMessages.enterText);
        return;
    }

    if (this.state.options.length === 1) {
        $_bx.showErrorMessage(userMessages.addAtLeastTwo);
        return;
    }

    v.state = this.state;
});


Example of a Hook for Saving Plugin State in view.html (Student's Answer)

// Sync local state with global component state
$_bx.event().on("before_submit", (v) => {
  if (this.state.answer === null || this.state.answer === undefined || this.state.answer === "" || this.state.answer < 0) {
    $_bx.showErrorMessage("Error: Please select an option to continue.");
    return;
  }
  v.state.answer = this.state.answer;
});


Deploying the Plugin

coobcli is a command-line tool that allows you to manage plugins and their versions, as well as publish them to the plugin repository.

Installing coobcli:

npm i coobcli

Using coobcli:

Commands:
index.js login    Authenticate on coob.app
index.js publish  Publish plugin on coob.app

Options:
--version  Show version number                                       [boolean]
--help     Show help
PreviousIntroductionNextBoost Your Course Creation with Import Features on coob.app

Last updated 8 months ago

🔌