Canvas-ish WordPress Template

Origin Story

The request came in on Monday for a WordPress theme that looked like the Canvas LMS. That’s not a very dramatic origin but it’s what I’ve got. You can check out the current iteration of the theme here or get it on github here.

What does Canvas look like?

I’m really just imitating the pages so I went to check out a demo page. It looks something like this.
Canvas page screenshot. Menu on the far left. Content on the right. Sub-navigation below the content.

In my head, I break it down into rectangles and start thinking of how to get the data into those boxes. The rough sketch below is how I conceptualized it. Most of the content is pretty straight forward as well.
The previous canvas lms screenshot but with an overlay of green rectangles indicating different website areas. Each area is labeled with the content that will go there.

The Work

For this type of quick work I knew that the understrap theme would get me most of the way there. It has a left sidebar template and it’s in bootstrap so no drama there. I didn’t strip this to the bones but that option remains open if we want to make this an even more streamlined theme. The two things I was less sure about were how I wanted to populate the left navigation bar and how I wanted to build out the next/previous buttons at the bottom of the page.

Left Sidebar Menu

I altered the sidebar-left.php file to read like this.

if (is_active_sidebar('left-sidebar' ))	{
	  dynamic_sidebar( 'left-sidebar' ); 
	} else {
	   if ( current_user_can('editor') || current_user_can('administrator') ){
	   	 echo '<div class="alert alert-info" role="alert" aria-atomic="true">Put a Menu in the left sidebar as a widget to further customize.</div>';//alert about using the menu to do fancier stuff
	   }
	  echo '<ul id="default-menu" aria-role"navigation">';
	  $args = array(
        'depth'        => 0,
         'title_li'     => '',
    );
      wp_list_pages($args);
	  echo '</ul>';	
	}

If I haven’t assigned a menu using the widget>left sidebar interaction, it will list all the pages but if I’m logged-in and can edit it will also give me a helpful little notification saying that I could customize that if I wanted to.
A small blue box notifying people they can set the menu through the widget interface for the left sidebar.

Now that we have links populating our sidebar, I considered a couple ways of doing the next buttons. You can tie them to menu order and do custom nav walkers etc. but that seemed like a lot of hassle given we basically had the order we wanted right here in the sidebar. This is one of those times when I copy a chunk of the HTML I need and throw that in codepen to use while I figure out the needed javascript.

To do this I figured I needed to know which page I was on and where that page sat in the order of links in the sidebar already. I’d also need to know when I was at the front or end of that list to hide the required buttons if a previous or next didn’t exist.

I could use the following to get the name of the page.

const currentPage = document.querySelectorAll('h1')[0].innerHTML;//gets first element that is an H1 and returns the inner HTML

I can use something similar to get all the li elements from our sidebar menu.

const navList = document.querySelectorAll('#default-menu li');get the li elements inside the element with the id default-menu

Now we know what page we’re on and we’ve got all the links in what amounts to an array. When the page title is the same as the name in the loop of menu items, we can move backwards or forwards in the array and get that information to set the URLs in our previous/next buttons. If there’s nothing there we’ll just hide the buttons.

function buildNav(navList, currentPage){
//add the index variable below lets me know where in the array the loop is at
  navList.forEach((list, index) => {
    if (list.childNodes[0].innerHTML == currentPage){
      if (index-1 > -1){
       let prevLink = navList[(index-1)].childNodes[0].href;  
         setNavUrl('prev-btn',prevLink)
      } else {
        hideEmptyNav('prev-btn')
      }
       if (index+1 < navList.length){
        let nextLink = navList[(index+1)].childNodes[0].href;
          setNavUrl('next-btn',nextLink)
       } else {
          hideEmptyNav('next-btn')
       }
    }
  })
}

function setNavUrl(id,url){
 const nav = document.getElementById(id);
 nav.href = url; 
}

function hideEmptyNav(id){
  const nav = document.getElementById(id);
  nav.classList.add('hidden')
}

The HTML that holds the navigation is like so.

  <div id="sub-nav-footer">
    <a href="" id="prev-btn" class="sub-nav-btn">Previous</a>
    <a href="" id="next-btn" class="sub-nav-btn">Next</a>
 </div>

You can see the whole codepen here.

See the Pen
sub nav js
by Tom (@twwoodward)
on CodePen.

In the end we get something like this. While not an exact match to Canvas it’s a decent parallel and in a pretty short turn around.
WordPress theme that looks very much like the Canvas LMS interface.