Skip navigation
All Places > Canvas Developers > Blog > Author: cesbrandt

Canvas Developers

2 Posts authored by: cesbrandt


This is my second blog post to the Canvas Community, but I'm going to stick with my tl;dr format.


The Situation

Who doesn't like their code to be easier to read!? Oh, you use the Rich Content Editor (RCE)? Well, why are you in this blog? I see, you thought this was to add syntax highlighting to the content of an activity. Yeah...about


I know there have been a few idea requests to add a syntax highlighter to the core of Canvas for supplying syntax highlighted code within the content of activities. While I have no doubt I could do this, I'm not going to.


So what's this blog all about? The HTML Editor is SO boring! We load ~95% of our content via the HTML Editor, having written it in third-party applications (i.e., Notepad++), because the HTML Editor in Canvas isn't particularly inspiring, nor is it easy to read.


Reason for Creating

Simply put, I did this to allow our developers to more easily read the code from within Canvas. There really isn't anything more to it.


The Solution

A userscript the "replaces" the HTML Editor with an Ace Editor ( and utilizes JS-Beautify to "beautify" the HTML in the editor. So, without further ado, the Q&A:


Q: What does this userscript do?
A: Simply put, it "replaces" the HTML Editor provided by Canvas with an Ace Editor.


Q: Why did you put "replaces" in quotation marks?
A: Ah, the long answer.


The userscript doesn't actually change any of the Canvas functionality. What it actually does is to hide the HTML Editor and add the Ace Editor to display in its place. When changes are made via the Ace Editor and the user clicks out of it (i.e., to see the Rich Content Editor or save), the HTML Editor is updated with the code from the Ace Editor and Canvas processes it normally.


Q: Will the syntax highlighter always be enabled?
A: It can be. The userscript adds a toggle anchor to the line immediately above the editors where the toggle between editors is. This will allow you to enable/disable the syntax highlighter.


Q: Will it remember if I had it enabled or do I have to enable it every time?
A: It will remember. The userscript uses cookies to remember the state of the toggle. This means you could enable it while working in one assignment and it will already be enabled when you open a discussion in another course.


Q: What about multiple Canvas instances? I want it to be enabled in one, but not another.
A: It will! Rather, it should! I configured the userscript to use the very first part of the domain name it's toggled on to give it a unique name for the instance. I haven't tested it on different Canvas instances, but if I did everything correctly it will create unique toggle cookies for each unique Canvas production instance.


Q: You just said it was for "production" Canvas. Why can't I use it for "Test" or "Beta" instances?
A: You can. Taking the entire previous answer to give context, I said that there would be unique cookies based upon the first part of a domain name. So, if your production URL is with a test URL of, your cookie will be the same between the two: abc123_Canvas_syntaxHighlighter.


Q: Can I integrate this into my global JavaScript?
A: Knock yourself out, but I won't be supporting that.


Q: Can I use this in German? Japanese? Italian?
A: Yes? There are a few settings that can be adjusted at the top of the script (keep an eye out for the "DO NOT EDIT BELOW" line). Included in this area are variables for adjusting to different languages. These will need to be manually adjusted if your Canvas is not in English.


Q: Can I use this with a self-hosted instance?
A: Yes? I won't commit that it'll work, but if you update the userscript @include and @exclude values to match your actual domain, I don't see why it wouldn't. Having said that, I will not support use of this code for self-hosted instances.


Q: Will it work with the #editor_tabs for inserting links, files, and images?
A: No. To be blunt, the functionality of the #editor_tabs has always been a bit "wonky" for me, so I'm not even going to try to make this new editor work with it. You can, of course, toggle the editor on/off or switch back to the Rich Content Editor, make your inserts, then toggle back.


Q: So, it adds this to ALL editors in Canvas?
A: No. For simplicity only the first editor on a page will have the editor applied (so it won't be available to quiz questions). Furthermore, there are some editors (i.e., global announcements) that lack the HTML Editor, which the script is dependent upon.


Having said that, the userscript was designed to be as inclusive as possible. If, however, you do find pages where the editor doesn't work correctly, please let me know so I can either fix it or prevent it from loading there.


Q: Does it support the new RCE?
A: Yes.




How It Works

  1. Load the userscript to your Userscript Manager of choice
  2. Enable the userscript
    1. If you're using the "old" RCE, access the "HTML Editor" of an activity edit page
    2. If you're using the "new" RCE, access the "Switch to raw html editor" of an activity edit page
    1. If you're using the "old" RCE, click the "Enable Syntax Highlighter" anchor right next to the toggle that allowed you to access the HTML Editor
    2. If you're using the "new" RCE, click the toggle that appears next to the "Switch to rich text editor" button






Releated Ideas/Discussion

HTML Formatter

Update 2018-07-25

I know this is late, but I was unable to edit the post to make this update.


On 2018-06-23 this script became OBSOLETE due to Instructure having made their own version a non-optional component of the official UI.


I have recieved a few messages inquiring about using the script for self-hosted instances of Canvas. The script was never tested with self-hosted Canvas, but should still work so long as the new UI is disabled. However, self-hosted Canvas was never supported, thus the status of OBSOLETE will be maintained.


For more information regarding the new UI enforcement, please check out the release notes:


Update 2018-03-05

This script is now DEPRECATED due to Instructure having released their own version as part of the official UI. The script will still work so long as the new UI is disabled.


For more information regarding the new UI, please check out the release notes:


Original Post 2017-07-09


This is my first blog post to the Canvas Community, and my first anywhere in nearly 15 years, so my apologies if it is a little off track with what everyone else expects to see. I looked through several frequent posters whose blogs I have used to try and get a feel for what may be considered acceptable formatting. Basically, I concluded that explaining the overall situation, reason for acting, and finally the "solution" developed would be the safest path to take. So, if you feel you have a sufficient understanding on what this post is about from the title (which I have no idea what it will be at the time of my writing this), then feel free to skip to the bottom.


The Situation

As everyone knows, the Courses list at the account-level is lacking in one major area: it only lists 100 courses? Yeah, that is right, it is limited to displaying only 100 courses, the selection of which I have not actually figured out. At first, I thought it was a list of the published courses, alphabetically by name, then unpublished courses until 100 were listed, but I later found that the published status means nothing and the alphabetical sorting is inconsistent (i.e., I get "WORKING ENG120" before "WORKING CJ125").


Furthermore, there is not even an option to view more courses! No pagination, no Show More link, just nothing! Well, that just will not do, and, as it turns out, Instructure agrees! Community Team submitted the idea back in April 2015 to have an Advanced Admin Search & Sort developed, and it was announced in November of that year that the idea was in development. Of course, this idea is for Courses AND Users, but that still includes Courses.


Well, here we are 20 months later with no idea when this might be found (I understand it is a major undertaking, I am not complaining).


Reason for Creating

So, like many others, our development team wanted a more robust Courses list. To be specific, we wanted to be able to see a full list of courses being developed. Of course, we track that outside of Canvas, but it often has its benefits to see what has made it into Canvas at a glance. We also wanted to be able to search using "match all terms", not "match exact string".


My first choice was to see if another developer had already created such a script. Well, in the idea posted by Community Team, Dave Schober posted about the search system developed by PennState, which looks like a great system, but as Andy Fisher mentioned, their setup relies on internal systems, making it difficult to share.


Well, the more I searched around, the less I found (I lost some of what I originally found, yeah, that happened). Finally, I just accepted that if we did not want to wait for Instructure to finish development I would have to write it, myself.


The Solution

I call it a solution, but it is really a userscript, and anyone that uses userscripts on a regular basis should be able to say that they are not solutions, just workarounds.


Q: What does this userscript do?
A: Simply put, it replaces the Courses list provided by Canvas with a full list of courses that fall under a subaccount with support for pagination (10, 25, 50, 100, and All per page). It still supports filtering by Term, sorting by Name, sorting by Creation Date (via the course_id), and filtering by Name. However, the filtering by Name has been modified to allow for search terms, not a search string; sorting by Course Code has been added, and Hide enrollmentless courses has been removed.


Q: What do you mean by "filtering by Name has been modified to allow for search terms"?
A: To explain simply, the Canvas-provided filter for Find a Course searched for a fixed string. This meant that if you wanted to find "201701 Miami Sandbox ENG480", you had to supply a fragment of that title that matched exactly (i.e., "201701 Miami", "Miami Sandbox", "Sandbox ENG480". etc.). This modification allows you to search for terms, not a title. So, if you knew the shell you wanted was "201701" and "ENG480", you can submit "201701 ENG480" or "ENG480 201701" and it will come up with the course.


The modified Course Name filter searches for all terms supplied, so only courses whose Name contains all the terms will be provided.


Q: Why is Hide enrollmentless courses removed?
A: Simply put, we do not have need of it. However, that is really only the reason why it was not pursued. The Canvas API options for determining enrollmentless courses is limited to a GET variable defined when making the API call. Due to this information not being available as part of the returned data, additional logic would be needed to provide all courses while supporting the identification of enrollmentless courses.


Q: Did you really just make an entire sentence and hyperlink?
A: Yes. Yes I did.


Q: Do you think Hide enrollmentless courses will be added to this userscript at some point?
A: Maybe. It is not like adding the logic for it would be particularly difficult, it just does not serve sufficient purpose to us to be considered worth adding that extra logic.


Q: Is there anything else that was removed? Is so, why were they removed?
A: Yes. Yes this is.

  • Student Count: This information is not provided using the /api/v1/accounts/:account_id/courses API call.
  • Enrolled Teachers: This information is not provided using the /api/v1/accounts/:account_id/courses API call.

Yes, this information could easily be retrieved with additional calls, but that would significantly increase the number of API calls which then slows done the processing time required to generate the course list.


Q: You mentioned the speed at which the course list is generated would be slowed down by making the additional API calls needed to display more information. What are we talking about? 5-seconds? 10-seconds?
A: Minutes to hours; entirely dependent upon the connection, number of courses, and how many additional calls are required to pull all the desired information. I, honestly, have not looked into this beyond seeing that it is not provided right away.


Q: Okay, that makes sense. So how long will this userscript take to run?
A: That depends on your connection to the server, the load on the server, and how many courses fall under the subaccount. A couple hundred can be retrieved in a matter of seconds, but thousands can take minutes.


Q: Why is it so slow?
A: It is slow because the Canvas API forces a pagination limitation of 100 results per call. So, if there are 4783 courses under a subaccount, 48 API calls are needed to retrieve the information for all of them. It may not seem like much, but it adds up, fast.




How It Works

  1. Load the userscript to your Userscript Manger of choice
  2. Enabled the userscript
  3. Access the "Courses List" of any subaccount in the Canvas LMS
  4. Use the filters to narrow your results
    • Course Name: Accepts multiple terms and compares them against the Course Name of all shells for matches of all terms (case-insensitive) for a complete match. (i.e., If you search for "WORKING 201701", it'll return "201701 Miami Working ENG480" because it contains "WORKING" AND "201701", but it won't return "201701 Miami Sandbox ENG480" because it is missing the "WORKING" term.)
    • Teacher(s): Accepts multiple terms and compares them against all Teacher(s) of each shell (case-insensitive) for a complete match. (i.e., If you search for "Smith Jones", it'll return courses with: "Aaron Smith" and "Jones McMillion"; "James Smithemson" and "Eric Jones"; "Smith Jones"; "Jones Smith")
    • Term Filter: This is literally a clone() of the default Canvas term filter, but it now serves this system (which doesn't have to reload the page when changing filters).
    • Sort By: Mostly a clone of the Canvas sorter, but with the ability to sort by the "Course Code", in addition to the original "Course Name" and "Creation Date" options.
    • Display x Shells: How many courses do you want to see per page? The default is 50, but additional options are 10, 25, 100, and All (All is not recommended for large subaccounts!).






Related Ideas/Discussions

Pagination for Courses List (Admin)

Advanced Admin Search & Sort