Here at Appsembler we get a lot of requests from our customers to customize or add functionality to their shiny new Open edXTM site. The most common request that comes with virtually any new site deployment is theming. That’s completely understandable – you want your student facing site to reflect your company’s branding, so you want it painted in your colors, your logo at the top and your imagery and content on the landing page and various static pages like “About us”, “Contact”, “Terms of service” etc. Open edX allows site theming out of the box, however it’s not something that you’d call user friendly or straight forward.
Standard Open edX theming approach
When we first started developing Open edX themes for our customers, we were using a pretty standard approach. Specifically, we were using the Stanford theming template. The way Open edX theming generally works is pretty straight forward from a broad perspective: the LMS frontend is based on Mako (and somewhat Django) templates and SASS. A theme templates folder actually reflects the platform’s templates folder organization and filenames, so if we instruct Open edX to use a custom theme called, for example, “Appsembler” it will look into its folder (themes/Appsembler/templates) and see if we have decided to override any of the Mako templates.
For example, if we want to create a custom template for the index page (let’s say we want to customize it completely), we’ll create the new template, name it “index.html” and place it in the templates folder, just as it’s done in the platform’s own templates folder. Now add some custom SASS to override some CSS rules used in the stock theme, change a few variables, add a few new rules for new elements of our index page, recompile and there you go! A brand new index page – it’s that simple! Or is it?
Trust us, when you start theming Open edX you’re going to say the above (or its more colorful variations) quite a few times.
First of all, the CSS rules that you write in themes SASS won’t necessarily work as planned. Open edX has a very complex frontend system and a lot of rules are applied to certain elements (buttons, containers, headings) very specifically, so you’ll realize that just styling a general button element on a page really won’t work all that well.
Now, take into account that this can make the styling process look more like a trial-and-error, then note that by default you need to re-run paver in your local Devstack each time you want to see the code change you made, and you end up with a lot of time wasted waiting for code recompiling.
The second part of the “oh no” situation is modifying the templates. And you’ll want to modify them. If you want to have a completely custom experience on the index (landing) page of your LMS, you’ll need to override the index.html Mako template. And then, of course, style the oh so beautiful thing you’ve produced.
In doing this, you need to be very careful so you don’t leave out any template includes, especially if you still want to have, for instance, the listing of X latest courses that Open edX index page provides by default. This part is pretty straightforward, and once you spend some time messing with templates and experimenting you’ll find that you’re getting around quite well, and that you can produce anything you imagine.
So, when does the big “oh no” occur? Open edX has regular releases of new versions (at the point of writing this article the latest stable version is called “Eucalyptus”), and as the Open edX team refines/upgrades the frontend, methods for fetching certain data can change. So if you made a custom course card to display your courses, the part where you fetch the name of the course can start causing an error after you upgrade your Open edX version. If you did some heavy customizations — and we all want to do them, because we like our stuff pretty and attractive 🙂 — code comparison can become time-consuming and you’ll end up spending quite a lot of time cherry-picking code. Now imagine you’re taking care of 20 customer themes, all customized. And imagine going through this cherry-picking process for each one of them separately every couple of months. Not the most productive way to spend your time, right?
Now, to be fair, with the Eucalyptus release Open edX introduces the new Comprehensive theming, which should tackle a lot of these pain points. Be sure to check it out here! However – it still didn’t solve all of our issues, not to mention we had these issues before comprehensive theming was introduced, so we had to take action on our side.
Now, imagine you want to make your Open edX LMS fully responsive (or at least mostly responsive) – this means rewriting a lot of templates and adding a large amount of custom styling. The method described above just doesn’t seem right to do that. We evaluated all of this and decided to take the harder approach and spend a substantial amount of time to create a new foundation for Appsembler theming.
The Appsembler approach to theming
The first step to creating our own codebase from which we’ll create our customer themes was to define some requirements that it needs to fulfill in order for the time spent into making it to make sense. We came up with the following:
- the resulting theme needs to be responsive
- templates need to be flexible so specific content and design requirements can be relatively easy fulfilled
- SASS needs to be flexible and brand color scheme should be relatively easy to apply
- logo assets need to be easily applied
- the codebase should provide a solution to the already mentioned platform upgrade issue
- the codebase needs to be built with a future SaaS system we’re building in mind, in a way it needs to lay the foundation for the system
Our templating solution
In order to give our codebase flexibility content-wise, while making the platform upgrades a much less painful process, we have devised a system that allows all of our themes to share the same base templates (ones containing Open edX data fetching from backend, etc.), then added an additional layer of design templates on top of them that can be included when and where needed. The design templates are actually building blocks which form a single page.
So for instance, if we want to have our LMS landing page to have a big hero section with an image background, then two text blocks with call-to-action buttons, then a section where the four latest courses are listed, then finally a section that features a testimonial, we define it in the single file where we define all the other pages. We list the building blocks (and their order) that the base template needs to import, and we also provide it with settings for these blocks (for example the text alignment, padding and background image URL). If a certain building block needs some Open edX specific data (like the block which lists a number of latest courses added to the site), that data gets passed to it directly from the base template.
In addition to specifying the content for all the pages, our main file also allows us to set the header and footer menu items, logo assets and their respective paths, footer copyright text, and many more options that come quite handy when building a client theme. Since it’s uniformly organized for all the pages and located in one file, basic theming can be done fairly quickly and provides us with a fast learning curve for beginners at theming. Of course, it doesn’t only allow us to use building blocks that are common to all customer themes, we can also create customer-specific building blocks that we import through that same file.
This solution makes debugging of themes during the Open edX version upgrade preparations much faster – all the things that could be changed and could now fail in the new version are contained in files that are common to all customer themes. What this means is that by preparing and testing only one theme (even our plain codebase theme) on the new Open edX version, we make sure all of them work. Once the one theme is modified and tested on the new platform version, we just update the codebase on all themes – there’s no need to debug each one separately. Another useful side-effect is that we can roll out theme improvements and bug fixes faster – if we note a bug or decide to improve on one theme, all of them can receive it fairly quickly.
Harnessing the power of SASS
All of the basic theme customization can be done through only one customer-specific SASS file, which contains all of the most important variables that control the overall look and feel of the site, plus some variables that can change certain elements visual styles (we picked some that our customers asked to change most often). A lot of these are passed to functions and mixins that consequently affect a lot of elements of the theme.
For example, the primary brand color doesn’t only get propagated to certain elements of the theme, its darker and lighter shades also get calculated automatically and passed to buttons, hover effects etc. Setting the navbar-style from “white” to “brand” doesn’t only change the background color of the navbar, it also recalculates the color values for the navbar buttons, menu icon, menu items, displays the negative version of the logo…
By forcing the use of variables, mixins and functions, we enabled ourselves to achieve the same organization of codebase and customer-specific files as with templates – making our SASS codebase prone to quick upgrades and bug fixes in the same fashion as with templates.
Oh, and as for the lengthy recompile – change style – recompile issue, we solved it by compiling our theme SASS separately from the LMS SASS, then including the resulting separate CSS file directly in the theme-head. One of the reasons was definitely faster development, because this allows us to use our SASS compiler of preference (I personally use Codekit). Combined with disabling of caching in local Devstack, this allowed for fast local theme development. Also, with all our styles prefixed, we don’t get any collisions with the default Open edX LMS styling.
This is just a glimpse into how Appsembler handles Open edX theming – we hope you found it to be an interesting read, and we’ll also gladly answer any questions or comments if you have them 🙂 This theming model/codebase is only a part of something much bigger and more complex that we’re cooking here in Appsembler – our new SaaS offering – Appsembler Management Console (AMC for short)! Once complete, it will feature a signup process with a step-by-step wizard for setting up your site (including your brand logo and colors!) and a powerful dashboard that you can use to manage you site’s visual appearance, menus, typography and even a visual page content editor. Be sure to stick around to learn more about that in or even participate in the beta in the (very) near future!