Customizing the LearnDash User Profile Course List

LearnDash provides the ability to template your LMS posts and shortcodes.

In this post, I’ll only cover how to add a thumbnail image to your LearnDash [ld_profile] Course List, but you can also extrapolate this idea and use it in your Lesson and Topics lists using the same concepts documented here.

There are 2 methods you can use to modify the Course List in the [ld_profile] shortcode.

  1. Using the LearnDash templating system in a child-theme.
  2. Using a code-snippets plugin.

In this tutorial we’ll first cover this process using method 1 alone.

Method 1, is the most native method to LearnDash and does not involve other plugins be installed.

First, let’s briefly describe what a child-theme is and why you might want to use a child-theme over a code snippet.

Simply put, a child-theme is a WordPress theme. It is a bit different in that it extents the features, vunctionality, and styling of your primary theme. This lets you customize these aspects of your site in many ways while leaving your primary theme to be updated without issue or concern that your changes will be erased in that update.

As an Example: I have a LearnDash Astra child-theme I give away in my store. This theme adds LearnDash customizations that do not display upcoming Lessons in the Lessons Lists and sidebar course outline menus until the DRIPped lesson is available. You can see the free product here (opens in a new tab).

In the case above, the Astra child-theme is adding functionality to the LearnDash plugin and processes by adding a new metabox with a DRIP Override checkbox added into each Course post. When checked, the Lessons in each post will not be shown until that lesson reaches it’s release date/time. The child-theme customizes LearnDash. If I had multiple other customizations other plugins, i could easily add other code to customize those plugins.

In my first example, you will be using a child-theme. Modifying the [ld_profile] shortcode in your child-theme requires no other plugins to achieve the same result as using a code-snippets plugin. Adding in Advanced Custom Fields will let you use an alternate image for the course list thumbnails. ACF will not add anymore value to your process beyond using a different image that your existing course thumbnail image.

Let’s get into it…

