Note:

If you want to create a new page for developers, you should create it on the Moodle Developer Resource site.

User:Sam Hemelryk/Creating renderable components: Difference between revisions

From MoodleDocs
Line 152: Line 152:
Once you've decided what type of component it is going to be you are ready to start designing what other components (if any) will make it up.
Once you've decided what type of component it is going to be you are ready to start designing what other components (if any) will make it up.


====Its an atom===
====Its an atom====
Whoa, its an atom?! Well this is easy for you then, it won't be constructed of anything else, it is a simple building block, there is nothing unique about it as far as the code is concerned. You can move onto the next step.
Whoa, its an atom?! Well this is easy for you then, it won't be constructed of anything else, it is a simple building block, there is nothing unique about it as far as the code is concerned. You can move onto the next step.


====Its a molecule====
====Its a molecule====
====Its an organism====


===Step 3: Create the component class===
===Step 3: Create the component class===

Revision as of 01:03, 19 June 2014

A guide to writing output components and the render methods for them.

Terminology

Don't worry if you don't understand these yet, this document is going to explain them. However for the sake of providing a quick understanding of some of the terminology used in output here it is:

  • Atom A simple building block, think of it like a HTML tag as that is what it is in many cases.
  • Molecule A collection of atoms combined together to serve a single purpose or offer a single interaction.
  • Organism A collection of molecules and atoms combined together to form a part of the user interface, serving one or more related purposes.
  • Element An element is an meta concept for the above, a base from which all atoms, molecules, and organisms begin.
  • Component Used to refer to any or all of the above. A component is a general term for renderable something relating to this output approach.
  • Renderable Used to mark the object as something that can be converted into output.

Understanding output in Moodle

In 2.8 the direction of output in Moodle was changed, or more accurately re-organised.
Most Moodle sites out there use a third party theme, or have a had a theme created for them. We can assume that themes are the most widely created plugin within Moodle. They deal with the design of the site, and design by nature is a moving, shifting, trending, fluid.
How Moodle produces its look need to be flexible enough to cater to current trends, requirements such as usability and accessibility, be able to keep up with trends, and cater to personal tastes.
We've long had renderers now that allow us to cater to this flexibility, however as Moodle has grown so has its interfaces. There are more interfaces, more controls, more possible interactions.
The move in 2.8 was to bring organisation to what was being done, to bring consistency to the party and the make this flexible a manageable possibility by having an organised set of components to style rather than an endless array of interfaces and unique parts.

The goals for the output project were:

  • Add an element library to Moodle (A page in Moodle listing all of the renderables and how they look in the current theme).
  • Add a complete set of core renderables that should be capable of completely rendering every new user interface.
  • Update the Output API documentation.
  • Create a output guide documentation including best practices.

All of this leans towards making Moodle framework agnostic, so that any frontend framework can be applied to Moodle with as little work as possible.

After reflection and research the decision to use a style of Atomic Design was made. Atomic Design is as you will come to understand later a compartmentalisation approach to interface design that facilitates simplicity and re-use.

Atomic Design, Renderables and Moodle

Renderables have been around for a long time now, they were one of the initial preferred means of creating a reusable output components.
As of Moodle 2.8 there is a new kid on the block, Elements.
Elements within Moodle is based upon the Atomic Design principles outlined by Brad Frost in his Atomic Design blog post and can be one of three distinct types in Moodle, they are either Atoms, Molecules, or Organisms.
These elements are within Moodle actually renderables by inheritance, all elements (atoms, molecules, and organisms) must have an associated render method to produce HTML, but more on that later.

Lets look at the three types of elements within Moodle.

Atoms

Atoms are the smallest part of the puzzle. Easily understood as HTML elements, an image, a table, list etc.
Individually they offer very little, but are essential as they are what all larger things are built out of.

Simply - Atoms don't serve any explicit purpose nor do they provide any interaction, they are just building blocks.

Molecules

Molecules are the combination of atoms into structures that begin to form part of the picture.
Atoms by themselves aren't useful, but by sticking a few of them together we create a molecule.
Think of molecules as simple objects that the user can interact with for a single purpose, a login prompt (title + two inputs + a button), a search form (title + input + button), or a menu (several links).

Simply - Molecules provide a single interaction or purpose. They are constructed of Atoms only.

Organisms

Organisms make things interesting, the are more complex than molecules but not so clearly differentiated.
An organism is a construct of molecules that when combined together form a distinct part of an interface.
They tend to both interesting, and obviously more than a molecule.
The following are examples of molecules:

  • A navigation bar containing a title, some navigation, and a user picture.
  • A user content block (like a forum post) containing a user picture, a title, some content, and a date.
  • A Moodle block containing a header, some actions, content, and a footer.

Simple - Organisms can group several purposes or interactions into one related structure. They are constructed of Molecules.

What about templates and pages?

Atomic Design defines two additional compartmentalisations, templates and pages.

  • Templates it states are the grouping of predominantly organisms into a structure, think of it like a layout. It is organisation without content.
  • Pages are specific instances of the above templates, loaded with content as the user would see them.

In regards to Moodle neither of these two ideas is explicitly dealt with, both ideas however are already partly included in Moodle in the form of theme layouts and current renderers.
Pages are a direct match to this approach, content in Moodle is dynamic and those layouts are where the output and content is joined.
Templates on the other hand are partly covered by layouts (for the page as a whole), and partly covered by renderers.

Renderers form part of that picture because it is within a script that things are assembled.
Again as of Moodle 2.8 with the work on output a best practices guide for renderers has been written which will outline how best to write renderers to match our chosen approach and why they should be written as such.

How we made this fit within the Moodle dodecahedron

