David Tod taught the world to hide confusing plugins from faculty using Instructure Canvas’s API. Read on to find out how to rename plugins at the same time.
Success story: menu default visibility
Back in 2015, in a Canvas support forum post titled “Allow account admins to set default course navigation menu,” Canvas administrator Buddy Hall pointed out that:
“It would be great if we could set a default course navigation menu to hide additional tools unless instructors wanted to use them.
“With the increasing number of additional Canvas and third-party LTI integrations that add items to the course navigation, it can quickly grow to be daunting and intimidating.
“It would be great if we could set these items (Roll Call Attendance, SCORM, Lecture Capture and Publisher LTIs, etc.) to be automatically disabled in the navigation, but instructors could go in and enable them if they want to use them.”
In 2019, fellow administrator David Tod replied with a clever coding hack:
“For what it’s worth, you can change tool defaults via the API.
“Copying and pasting this into a JavaScript console (e.g. in Chrome) would do the trick.
// disable a tool in course navigation var accountid='1'; // replace with your account var toolid='2753'; // replace with the tool ID in the account->settings->apps listing var url='https://YOURURL.instructure.com/api/v1/accounts/' + accountid + '/external_tools/' + toolid; $.ajax({ url: url, type: 'PUT', data: 'course_navigation[default]=disabled', success: function(data) { alert('Tool was disabled by default in course navigation.'); } });
My friend Eric Larson shared with me that Canvas administrators at his school have been using David’s trick with great success.
After logging into Canvas’s web-based configuration interface, an admin at Eric’s school opens the Developer Console in Chrome as follows
(instructions quoted from Balsamiq):
“To open the developer console in Google Chrome, open the Chrome Menu in the upper-right-hand corner of the browser window and select More Tools > Developer Tools.
“You can also use the shortcut Option + ⌘ + J (on macOS), or Shift + CTRL + J (on Windows/Linux).”
Then, in David’s code, the admin replaces 1
with an applicable Canvas “account ID” and replaces 2753
with the ID of the LTI Canvas plugin whose default course navigation menu needs configuration.
An admin pastes the modified code into the Chrome’s “developer console’s” command prompt (indicated by >
) and presses enter to execute it.
Voilà – plugin “#2753” (or whatever the admin changed it to) disappears off the course navigation menus except as re-added by professors!
Unstoppable power: menu naming
Eric thought it’d be nice to change the names of some plugins in course navigation menus as well.
Inspecting Canvas’s (official External Tools API specification), Eric realized that the heart of David’s solution seemed to lie in single quotes after the word data
:
course_navigation[default]=disabled
Working from the official API specification, Eric went out on a limb and tried changing the text between '
marks after data
to read:
course_navigation[text]=New Name For Plugin
The code for Eric’s new variation now read:
// rename a tool in course navigation
var accountid='AN_ACCOUNT_NUMBER'; // replace with your account
var toolid='A_PLUGIN_NUMBER'; // replace with the tool ID in the account->settings->apps listing
var url='https://SCHOOL_URL.instructure.com/api/v1/accounts/' + accountid + '/external_tools/' + toolid;
$.ajax({
url: url,
type: 'PUT',
data: 'course_navigation[text]=New Name For Plugin',
success: function(data) {
alert('Tool was renamed in course navigation.');
}
});
Not perfect yet
There was trouble in paradise.
What if an admin wanted to rename a plugin within course menus and hide it from those course menus by default?
It turns out that simply executing the [default]=disabled
and [text]=New Name For Plugin
variations on David’s code back-to-back as two separate commands didn’t work.
- Setting the default to
disabled
renamed the plugin back to its original name.- Changing the name of the plugin set its default visibility back to
enabled
.
Somehow, Eric’s code needed to pass values for both course_navigation[default]
and course_navigation[text]
in a single command.
Eric knows I love APIs, so he asked if I had any thoughts, and together we figured it out.
New & improved code
If you arrived here from search results and just want to see the answer without knowing why it works, here it is:
// disable and rename a tool in course navigation
var accountid='YOUR_ACCOUNT_NUMBER'; // replace with your account
var toolid='YOUR_PLUGIN_NUMBER'; // replace with the tool ID in the account->settings->apps listing
var url='https://YOUR_URL.instructure.com/api/v1/accounts/' + accountid + '/external_tools/' + toolid;
$.ajax({
url: url,
type: 'PUT',
data: 'course_navigation[default]=disabled&course_navigation[text]=New Name For Plugin',
success: function(data) {
alert('Tool was disabled by default and renamed in course navigation.');
}
});
In other words, between the two single-quotes after data
, we combined the two pieces of text into one, separating them with an ampersand &
.
course_navigation[default]=disabled&course_navigation[text]=New Name For Plugin
How does it work?
For those of you who like to disassemble toasters, let’s talk a little bit about what David’s code actually does.
Canvas’s “API” works by issuing it “HTTP requests” from your computer.
Please take a moment to read about HTTP requests and responses – I promise you’ll be back in a jiffy.
Intro to HTTP (for data folks & managers, especially!)
Katie ・ Jun 3 '19 ・ 10 min read
There are many ways to make your computer issue HTTP requests to a server like Canvas’s.
To be honest, the way that David came up with for issuing an HTTP request to Canvas is pretty sneaky, and a bit fragile. But also cool!
When you execute David’s code while logged into Canvas, it leverages the fact that Canvas’s web site comes with an extended set of JavaScript commands called JQuery installed (that’s what the $
stands for in $.ajax()
).
(I’m pretty sure that David’s code will stop working if Canvas’s web site ever stops using JQuery.)
The JQuery command ajax()
is capable of issuing an HTTP request on behalf of your computer.
What’s really tricky about using the ajax()
command within a web browser currently looking at your Canvas configuration web page is that, from what I can tell, it magically borrows the “authorization token” from your web browser’s logged-into-Canvas state and includes it as a header of the HTTP request.
Such an HTTP header is required by Canvas’s API (so that strangers can’t alter your Canvas environment without your permission).
Canvas’s API can be manipulated with HTTP requests you issue from other software on your computer (like the free point-and-click desktop software Postman, or like the free command-line-interface desktop software cURL) and it will work just as well.
The only catch is that you’ll have to manage logging into Canvas over the API yourself.
If you’re really going deep into learning the Canvas API, I think this is a worthwhile tradeoff for the convenience of being able to work with powerful point-and-click tools like Postman, as seen here:
But back to David’s code. Between the curly braces {}
of the $.ajax()
command, David specifies some properties of the HTTP request he’s trying to make:
- It has a URL of
https://YOURURL.instructure.com/api/v1/accounts/YOUR_ACCOUNT_NUMBER/external_tools/YOUR_PLUGIN_NUMBER
. - It has a method of
PUT
. - It has a body of
course_navigation[default]=disabled
.- Or, in Eric’s case, the body is
course_navigation[default]=disabled&course_navigation[text]=New Name For Plugin
- Note that the reason we put them together with an ampersand is that for a
PUT
-type request,$.ajax()
’s default behavior is to structure body data using a punctuation standard known as “application/x-www-form-urlencoded
,” which, according to Dinesh Balaji, uses ampersands to put separate “key-value pairs” together. - Eric’s body is the equivalent of doing this in an HTTP request composed using Postman software:
- Or, in Eric’s case, the body is
Also between the curly braces, David’s code specifies that if everything goes well, the browser should pop up a dialog box telling you: “Tool was disabled by default in course navigation.”
As I mentioned before, the HTTP request has some hidden headers as well, like the logged-in state that $.ajax()
is taking care of handling for you, but you don’t need to worry about these if you’re just using David’s code in a browser.
Takeaways
Once you familiarize yourself with the concept of HTTP requests and get your moves down with a tool or two for issuing them them (be it Postman, Curl, or the Developer Console of your web browser), you can play with Instructure Canvas settings in ways that might not be possible through point-and-click configuration panels in your web browser.
Canvas API documentation such as the External Tools specification for plugins will suddenly read like a foreign language you’ve learned (at least to the level of the “One Semester of Spanish Love Song“).
You’ll be a wizard like Eric and David in no time.
Have fun!