LMS Builder

Build your own course inside of Brick Builder. 

[course_navigation]
rbd logo

← How to build a course platform

[lesson_nav_arrows]

[lesson_number_display]

Adding Schema in BricksBuilder Using Custom Fields

[lesson_backup_reminder url=/reminder threshold=6]
[lessons_completed_arrows arrows=yes]

Adding Schema in Bricks Builder Using Custom Fields (WordPress SEO)

This is Erik with RankByDesign. In this lesson I’ll show you how to add schema markup to your WordPress course pages using Bricks Builder and custom fields.

Important: I’m not affiliated with Bricks Builder in any way. This is a free tutorial showing how I use Bricks Builder to build a course platform (and improve SEO along the way).

Recommended: Work on a staging site and perform a full backup before editing theme files or adding custom code.

FAQ: Common Schema Questions Clients Ask

Does schema help SEO?
Yes — schema helps Google understand your content better, which can improve visibility and rich results, but it’s not a guaranteed ranking boost.

Do I need schema on every page?
No. Schema is most valuable on key pages like service pages, course pages, lesson pages, blog posts, and product pages — not necessarily every page on the site.

Can Bricks Builder add schema without plugins?
Yes. In this lesson, we add schema using custom fields and a simple functions.php script, so schema can be added without installing a dedicated schema plugin.

Will schema make my site rank higher automatically?
Not automatically. Schema supports SEO, but content quality, internal links, user experience, speed, and trust still matter most.

How do we know if schema is working?
You validate it using a schema testing tool (like schema.org’s validator). If schema shows up and has no errors, it’s working.

What schema type is best for course content?
For course platforms, “Course” works well for a main course page, and “LearningResource” is often best for individual lesson pages.

Why Schema Matters for WordPress SEO

Schema markup (also called structured data) helps search engines better understand what your page is about. When Google can interpret your page content more clearly, it may display enhanced results such as rich snippets.

Schema is especially useful for a WordPress course or LMS website because your pages have a clear structured purpose: lessons, tutorials, learning resources, and course overviews.

Bottom line: Schema won’t replace great content, but it helps search engines interpret your content correctly — which supports visibility over time.

What We’re Doing in This Lesson

Instead of manually writing schema markup for every page, we’re going to build a simple system where schema data is controlled using custom fields.

This is a powerful approach for WordPress course sites because it lets you:

  • reuse a consistent schema structure across lesson pages
  • control schema per lesson (on/off toggle)
  • avoid editing code repeatedly
  • keep schema accurate and organized as your course grows

Once your schema fields are created, a short script automatically pulls your schema custom field values and outputs JSON-LD markup into the <head> section of your page.

Step 1: Add the Schema Function Code to Your Theme

To do this, we’ll add a schema script to WordPress by editing the theme’s functions file:

  • Go to Appearance → Theme File Editor
  • Locate your functions.php file
  • Paste in the schema function code (from the Lesson Resources section)
  • Click Update File

Important safety note: You should always add custom code to a child theme (or use a Code Snippets plugin). Otherwise, theme updates can overwrite your changes.

Tip: Place the schema code at the bottom of functions.php so it’s easy to find later.

Step 2: Create a Schema Field Group (Custom Fields)

Next, we need a dedicated custom field group for schema.

You can use ACF (Advanced Custom Fields), SCF, or another custom fields plugin — the key is that your schema fields must match the names expected by your script.

Important: These fields are specific to the script. Do not rename the fields unless you also update the function code to match.

Schema Custom Fields (Reference Table)

These custom field names must match the function code exactly. If you rename the fields, the script must be updated to match.

Field Label Field Name (Example) Recommended Field Type What It Controls
Include Schema include_schema True / False Turns schema output on or off for the page
Schema Title schema_title Text The structured title used in the schema markup
Schema Description schema_description Text Area A short structured summary used by search engines
Schema Time schema_time Number Lesson duration (example: 0.1 ≈ ~5–6 minutes)
Schema Keywords schema_keywords Text Area Keywords relevant to the lesson (often matches YouTube tags)
Schema Include Video schema_include_video True / False Adds VideoObject schema when the lesson includes video content
Schema Type schema_type Radio Button Controls schema type output (example: LearningResource or Course)

Recommended Schema Type Values (So Validation Works)

If you create the Schema Type field as a radio button, you should use these exact values (because the script outputs them directly):

  • LearningResource (recommended for lesson pages)
  • Course (recommended for the main course overview page)

Tip: If Schema Type is not defined, the script may fallback to a more general type such as CreativeWork.

Step 3: Fill Out Schema Fields on Your Lesson Pages

Now go into one of your lesson posts (for example: a lesson inside your “Video Classes” custom post type). Scroll to the bottom and fill out the schema fields you created.

