• Skip to main content
  • Skip to primary sidebar
  • Skip to footer

nSiteful Web Builders

Building a Better Web - One Site at a Time.

  • Home
  • About
    • Testimonials
    • Resources
    • Partner With Me
    • Frequently Asked Questions
  • Web Sites
  • Online Marketing
  • WordPress Support
    • Customized WordPress Training
    • 60-for-60 Sessions
  • Web Applications
  • Blog
    • At-A-Glance
    • Blog Articles Grouped by Category
    • Case Studies
    • General
    • Portfolio
    • Reviews
    • Snippets
    • Techniques
    • Projects
  • Contact
    • Purchase Retainer Consulting Hours
    • About Retainer Consulting Hours
    • Book a Meeting with Jeff
    • Tell Me About Your Web Project
    • nSiteful Newsletter Archives
    • nSiteful Rewards
Custom Lesson Icons

By Jeff - 11/1/2021
Cats: Techniques · Tags: MemberPress, MemberPress Courses, Membership Sites, WordPress

techniques

Use Custom Lesson Icons for MemberPress Courses

Last updated March 1st, 2024 at 05:36 pm

I’m currently working on a Web site that offers online courses. I’m using the MemberPress Membership Plugin to restrict course content to registered members, and I’m using MemberPress’ Courses LMS addon for developing the course curriculums.

In the future, I may publish a full review of MemberPress and MemberPress Courses (hint: it will be positive). For now, however, I just want to share one small but nagging problem I encountered with Courses and how I solved it.

Disclaimer: I am an affiliate for MemberPress. What this means is that if you purchase MemberPress by clicking on my affiliate link, I will earn a small commission — but there is no additional cost to you.

The Problem/My Goal:

Icons which appear in front of lesson names (both in the main body of the page and in the lesson navigation sidebar) are all the same: little document graphics. What I wanted — partly because I’ve seen and like this in online courses I have taken — is for different icons to appear for different kinds of lessons.

I want custom lesson icons.

If the lesson includes a video, I want an icon representing a video to appear. If the lesson includes downloadable assets, I want an icon representing downloads (like a paper clip) to appear. If the lesson includes a quiz, I want an appropriate icon to appear. And so on.

Here’s what I was getting by default (click to enlarge):

Default lesson icons
Default Lesson Icons (NOT what I wanted)

Close-up of Default Icons:

Closeup of Default Icons

More before images here (click to enlarge):

custom-icons-before-01
Custom Lesson Icons
custom-icons-before-02
Custom Lesson Icons
custom-icons-before-03
Custom Lesson Icons
custom-icons-before-04

Here’s my goal (click to enlarge):

Custom lesson icons
This is my goal: notice the sematic icons.

Close-up of Custom Lesson Icons:

Closeup of Custom Icons

More images showing custom lesson icons here (click to enlarge):

Custom Lesson Icons
custom-icons-after-01
Custom Lesson Icons
custom-icons-after-02
Custom Lesson Icons
custom-icons-after-03
Custom Lesson Icons
custom-icons-after-04

My idea was that if I could assign categories or tags to Lessons (which one can do with Courses), I could then use theme customizations and custom CSS to display the icons I wanted.