Within Moodle we've decided to use the terminology from the Atomic Design approach. As discussed above templates and pages are not explicitly handled within Moodle, however atoms, molecules, and organisms are.
Class auto-loading has being used, and as these things belong to the Output API they have been organised by namespace under classes/output.

The following are the base structures:

core\output\element implements renderable
This is the absolute bottom unit, it can only be utilised by the core Output API. It contains basic functionality to all atoms, molecules and organisms.
core\output\atom extends element
This matches the Atomic Design atom concept. It is a basic building block often equating to just a single HTML tag.
Within Moodle we don't created atom classes for each HTML tag. That approach was considered but the clutter, the classes it would introduce, and the render methods for those classes was deemed to outweigh the advantages having them would provide. Instead in many cases our smallest "renderable" element will be the molecule.
core\output\molecule extends element
This matches the Atomic Design molecule concept. It serves a single purpose/interaction and can consist of atoms (as properties) but because we don't have classes/objects for every atom can also in some situations contain no atom objects at all.
core\output\organism extends element
This matches the Atomic Design organism concept. It is a collection of other molecules and atoms, and can have serve several purposes and/or interactions that have all being grouped under a single umbrella, this organism.

All of these base structure are abstract and cannot be directly instantiated. Instead actual atoms, molecules, and organisms must derive from one of atom, molecule, or organism. The element class is deemed to be internal to the Output API and therefore cannot be extended outside of the core Output API (at least the integrators won't accept it).

The importance of inheritance in rendering

By now you have a good picture of how we've organised output in Moodle in 2.8.
What is left to discuss is the importance of this hierarchy and its impact on how we produce output in renderers.

We know that Atoms form Molecules, which in turn form Organisms.
We try to apply this same inheritance within our renderers so that when you render an organism we start by producing the encompassing structure, then for each of the molecules that make it up we render on each. This passes the molecule to its own render method to produce the molecule. The same goes for the molecules that contain atoms, we produce the structure for the molecule and call render on each atom at the appropriate time for the structure.
Through this means there should in the perfect world scenario be one way to render each organism, molecule, and atom. Thus when a theme designer wishes to change how the search molecule looks for instance they need only change the render method for that one molecule, and every place that molecule is used, either stand alone or as part of a larger organism will be updated at the same time.

Unfortunately, with the present state of Moodle themes this idea of having the minimal possible render methods to produce the most consistent output is but a pipe-dream.
However as time goes on that will slowly correct itself, as more of Moodle is converted and themes begin to develop with this new approach.
For the time being the consistency that having a specific set of components and the organisation of those components is going to be a big win.

The element library

Hopefully you are already familiar with the element library in Moodle; if not then you really should take a look at it and get to understand what is it doing.

The element library is a very important piece in the puzzle that is Output within Moodle.
It shows how a component looks in one or more scenarios, the scenarios usually revolving around varying contents.

Designing and writing a component

A step by step approach to working through the creation and rendering of an element so that it meets the Output standards for Moodle.

Step 1: Are you sure you need to create a component

We want Moodle to contain a limited number of components. The problem that existed before this work was that every bit of code was creating its own output, and we do not want to end up back there.

The very first thing to do is to be absolutely sure that you need to create this component.

Atoms and molecules After the initial release this should be rare. It should be especially rare that you need to write an atom or molecule for a plugin.
Moodle should provide 95% of the atoms and molecules you could ever need. However if you have something that is truly new and unique in some way then perhaps indeed you do need to write a component.

Organisms Writing an organism isn't going to be as rare, certainly not at first anyway. As time progresses obviously we want to settle upon a finite selection of organisms, however it is a reality that we will not be able to cater for all core code and plugins initially. If you find yourself with a unique interface requirement, perhaps for the new and original plugin you are working on then you probably have met the requirement for creating an organism.

In both cases it is important that you search through the components already in Moodle and see if there are any that meet your needs.
If there is something close in Moodle core already then perhaps you need to adjust your design to make use of the existing component rather than introducing something similar but slightly different.
If you find a component you could use in a core plugin then you should create an issue in our Tracker and request that the component be moved from the plugin to core.
Then for the time being copy the component from the plugin you found it in, into your plugin. This way it will look consistent, you can use it and if it does get accepted into core you don't have to change anything about how you use it.

Step 2: Define the component

It very important to be sure of what you want to create.

The first thing to do is to work out what is it going to be, is it an atom, a molecule, or an organism?
Remember the following, they describe each of those in a single sentence:

Atom
A basic building block that severs no purpose or interaction.
Molecule
Serves just a single purpose OR interaction, not usually a part of an interface by itself, grouped with other molecules and atoms to form an organism.
Organism
A part of the interface, it is constructed of molecules and atoms, it can facilitate several like purposes and interactions

It should be possible to create a flow chart to aid this decisions, unfortunately one has not being created yet.

Once you've decided what type of component it is going to be you are ready to start designing what other components (if any) will make it up.

Its an atom

Whoa, its an atom?! Well this is easy for you then, it won't be constructed of anything else, it is a simple building block, there is nothing unique about it as far as the code is concerned. You can move onto the next step.

Its a molecule

Its an organism

Step 3: Create the component class

Step 4: Write the render methods

Step 5: Write generator samples

Step 6: Style those samples in bootstrapbase and base

Step 7: Use your component

Tracker issues

The following tracker issues relate in one way or another to the development and continued work on Output.

  • MDL-45885 Decide how output components (the issue that saw this document created)
  • MDL-45770 Implement stage 1 tasks from the Render Library specification
  • MDL-41663 Allow renderers and renderables in a namespace to be auto loaded.
  • MDL-45828 Create the element library admin tool.


See also