Typical values per lesson:

  • Schema Title: the lesson title
  • Schema Description: a short lesson summary
  • Schema Time: duration of the lesson
  • Schema Keywords: keyword phrases related to the lesson topic
  • Schema Include Video: enabled when lesson has a video

Once complete, click Update to save the lesson page.

Step 4: Validate Your Schema Markup

Validation is the last step — and it’s important.

  • View the lesson page on the front end
  • Copy the full lesson URL
  • Paste it into the schema validator tool
  • Confirm your schema shows up with no errors

If the validator shows schema types detected (and no errors), your schema system is working properly.

Why This Works Well for WordPress Course Platforms

Most WordPress LMS sites grow over time. New lessons get added, content gets edited, and course pages expand.

When schema is managed through custom fields instead of manual code edits, you get a long-term system that stays clean and scalable.

This is one of those improvements that pays off later — especially if you plan to grow a course library, build a training portal, or create a membership platform using WordPress.

Function Code Used in This Lesson

Where to paste this: Copy/paste the code below into your Bricks Child Theme file:

  • Appearance → Theme File Editor
  • Select: Bricks Child Theme
  • Open: functions.php
  • Paste the code near the bottom of the file
  • Click Update File

Important warning: Your functions.php file almost always already contains the opening PHP tag at the top. That means the file already begins with:

<?php

So do NOT add another <?php tag. The code below is intentionally provided without it.

Backup / recovery warning: If WordPress fails to save your file, or if you paste something incorrectly, your site may display a fatal error. Make sure you have access to your hosting (example: cPanel / File Manager) so you can open the functions.php file and undo the change if needed.

Schema Function Code