Good idea. But I quickly discovered that there were two major challenges I had to overcome to achieve my goal:

  1. By default, MemberPress Lessons (CPT mpcs-lesson do not have taxonomies registered to them. (MemberPress Courses do support Course Categories and Course Tags.)
  2. The MemberPress Courses theme (“Classroom Mode”) is not lesson-taxonomy-aware, which makes sense since MemberPress Lessons don’t support taxonomies.

Solution Overview – Using Custom Lesson Icons:

The solution required several tasks and involved several tools:

Tasks:

  1. Register a custom taxonomy for lessons (I wanted tags)
  2. Create an admin interface for assiging lesson tags to lessons
  3. Create a function for adding appropriate lesson-tag names to the body class
  4. Override and customize the default MemberPress Courses template that generates the sidebar lesson navigation
  5. Include Fontawesome
  6. Create appropriate CSS rules
  7. Link stylesheet in courses header

Tools:

These are the tools that helped me achieve my goal.

  • Admin Menu Editor plugin
  • Admin Columns Pro plugin
  • Fontawesome (for icons)

Solution Details – Custom Lesson Icons:

Step 1:Register the taxonomy.

By default, MemberPress Lessons cannot have taxonomies assigned to them. This step will fix that “problem”.

Here’s the code, which I added to the functions.php file in my mu-plugins folder.

function fto_tax_lesson_tags() {

  $labels = array(
    'name'                       => 'Lesson Tags',
    'singular_name'              => 'Lesson Tag',
    'menu_name'                  => 'Lesson Tags',
    'all_items'                  => 'All Lesson Tags',
    'parent_item'                => 'Parent Item',
    'parent_item_colon'          => 'Parent Item:',
    'new_item_name'              => 'New Lesson Tag',
    'add_new_item'               => 'Add New Lesson Tag',
    'edit_item'                  => 'Edit Lesson Tag',
    'update_item'                => 'Update Lesson Tag',
    'view_item'                  => 'View Lesson Tag',
    'separate_items_with_commas' => 'Separate items with commas',
    'add_or_remove_items'        => 'Add or remove Lesson Tags',
    'choose_from_most_used'      => 'Choose from the most used',
    'popular_items'              => 'Popular Lesson Tags',
    'search_items'               => 'Search Lesson Tag',
    'not_found'                  => 'Not Found',
    'no_terms'                   => 'No items',
    'items_list'                 => 'Lesson Tags list',
    'items_list_navigation'      => 'Lesson Tags list navigation',
  );
  $args = array(
    'labels'                     => $labels,
    'hierarchical'               => false,
    'public'                     => true,
    'show_ui'                    => true,
    'show_admin_column'          => true,
    'show_in_nav_menus'          => true,
    'show_tagcloud'              => true,
  );
  register_taxonomy( 'lesson_tags', array( 'mpcs-lesson' ), $args );
}
add_action( 'init', 'fto_tax_lesson_tags', 0 );

Step 2:Create Admin Interface for Lessons

The default MemberPress Courses admin interface requires the block editor for adding Lesson content. And since MemberPress Courses addon does not natively support custom taxonomies for Lessons, I knew that I wouldn’t be able to assign lesson tags to lessons using that default interface — and I had no interest in hacking the code to make it possible.

Also, truth be told, I still prefer the Classic Editor for some editing purposes, especially course lessons.

Using the Admin Menu Editor plugin, I was able to add a custom menu to the WordPress dashboard, effectively adding a new browse screen for Lessons.

Here’s the URL for the new menu:

edit.php?post_type=mpcs-lesson.

Now that I could browse Lessons like any other post, I wanted to simplify the process of adding lesson tags to lessons. Using the Admin Columns Pro plugin, I was able to add a columm for Lesson Tags to the browse screen, which allowed me to inline-edit each lesson and add the Lesson Tags. Going a step further, I enabled the Bulk Editing feature of Admin Columns Pro so that I could assign lesson tags to multiple lessons at one time.

Step 3:Add Lesson Tag(s) to body class.

So let’s recap what’s already been done:

  1. I’ve registered lesson tags for MemberPress Lessons.
    This allows me to assign tags to lessons.
  2. I’ve created an admin interface for assigning lesson tags to lessons.
    That is, “Lessons” now shows up as a MemberPress sub-menu, and I can browse lessons just like I can browse so many other post types. This means I can use “Quick Edit” to assign tags. Also, thanks to Admin Columns Pro, I can bulk edit lessons and add a tag to many at one time.

Now what I need to do is customize WordPress so that the class attribute of the body element includes the slug of each lesson tag assigned in step 2. This will enable me to use CSS rules to target lesson content based on each lesson’s lesson tag(s).

Here is an example of what the body element for a lesson with the tag “Script” looks like when viewing source. Line 3 is the class name I need. (I added line breaks and removed some class values for simplicity.)

<body class="mpcs-lesson-template-default single 
single-mpcs-lesson postid-1455 
lesson-tag-script 
this-post-type_mpcs-lesson">

Here’s the code to accomplish my objective:

add_action('after_setup_theme', 'nwb_add_tax_to_single_action');
function nwb_add_tax_to_single_action($classes) {
  add_filter('body_class','nwb_add_tax_to_single');
  function nwb_add_tax_to_single($classes) {
    $this_post_type = get_post_type(get_the_ID());
    $post_type_cos = 'this-post-type_' . $this_post_type;
    if ( is_single() ) {
      global $post;
      $taxonomy_terms = get_the_terms($post->ID, 'lesson_tags'); // change to your taxonomy
      if ( $taxonomy_terms ) {
        foreach((get_the_terms($post->ID, 'lesson_tags')) as $term) {
          // *** Add category slug to the $classes array
          $classes[] = 'lesson-tag-' . $term->slug;
         }
      }
      $classes[] = $post_type_cos;
      // ***  return the $classes array
      return $classes;
    }
  }
}

Notice that on Line 13 I prepended ‘lesson-tag-‘ to the lesson tag slug, just to make it unique.

Step 4:Customize MemberPress Course template.

Everything I’ve done to this point is well and good.

However, the default MemberPress Courses template won’t work out of the box.

This step requires overriding a default MemberPress Courses template in order for the sidebar lesson navigation to display custom lesson icons based on lesson tags.

(Here is the official documentation for the basic steps for overriding MemberPress template files. And here is an article I published in September which attempts to simplify the instructions while also pointing out a gotcha that I encountered when following the official documentation.)

The template files I needed to override was courses_classroom_section_lessons.php which is located in the /{child_theme}/memberpress/courses/ folder.

Here is what I added right after the foreach loop on line #13 of courses_classroom_section_lessons.php:

$lesson_tags = get_the_terms($lesson->ID, 'lesson_tags');
if (is_array($lesson_tags) || is_object($lesson_tags) ) {
  $tag_classes = array();
  foreach( $lesson_tags as $term ) {
    // *** Add category slug to the $classes array
    $tag_classes[] = 'lesson-tag-' . $term->slug;
  }
  $tag_classes_cos = ' ' . implode(' ', $tag_classes);
} else {
  $tag_classes_cos = '';
}

I prepended the string lesson-tag- to the actual slug for the lesson tag to make CSS targeting easier and to avoid any naming conflicts.

Finally, I added an i tag to the lesson link div so that I could target it with a CSS rule that sets the ::before content to the appropriate Fontawesome icon:

<div class="mpcs-lesson-link">
  <i class="mpcs-doc-text-inv<?php echo $tag_classes_cos;?>"></i>
  <?php echo $lesson->post_title; ?>
</div>

Step 5:Include Fontawesome.

The easiest way to do this is to use the Fontawesome plugin!

Step 6:Create CSS rules.

Here is the pertinent CSS markup. This is from when I had created three lesson tags: intro for introductory lessons, video, for lessons that included videos, and reading, for lessons that were text-only.

.lesson-tag-intro #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-intro::before {
	content: '\f05a';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.lesson-tag-video #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-video::before {
	content: '\f03d';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.lesson-tag-reading #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-reading::before {
	content: '\f518';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.lesson-tag-download #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-download::before {
	content: '\f56d';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}

