One of the great things about Moodle (other than the number of databases it can use!) is the way that courses can be easily created and edited. One of its best features is the edit button that can be found at the top of many pages. Administrators and course managers can push this button and quickly add and remove functionality to redesign a course or a site within seconds.
This blog post is the first in a series of two (but might even extend to three) that aims to answer the question of: how does the Moodle block editing magic work? To answer this question I found that it was useful to split this big question into a number of smaller questions. These are: how are blocks presented to the user?, how are block layouts stored in the Moodle database?, and what happens when the user clicks on the edit button and makes changes to the layout of a site or a course?
There are two reasons for wanting to answer to these questions. The first is that knowing something about this key part of Moodle might help me to understand more about its architecture which might help me in the future if I have to make any changes as a part of the EU4ALL project. The second is pure curiosity, particularly regarding the database tables and structures - I would like to know how they work.
There are two broad approaches that I could take to answer these questions: look at things from the top down, or from the bottom up. I could either look at how the user interfaces are created, or I could have a look at the database to see if I can find data tables that might be used to store data that is used when the Moodle user interface is created. In the end I used a combination of top down and bottom up approaches to understand a bit of what is going on.
This post will present what I have learnt about how Moodle presents blocks. The second post will be about what I have found out about the database and how it works (in relation to Moodle blocks) and what happens when you click on the various block editing icons.
There will be load of detail which will remain unsaid and I’ll be skipping over loads of code subtleties that I haven’t yet fully understood! I’ll also be opinionated, so advance apologies to and Moodle developers who I might inadvertently offend. I hope my opinions are received with positive spirit, which is the way that they are intended.
Blocks are bits of functionality which sit on either side of a Moodle site or course. They can do loads of stuff: provide information to students about their assignment dates, and provide access to discussion forums. When first looking at Moodleworld, I had to pause a moment to distinguish between blocks, resources and activities. Blocks, it might be argued, are pieces of functionality that can support your learning, whilst activities and resources may be a central part of your learning (but don’t quote me on that!)
Not long after starting looking at the blocks code, I discovered a developer page on the subject. This was useful. I soon found out that apparently there are plans to improve the block system for the next version of Moodle. The developers have created an interestingly phrased bug to help guide the development of the next release. This said, all the investigations reported here relate to version 1.9+, so things may very well have moved on.
Looking at Index
Blocks can be used in at least two different ways: on the main Moodle site area (which is seen when you enter a URL which corresponds to a Moodle installation) and within individual courses. I immediately suspect that there is some code that is common between both of them. To make things easy for myself, I’ve decided (after a number of experiments) to look at how blocks are created for a Moodle site.
To start to figure out how things work the first place that I look at is the index.php file. (I must confess that I actually started to try to figure out what happened when you click on the editing button, but this proved to be too tough, so I backtracked…)
So, what does the index.php file do? I soon discover a variable called $PAGE and asked the innocuous question of ‘why are some Moodle variables in UPPERCASE and others in lowercase?’ I discover an answer in the Moodle coding guidelines. Anything that is in uppercase appears to be global variables. I try to find a page that describes the purpose of the different global variables, but I fail, instead uncovering a reference to session variables, leaving me wondering what the $PAGE class is all about.
Pressing on I see that there are some functions that seem to calculate the width of the left and the right hand areas where the blocks are displayed. There is also some code that seems to generate some standard HTML for a header (showing the Moodle instance title and login info).
The index page then changes from PHP to HTML and I’m presented with a table. This surprises me a little. Tables shouldn’t really be used for formatting and instead should only be used to present data. It seems that the table is used to format the different portions of the screen, dividing it unto the left hand bunch of columns, a centre part where stuff is displayed, and a right hand column.
It appears that the code that co-ordinates the printing of the left and right blocks is very similar, with the only difference being different parameters to indicate whether things appear on the left, and things appear on the right.
The index file itself doesn’t seem to display very much, so obviously the code that creates the HTML for the different blocks is to be found in other parts of the Moodle programming.
Seeding program behaviour
To begin to explore how different blocks are created I decide to create some test data. I add a single block to the front page of Moodle and position it at the top on the right hand side:
Knowing that I have one block that will be displayed, I can the trace through the code when the ‘create right hand side’ code is executed using my NuSphere debugger to see what is called and when.
One thing that I’m rather surprised about is how much I use the different views that my debugger offers. It really helps me to begin learn about the structure of the codebase and the interdependencies between the different files and functions.
Trying to understand the classes
It soon becomes apparent that the developers are making use of some object-oriented programming features. In my opinion I think this is exactly the right thing to do. I hold the view that if you define the problem in the right way then its solution (in terms of writing the code that connects the different definitions together) can be easy, providing that you write things well (this said, I do come from a culture of Java and C# and brought up, initially, on a diet of Pascal).
After some probing around there seem to be two libraries that seem to be immediately important to know about: weblib and blocklib. The comments at the top of weblib describes it as ‘library of all general-purpose Moodle PHP functions and constants that produce HTML output’. Blocklib is described as, ‘all the necessary stuff to use blocks in course pages’.
In index, there is a call to a function called blocks_setup (blocks, I discover, can be pinned true, pinned both, or pinned false – block pinning is associated to lessons, something that I haven’t studied). This function appears to call another function named blocks_get_by_page (passing it the $PAGE global). This function returns a data structure that contains two arrays. One array is called l and the other is called r. I’m assuming here that array data has been pulled from the database.
The next function that follows is called blocks_have_content. This function does quite a bit. It takes the earlier data structure, and translates the block number (which corresponds to which block is to be displayed on the page) and converts it into a block name through a database call. The code then uses this name to instantiate an object whose class is similar to the block name (it does this by prepending ‘block_’ to the start).
There is something to be cautious about here: there is a dependency between the contents of the database (which are added to when the Moodle database is installed) and the name of the class. If either one of these were to change the blocks would not display properly.
The class that corresponds to the news block is named ‘block_news_items’. This class is derived from (or inherits) another class called block_base that is defined within the file moodleblock.class.php. A similar pattern is followed with other blocks.
Following the program flow, there is a call to a function called is_empty() within blocklib.php. This code strikes me as confusing since is_empty should only be doing one thing. Is_empty appears to have a ‘side effect’ of storing the HTML for a block that comes from a call to get_content to a variable called ‘content’. Functions should only do what they say they do. Anything else risks increasing the burden of program comprehension and maintenance.
The Moodle codebase contains several versions of get_content, one for each of the different blocks that can be displayed. The version that is called depends on which object Moodle is currently working through. Since there is only one block, the get_content function within block_news_items is called. It then returns some HTML that describes how the block will be presented.
This HTML will be stored to the structure which originally described which block goes where. If you look through the pageblocks variable, the HTML can be found by going to either the left or right array, looking in the ‘obj’ field, then going to ‘content’. In ‘content’ you will find a further field called ‘text’ that contains the HTML that is to be displayed.
When all the HTML has been safely stored away in memory it is almost ready to be printed (or presented to a web client).
Calls to print_container_start() and print_container_end() delineate a call to blocks_print_group. In this function there will then be a database call to check to see if the block is visible and then a call to _print_block() is made. This is a member function of a class, as indicated by the proceeding underscore. The _print_block() can be found within the moodleblock.class file. This function (if you are still following either me or the code!) makes a call to print_side_block function (which is one of those general purpose PHP functions) contained within weblib.php.
Summary and towards part 2
I guess my main summary is that to create something that is simple and easy to use can require quite a lot of complicated code.
My original objective was to try to understand the mechanisms underpinning the editing and customising of course (particularly blocks) but I have not really looked at the differences between how blocks presented within the course areas and how blocks are presented on the main site. Learning about how things work has been an interesting exercise. One point that I should add is that from an accessibility perspective, the use of tables for layout purposes should ideally be avoided.
What is great is that there is some object-oriented code beginning to appear within the Moodle codebase. What is confusing (to me, at least) is the way that some data structures can be so readily changed (or added to) by PHP. I hold the opinion that stronger data types can really help developers to understand the code that they are faced with since they constrain the actions that can be carried out to those types. I also hold the view that data stronger typing can really help your development since you give your development tools more of an opportunity to help you (through presenting you with autocomplete or intellisense options), but these opinions probably reflect my earlier programming background and experience.
On the subject of data types, the next post in this series will be about how the Moodle database stores information about the blocks that are seen on the screen. Hopefully this might fill the gaps of this post where the word ‘database’ is mentioned.
Acknowlegement: Picture by zoologist, from Flickr. Licenced under creative commons.