// Place this code in your functions.php in your Bricks Builder Child Theme
function add_schema_based_on_custom_field() {

    $options = array(
        'include_schema_field'       => 'include_schema',
        'schema_type_field'          => 'schema_type',
        'schema_title_field'         => 'schema_title',
        'schema_description_field'   => 'schema_description',
        'schema_keywords_field'      => 'schema_keywords',
        'schema_time_field'          => 'schema_time',

        // Video handling
        'video_id_field'             => 'video_id',

        // Course fields
        'course_instance_start_date_field' => 'course_instance_start_date',
        'course_instance_end_date_field'   => 'course_instance_end_date',
        'course_instance_course_mode_field'=> 'course_instance_course_mode',

        'offers_price_field'         => 'offers_price',
        'offers_currency_field'      => 'offers_currency',

        'provider_name_field'        => 'provider_name',
        'provider_url_field'         => 'provider_url',

        // Lesson query settings
        'lesson_key_field'           => 'lesson',
        'lesson_course_field'        => '',
        'lesson_post_type'           => 'video-class',
    );

    if ( ! function_exists('get_field') ) {
        return;
    }

    // Only proceed if schema is enabled
    if ( ! get_field( $options['include_schema_field'] ) ) {
        return;
    }

    $schema_type = get_field( $options['schema_type_field'] ) ?: 'CreativeWork';

    $schema = array(
        "@context" => "https://schema.org",
        "@type"    => $schema_type,
    );

    // Base schema fields
    $fields = array(
        'name'        => get_field( $options['schema_title_field'] ),
        'description' => get_field( $options['schema_description_field'] ),
        'url'         => get_permalink(),
        'keywords'    => get_field( $options['schema_keywords_field'] ),
    );

    foreach ( $fields as $key => $value ) {
        if ( ! empty( $value ) ) {
            $schema[ $key ] = $value;
        }
    }

    // Time required (hours or fractional hours -> ISO 8601 duration)
    $time_required = get_field( $options['schema_time_field'] );
    if ( $time_required ) {
        if ( strpos( (string) $time_required, '.' ) !== false ) {
            $hours   = floor( $time_required );
            $minutes = round( ( $time_required - $hours ) * 60 );
            $time_required = "PT{$hours}H{$minutes}M";
        } else {
            $time_required = "PT{$time_required}H";
        }
        $schema['timeRequired'] = $time_required;
    }

    // If schema type is Course, attach course-specific metadata + lessons
    if ( strtolower( $schema_type ) === 'course' ) {

        // CourseInstance
        $courseInstance = array("@type" => "CourseInstance");

        $startDate = get_field( $options['course_instance_start_date_field'] );
        $endDate   = get_field( $options['course_instance_end_date_field'] );
        $courseMode= get_field( $options['course_instance_course_mode_field'] );

        if ( $startDate )  $courseInstance['startDate']  = $startDate;
        if ( $endDate )    $courseInstance['endDate']    = $endDate;
        if ( $courseMode ) $courseInstance['courseMode'] = $courseMode;

        if ( count($courseInstance) > 1 ) {
            $schema['hasCourseInstance'] = $courseInstance;
        }

        // Offers
        $offer = array("@type" => "Offer", "url" => get_permalink());

        $price = get_field( $options['offers_price_field'] );
        $curr  = get_field( $options['offers_currency_field'] );

        if ( $price ) $offer['price'] = $price;
        if ( $curr )  $offer['priceCurrency'] = $curr;

        if ( count($offer) > 2 ) {
            $schema['offers'] = $offer;
        }

        // Provider
        $provider = array("@type" => "Organization");

        $provider_name = get_field( $options['provider_name_field'] );
        $provider_url  = get_field( $options['provider_url_field'] );

        if ( $provider_name ) $provider['name'] = $provider_name;
        if ( $provider_url )  $provider['url']  = $provider_url;

        if ( count($provider) > 1 ) {
            $schema['provider'] = $provider;
        }

        // Query lessons
        $current_course_id = get_the_ID();

        $meta_query = array(
            array(
                'key'     => $options['lesson_key_field'],
                'compare' => 'EXISTS'
            )
        );

        if ( ! empty( $options['lesson_course_field'] ) ) {
            $meta_query[] = array(
                'key'     => $options['lesson_course_field'],
                'value'   => $current_course_id,
                'compare' => '='
            );
        }

        $args = array(
            'post_type'      => $options['lesson_post_type'],
            'posts_per_page' => -1,
            'meta_query'     => $meta_query,
        );

        $lessons_query = new WP_Query( $args );

        $lessons_schema = array();

        if ( $lessons_query->have_posts() ) {
            while ( $lessons_query->have_posts() ) {
                $lessons_query->the_post();

                $lesson_title = get_field( $options['schema_title_field'] );
                $lesson_desc  = get_field( $options['schema_description_field'] );

                if ( empty( $lesson_title ) || empty( $lesson_desc ) ) {
                    continue;
                }

                $lesson_schema = array(
                    "@type"       => "CreativeWork",
                    "name"        => $lesson_title,
                    "description" => $lesson_desc,
                    "url"         => get_permalink(),
                    "datePublished" => get_the_date('c'),
                );

                $lesson_time = get_field( $options['schema_time_field'] );
                if ( $lesson_time ) {
                    if ( strpos( (string) $lesson_time, '.' ) !== false ) {
                        $hours   = floor( $lesson_time );
                        $minutes = round( ( $lesson_time - $hours ) * 60 );
                        $lesson_time = "PT{$hours}H{$minutes}M";
                    } else {
                        $lesson_time = "PT{$lesson_time}H";
                    }
                    $lesson_schema['timeRequired'] = $lesson_time;
                }

                $lesson_video_id = get_field( $options['video_id_field'] );
                if ( $lesson_video_id ) {
                    $lesson_schema['video'] = array(
                        "@type"      => "VideoObject",
                        "contentUrl" => get_permalink(),
                        "uploadDate" => get_the_date('c'),
                    );
                    $lesson_schema['thumbnailUrl'] = "https://img.youtube.com/vi/{$lesson_video_id}/hqdefault.jpg";
                }

                $lessons_schema[] = $lesson_schema;
            }
            wp_reset_postdata();
        }

        if ( ! empty( $lessons_schema ) ) {
            $schema['hasPart'] = $lessons_schema;
        }

    } else {

        // Non-course pages: include lesson video schema only once
        $video_id = get_field( $options['video_id_field'] );
        if ( $video_id ) {
            $schema['video'] = array(
                "@type"      => "VideoObject",
                "contentUrl" => get_permalink(),
                "uploadDate" => get_the_date('c'),
            );
            $schema['thumbnailUrl'] = "https://img.youtube.com/vi/{$video_id}/hqdefault.jpg";
        }

        $schema['datePublished'] = get_the_date('c');
    }

    $json_ld = json_encode( $schema, JSON_UNESCAPED_SLASHES );
    echo '<script type="application/ld+json">' . $json_ld . '</script>';
}
add_action( 'wp_head', 'add_schema_based_on_custom_field' );

Lesson Overview

Main Points

√ Schema markup helps search engines better understand your WordPress lesson pages.
√ We add schema using custom fields so it’s dynamic and repeatable.
√ Schema fields are stored in a field group and must match the function code names.
√ The schema function code is added to functions.php so schema loads into the page head.
√ Lesson schema can include title, description, duration, keywords, and optional video schema.
√ You validate schema by testing your front-end lesson URL in a schema validator.
√ LearningResource is a great schema type for lesson pages, while Course works well for overviews.

Lesson Resources

Schema ACF Function

Premium Content

Subscribe today for premium content.

[complete_lesson_button]
[lessons_completed_text]
Review Your Cart
0
Add Coupon Code
Subtotal