.lesson-tag-challenge #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-challenge::before {
	content: '\f733';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.lesson-tag-audio #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-audio::before {
	content: '\f028';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.lesson-tag-discussion #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-discussion::before {
	content: '\f086';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.lesson-tag-summary #mpcs-main .mpcs-doc-text-inv::before,
.mpcs-lesson-link i.lesson-tag-summary::before {
	content: '\f31a';
	font-family: 'Fontawesome';
	font-size: var(--icon-size-large);
	color: black;
}
.mpcs-lesson i[class*="lesson-tag"]::before {
	font-size: var(--icon-size-small);
}

I’m using two selectors for each of the first eight rules because I am targeting the lesson name classes in both the main body of the lesson (first selector) and the the sidebar lesson navigation (the second selector). The final rule (using an attribute selector with a contains operator) resets the font size of each icon for the sidebar lesson navigation (I wanted it smaller here). Note also that I’m using custom properties (defined at the top of the file) for the icon sizes:

:root {
	--icon-size-large: 1.5rem;
	--icon-size-small: 0.75rem;
}

And here again is a close-up of the final result, with custom lesson icons:

Closeup of Custom Icons

Step 7:Link CSS in Classroom Template Header.

Finally, you have to link the main stylesheet into the courses pages, which use a different header than is used by the rest of the website.

