Register Custom Fields in Tutor LMS Course Builder

The Tutor LMS Course Builder provides an extensible system that allows third-party plugins to inject custom fields and content into predefined slots within the course builder interface. This system is inspired by the WordPress hook mechanism and allows developers to extend the Tutor LMS native course builder by adding custom fields within it.

How It Works

  • Developers can register fields dynamically in the course builder using the registerField function.
  • Fields can be added to specific slots, ensuring they appear in the desired sections.
  • Supports different field types, including text, password, textarea, select, radio, WPEditor, custom components, etc.
  • Developers can inject arbitrary content, not just form fields.

1. Download the Demo Plugin

To begin, download the ‘Tutor LMS Custom Fields’ demo plugin. This plugin serves as a reference structure that you can update accordingly in order to add your customized settings.

Tutor LMS Custom Fields Directory Structure

Once you’ve downloaded the plugin, you’ll notice the following file structure:

tutor-lms-custom-fields/
│
├── custom-fields.js
└── tutor-lms-custom-fields.php
  • custom-fields.js: This file contains JavaScript code to register custom fields in the course builder interface.
  • tutor-lms-custom-fields.php: It contains PHP functions to enqueue scripts, save field data, and display field values.

2. Creating and Registering Custom Fields

Custom fields are registered using JavaScript through the Tutor LMS course builder API. Create a custom-fields.js file with the following structure:

document.addEventListener("DOMContentLoaded", function () {
   if (typeof Tutor !== "undefined" && Tutor.CourseBuilder) {
      
       // Register a textarea field
       Tutor.CourseBuilder.Basic.registerField("after_description", {
           name: "seo_content",
           type: "textarea",
           label: "SEO Content",
           placeholder: "Write here...",
           priority: 20,
       });

       // Register a number field
       Tutor.CourseBuilder.Curriculum.Lesson.registerField("bottom_of_sidebar", {
           name: "lesson_duration",
           type: "number",
           label: "Lesson Duration (minutes)",
           priority: 5,
       });
   }
});

We’ve added two custom fields here. The first is a textarea field called SEO Content, located in the Basics tab. The second is a number field called Lesson Duration (minutes), placed at the bottom of the Lesson sidebar.

Here’s the SEO Content field in the Basics section:

Tutor LMS Custom field in the Basics tab

Here’s the Lesson Duration field at the bottom of the Lesson sidebar:

Tutor LMS custom field in the lessons sidebar

3. Enqueuing Scripts to Show Custom Fields

You must enqueue your JavaScript file to display your custom fields in the course builder. To do this, create the tutor-lms-custom-fields.php file and add the following code:

<?php
/**
 * Plugin Name: Tutor LMS Custom Fields
 * Description: Adds custom fields to Tutor LMS course builder.
 * Version: 1.0.0
 * Author: Themeum
 */

add_action('tutor_after_course_builder_load', 'tlcf_enqueue_scripts');
/**
* Enqueue custom scripts for course builder
*
* @return void
*/
function tlcf_enqueue_scripts() {
   $js_url = plugin_dir_url( __FILE__ ) . 'custom-fields.js';
   wp_enqueue_script(
       'tlcf-custom-fields-js',
       $js_url,
       array( 'tutor-course-builder' ),
       '1.0.0',
       true
   );
}

// ... (rest of the code will be added here)
?>

This function hooks into tutor_after_course_builder_load to ensure the script is loaded only when the course builder is active, and it depends on the tutor-course-builder script.

4. Storing Custom Field Values

When a course is saved, you need to capture and store the custom field values:

add_action('save_post_courses', 'tlcf_save_course_meta');
/**
* Save custom field data when course is saved
*
* @param int $post_id Course post ID.
*
* @return void
*/
function tlcf_save_course_meta( int $post_id ) {
   $seo_content = sanitize_text_field( wp_unslash( $_POST['seo_content'] ) ?? '' );
   if ( $seo_content ) {
       update_post_meta( $post_id, 'tlcf_seo_content', $seo_content );
   }
}

You can specify the following things here:

  • add_action('save_post_courses', 'tlcf_save_course_meta'): This hooks into the course saving process.
  • $_POST['seo_content']: Retrieves the value of the seo_content field.
  • sanitize_textarea_field(): Sanitizes the input to prevent security vulnerabilities.
  • update_post_meta(): Stores the sanitized value in the WordPress post meta table.

5. Displaying Custom Field Data

To make custom field data available to the frontend or REST API, use the tutor_course_details_response filter:

add_filter('tutor_course_details_response', 'tlcf_display_custom_field_data');
/**
* Display custom field data in course details
*
* @param array $data Course data array.
*
* @return array Modified course data array with custom field
*/
function tlcf_display_custom_field_data( array $data ) {
   $course_id   = $data['ID'];
   $seo_content = get_post_meta( $course_id, 'tlcf_seo_content', true );
   if ( $seo_content ) {
       $data['seo_content'] = $seo_content;
   }
   return $data;
}

Here’s the explanation of this:

  • add_filter('tutor_course_details_response', 'tlcf_display_custom_field_data'): This filters the course details response, allowing you to add custom data.
  • get_post_meta(): Retrieves the stored custom field values.
  • $data['seo_content'] = $seo_content;: Adds the custom field value to the course details response.

Hooking into the System

You can extend Tutor LMS Course Builder by using the following filter and action hooks.

Filter Hooks

apply_filters( 'tutor_course_details_response', array $course_data );
apply_filters( 'tutor_quiz_details_response', WP_Post $data, int $quiz_id );
apply_filters( 'tutor_assignment_details_response', array $post, int $assignment_id );
apply_filters( 'tutor_lesson_details_response', array $post, int $lesson_id );

Action Hooks

do_action( "save_post_courses", int $post_id, WP_Post $post, bool $update );
do_action( "save_post_lesson", int $post_id, WP_Post $post bool $update );
do_action( "save_post_tutor_assignments", int $post_id, WP_Post $post bool $update );
do_action( "save_post_tutor_quiz", int $post_id, WP_Post $post bool $update );

Available Field Registration Options

When registering a field, you can specify:

PropertyTypeDescription
namestringUnique name for the field (this field is required).
typetexttext,
number,
password,
textarea,
select,
radio,
checkbox,
switch,
date,
time,
image,
video,
uploader,
WPEditor
labelstringLabel for the field.
placeholderstringPlaceholder text (optional).
optionsarrayRequired for select and radio fields.
Example: [{ value: '1', label: 'Option 1' }].
prioritynumberDetermines order within the slot (lower values appear first).
rulesobjectValidation rules for React Hook Form.

Available Slots

Here are the available slots where you can insert custom fields:

Basics Section

  1. after_description
  2. after_settings

Curriculum Section

  • Lesson
  1. after_description
  2. bottom_of_sidebar
  • Quiz
  1. after_question_description
  2. bottom_of_question_sidebar
  3. bottom_of_settings
  • Assignment
  1. after_description
  2. bottom_of_sidebar

Additional Section

  1. after_certificates
  2. bottom_of_sidebar

FAQ

Q: How do I validate fields?

Use the rules property when registering a field:

Example 1: Required field validation

const requiredRule = () => ({
    required: { value: true, message: 'This field is required' },
});

Example 2: Max limit validation

const maxLimitRule = (maxLimit) => ({
    validate: (value) => {
        if (value && maxLimit < value.length) {
            return `Maximum ${maxLimit} character supported`;
        }
        return undefined;
    },
});

By following this documentation, you can extend Tutor LMS with custom fields tailored to your specific needs.

Was this helpful?