The first thing you want to do is create a folder in your child-theme. Let’s use safe practice for this and make use of your FTP client software to connect to your server and traverse to your web site root folder (typically named ” public_html “. From there, your child-theme folder will reside under your wp-content/themes sub-folder. The name of your child-theme folder could be anything, so you’ll need to find out what that folder is named before starting this process.

Once you’ve located your child-theme folder name, traverse into it and create a new folder in the root of your child-theme.

This folder must be named ” learndash “.

Next, using your FTP client software, traverse to the wp-content/plugins/sfwd-lms/themes folder. Once you enter that folder, you’ll see many files that run when you use LearnDash in your site.

Now you’re in a place where you need to select the correct files based on the LearnDash mode you are using in your site.

We’re interested in modifying the LearnDash Profile shortcode and we’ll be customizing the ” LearnDash 3.0 ” Profile. Let’s keep focused on this…

Now that your are in the LearnDash LMS plugin ” themes ” folder, you’ll see the ” ld30 ” and ” legacy ” folders, enter the ” ld30 ” folder to see all the files and folders related to the LearnDash 3.0 and Focus Mode templates.

Now that you’ve entered ld30 folder, travers into the ” templates/shortcodes/profile ” folder.

The only file we’re interested in, is the course-row.php file. Download this file to your computer into a location you know you’ll find it easily later and maybe pick a location that would be backed-up to a cloud service while you at it.

It’s been a long road to get to this point. Pat yourself on te back if you haven’t gotten lost or fallen asleep in this process!

Method 1: Time to make something happen!

Using a code editor (like the free SubLime Text program) edit the course-row.php file.

On line number 45 of this file (line number may vary with different LearnDash plugin versions), you’ll see the following line of code:

<div class="<?php echo esc_attr( $course_class ); ?>" id="<?php echo esc_attr( 'ld-course-list-item-' . $course_id ); ?>">

That is the code that generates the styling classes for the course list in the LD Profile shortcode.

I like to edit the next line to add my own CSS styling class to it. This makes it easier for me to target my own classes rather than have to keep using the !important override with LearnDash CSS classes.

Original LearnDash version:
<div class="ld-item-list-item-preview">

My version:
<div class="ld-item-list-item-preview ld-profile-course-list">

The ” ld-profile-course-list ” is the CSS class I’ve added to this HTML DIV tag.

The magic occurs here…

Now we can insert a new line into the file. This is the line that will get the thumbnail version of each of the Courses Featured Images.

<span class="ld-course-thumbnail"><?php echo get_the_post_thumbnail( $course_id ); ?></span>

All that for a single line of code. Whew!

That single line of code, however, will really add some “pizzazz” to your course list once you style it.

Save that file and note where you’ve saved it.

Giving it a nice look and feel…

Here is some CSS that will style you new images. You can always put the CSS into your child-theme style.css file, but let’s be real, LearnDash is a big pain when it comes to CSS overrides, so my solution below will just get it done with no hassles. The added advantage is that CSS wil only load for the LD Profile.

In your course-row.php file, insert a new line on line 2 of the file.

Copy/paste the code below into that new line and save your file.

<style type="text/css">
/* Remove padding around course List content */
.ld-item-list-item-preview.ld-profile-course-list {
    padding: 0px !important;

/* Thumbnail */
span.ld-course-thumbnail {
    min-width: 200px;
    max-width: 200px;
    margin: -1px 20px -1px -1px; /* -2px has image cover List Item border */

/* Round the left corners of the thumbnail to match List Item rounded corners */
img.attachment-post-thumbnail.size-post-thumbnail.wp-post-image {
    border-bottom-left-radius: 6px;
    border-top-left-radius: 6px;

Installing your new work of art!

Returning to your FTP client, it’s time to upload this file into your website’s child-theme.

On your server, assuming you are in the root folder of your child-theme, if you haven’t already done it, create a new folder named ” learndash “.

Once created, enter that folder and create a new folder named ” ld30 “.

Enter that folder and create a new folder named ” shortcodes “.

Next, enter that folder and create a new folder named ” profile “.

Upload your course-row.php file into this folder on your server.

Visit your web site in your browser and view the page you have your [ld_profile] shortcode in so you can “marvel at your masterpiece“.

You may want to adjust your styles at the top of the file, but you only need to work in the one file, and adjust the styling as you need.

If this did not work for you, visit your dashboard > LearnDash LMS > Support tab and scroll down to the Templates section. you should see the first item listed is this new course-rows.php template file. It will be shown in red, meaning it is the active overridden template.

# Using a Code Snippets plugin to apply all this

I’ll start this by making mention…

If you apply this in a Code Snippets plugin, you really should ensure that plugin can selectively load this snippet on a specific post or page.

Yes, I could have wrapped this code inside an is_page() function, but that’s not going to stop these code snippets from loading everywhere in your site. Where to load a code snippet in your site is the responsibility of the Code Snippets plugin your select. Wrapping it will stop the loading of this code inside the is_page() function, but the snippet will still load everywhere.

Make sure your Code Snippet plugin can be set to load only in a specific page or that you can disable plugins on a page-by-page basis – yes, yet another plugin to load.

That is my child-theme argument for those who believe use a code snippets plugin is the best way to go. Using Method 1 only replaces the LD Profile that LearnDash uses natively and that code is only loaded on on that page or post.

Method 2: Let’s get started…

Applying this using a Code Snippet plugin requires 2 snippets.

One Snippet that needs to run using WordPresses ajax.php process and needs to “Only run in the administration area”

This snippet is required process the post thumbnails.

function lt_custom_course_thumbnail() {
    $courseThumb = get_the_post_thumbnail( $course_id );
	echo get_the_post_thumbnail_url(  $_POST['course_id'] );
add_action("wp_ajax_lt_course_thumbnail", "lt_custom_course_thumbnail");
add_action("wp_ajax_nopriv_lt_course_thumbnail", "lt_custom_course_thumbnail");

Next, you need to create a new snippet to present these thumbnails and create the HTML structure to insert them into.

In the snippet below, we’re inserting a couple of things, as follows:

  • We’ll be adding a ” ld-profile-course-list ” custom class to the DIV that contains the ” ld-item-list-item ld-item-list-item-course ld-expandable learndash-incomplete” CSS classes. We’re doing this to ensure any custom CSS we use is not going to apply to other LearnDash lists.
  • We’re going to be modifying the HTML structure to add a container for the thumbnail and the custom CSS class we’re having it use is ” ld-course-thumbnail “.
  • In our code below: We are breaking out of PHP in the snippet and loading these custom styles. You can remove these styles from this snippet and load them form wherever you usually load your custom CSS.
  • We’re then switching to JavaScript and using jQuery to modify the HTML structure of the course list.
  • jQuery lets us add the custom classes to the HTML elements and we’re then using AJAX to load the the thumbnails we collected using the admin area code snippet into a new SPAN HTML element that will contain them on the left side of each course list item.
  • The width and the height of the thumbnails are hard-coded to be 200 pixels wide and 100 pixels high in this snippet. Change the dimensions on line number 45, but then you’ll also need to adjust the ” List item” and the ” Course name and expand button ” styles to accommodate this change.
  • Once we’re back in PHP mode, we’ll fun a function to add the ” ld-profile-course-list ” class to the course list.

To use the code below, you’ll need to create a Code Snippet and set it to ” Only run on site front-end “.

Again, you want to actually selectively only load this on the specific page that contains your [ld_profile] shortcode or ” LearnDash Profile ” block.

function changeLDProfile(){

	<style type="text/css">
	/* List item */
	.ld-profile-course-list {
		height: 113px;
	/* Course name and expand button */
	.ld-profile-course-list .ld-item-list-item-preview {
	    margin-top: -90px;
	.ld-profile-course-list a.ld-item-name, .ld-profile-course-list .ld-item-details {
		margin-left: 22%;
	/* Thumbnail */
	span.ld-course-thumbnail img {
		margin: -2px 20px -2px -2px;
		border-bottom-left-radius: 6px;
		border-top-left-radius: 6px;
	.ld-course-thumbnail img {
	    height: -webkit-fill-available;
	/* Sub-panels */
	.learndash-wrapper .ld-profile-course-list .ld-item-list-item-expanded {
		background-color: #ffffff;
		z-index: 9999;

	<script type="text/javascript">
        jQuery( document ).ready(function() {
			jQuery.each( jQuery(".ld-profile-course-list") , function( index, value ) {
                var course_id = jQuery(this).attr("id").substring(20);
                var ele = jQuery(this);
                    type: "POST",
                    url: ldVars.ajaxurl,
                    data: {action : "lt_course_thumbnail", course_id : course_id },
                    cache: false,
                    success: function (response) {
                        ele.prepend('<span class="ld-course-thumbnail"><img src="' + response +'" width="200px" height="100px" /></span>');
	function addClassToCourseList() {

add_action( 'wp_head', 'changeLDProfile' );

function add_class_learndash_course_row_class($course_class, $course, $user_id){
    $course_class = $course_class . " ld-profile-course-list ";
    return $course_class;


Why did we use jQuery?

jQuery is used to modify the HTML DOM

Why did we use AJAX?

AJAX is used to get the thumbnails

Why did we need to run the admin code snippet?

You need that to code snippet because jQuery can load information like thumbnails, but it’s a client side script, so it cannot access the thumbnails. That’s done using PHP and making the URL’s available in a variable for jQuery to access using the ” jQuery.ajax ” function.