Overwrite the header file for MemberPress classroom by copying courses_header.php from wp-content/plugins/memberpress-courses/app/views/classroom/ to wp-content/themes/{child-folder}/memberpress/classroom/ and add the code on line 4 below within the head element:

<head>
  <meta charset="<?php bloginfo( 'charset' ); ?>">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel='stylesheet' id='generate-child-css' href='https://nyobc.com/wp-content/themes/gp-child/style.css' media='all' />
  <link rel="profile" href="https://gmpg.org/xfn/11">
  <?php wp_head(); ?>
  <?php global $post; ?>
</head>

In Closing

If you found this article, please let me know by commenting below and/or by sharing it on your own blog or on social media. If you have questions or other ideas for how to solve the problem, I’d like to hear about those also.

Like what you see? Share with others and join my mailing list. No long-term commitment, unsubscribe any time.

Related Posts

  1. How to Override MemberPress Template Files
  2. MemberPress: How to Create a Custom MemberPress Course Progress Page
  3. New Membership Site To Help People Follow Through On Their Intentions
  4. Automatic “Visit Web Site” Links on WordPress Portfolio Posts
  5. MemberPress: Create a Custom Shortcode to Display a MemberPress Membership Price ANYWHERE on Your Website

Reader Interactions

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

Primary Sidebar

mailchimp signup

Subscribe to get notified when new articles are published. Unsubscribe any time. No spam. I promise. Check out my newsletter archives.

social

Twitter Facebook LinkedIn

Recent Articles

  • Post-Specific CSS for WordPress October 5, 2026
  • You built an online course, but they haven’t come. September 16, 2026
  • Custom MemberPress Pricing Pages December 19, 2025
  • CSS Data Attribute Override December 11, 2025
  • MemberPress Rules Using Custom Taxonomies and Custom Roles December 10, 2025

Filter By Category/Tag

Categories

  • Case Studies (8)
  • For Staff (1)
  • General (73)
  • Portfolio (7)
  • Reviews (14)
  • Snippets (24)
  • Techniques (52)

Popular Tags

Advanced Custom Fields Blogging Child Themes Content Marketing CSS Customer Service Custom Fields Custom Post Types Diagnostics Domain Names Facebook FooGallery Genesis Hosting HTML Images iPhone Libra Live Chat Marketing Media MemberPress MemberPress Courses Membership Sites Mobile-Friendly MySQL Photo Gallery php Pinterest Plugins Post Formats Pricing Project Management SEBA SEO Seth Godin Shortcodes Social Networking Surveys Taxonomies Twitter Video Web design Web forms WordPress

Footer

Background

Web Sites | WordPress Support | Web Applications.

Formally trained in liberal arts and education (I have a B.A. in Government from Harvard and studied Secondary Education at Rutgers Graduate School), I have honed my skills in the communication arts and sciences as a teacher, trainer, instructional designer, writer, photographer, calligrapher, helpdesk manager, database programmer, and multimedia developer.

(I've also been a group counselor, waiter, bartender, bicycle messenger boy, computer salesman, carpenter's helper, financial analyst, and school board president.)

Tech

Systems since 1983.
Web sites since 1994.
PHP since 2001.
WordPress since 2007.

Contact

Book Meeting
770-772-5134
Email Jeff
Send Money
All Ways

Copyright 2026, nSiteful Web Builders, Inc.

Cookies Consent
To provide the best experiences, we use technologies like cookies to store and/or access device information. Consenting to these technologies will allow us to process data such as browsing behavior or unique IDs on this site. Not consenting or withdrawing consent, may adversely affect certain features and functions.
Functional Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
  • Manage options
  • Manage services
  • Manage {vendor_count} vendors
  • Read more about these purposes
View preferences
  • {title}
  • {title}
  • {title}
https://iframe.mediadelivery.net/embed/392008/42d18bc1-2adc-4741-b733-053d08d09c32
https://vz-000c5976-3ab.b-cdn.net/42d18bc1-2adc-4741-b733-053d08d09c32/play_720p.mp4

Receive occasional emails from Jeff