Note:

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

Guide to creating output elements: Difference between revisions

From MoodleDocs
No edit summary
Line 6: Line 6:
|assignee = Damyon, Sam
|assignee = Damyon, Sam
}}
}}
{{Work in progress|forumurl=https://moodle.org/mod/forum/discuss.php?d=261202}}
{{Work in progress|forumurl=https://moodle.org/mod/forum/discuss.php?d=261202|info=This entire page needs rewriting as we now want to implement templates in renderers instead of relying on strict php OO inheritance}}
A guide to writing output elements and the render methods for them.
A guide to writing output elements and the render methods for them.



Revision as of 06:35, 16 January 2015

Renderer consistency
Project state Specification
Tracker issue https://tracker.moodle.org/browse/MDL-45885
Discussion https://moodle.org/mod/forum/discuss.php?d=261202
Assignee Damyon, Sam

Note: This page is a work-in-progress. Feedback and suggested improvements are welcome. Please join the discussion on moodle.org or use the page comments. This entire page needs rewriting as we now want to implement templates in renderers instead of relying on strict php OO inheritance

A guide to writing output elements 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, when we talk about elements we talk about one of or more of atoms, molecules, and organisms.
  • Subelement When we speak of subelements we are talking about the smaller elements that are going to be of a larger element. e.g the molecules that are present in an organism.
  • 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 elements 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 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.

We should not be creating Atoms as elements. It breaks the natural structure of the templates. We should use HTML instead of inventing a new language on top of it.

A html <button> is a button and a list is a list.

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 elements and the organisation of those elements 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 an element looks in one or more scenarios, the scenarios usually revolving around varying contents.

Designing and writing an element

A step by step approach to working through the creation and rendering of an element so that it meets the Output standards for Moodle.
If you want a quick overview of what to do have a look at the peer-review checklist in the next section

Step 1: Are you sure you need to create an element

We want Moodle to contain a limited number of elements. 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 element.

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 an element.

Organisms Writing an organism is going to be a common requirement. Within core there may be a finite number of organisms, only increasing as new Moodle elements are created and new interfaces added. However when creating plugins or updating output in existing plugins it is very likely that new organisms will be created. If you have an interface in a plugin that is somehow unique to that plugin then you have a organism.

In both cases it is important that you search through the elements 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 element rather than introducing something similar but slightly different.
If you find an element you could use in a core plugin then you should create an issue in our Tracker and request that the element be moved from the plugin to core.
Then for the time being copy the element 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 element

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 element it is going to be you are ready to start designing what other elements (if any) will make it up.

Now is a good time to be very clear about the purpose of your element, as well as any interactions that you want it facilitate. Consider writing down a clear and concise description of your element and sharing what you are planning in the forums, with colleagues or just generally with other developers. This output approach is still fresh and we are all still learning how it works in detail so the more exposure you can get now the easier it will be down the track.

When thinking about your element try to think about it is a blueprint to what you want to display. When displaying an actual something it is populated by data and that data is then used by a render method of a renderer to produce HTML. Think about where that data is coming from, think about the renderer best practices, think about the style guide, and think about what others may and will do when overriding a renderer to override your render method.

There are two additional important concepts to consider at this point as well, attributes and properties. Important enough to have their own heading so as to be easily found.

Attributes

These are HTML attributes. It may be very very tempting to set attributes like classes and ID's within an element. But please do not.
Attributes should only be added to an element by the renderer. They may be added by any one of the three types of render methods you'll read about later.

The reason for this is that we want the renderer to be solely responsible for translating an element to HTML. An instance of an element is simply a catalyst for the data contained within.

Within a renderer attributes can be interacted with as follows: // A publicly accessable array of attributes. Key => Value. $element->attributes;

// Set an attribute on the element. $element->set_attribute($key, $value);

// Set an array of attributes on the element; $element->set_attributes(array(key1 => value, key2 => value));

// Addes a CSS class to the attributes $element->add_class('some-class');

// Returns the attributes as a string suitable for use in HTML output. $element->get_attributes();

Properties

Talking about properties here I am not talking about class properties of the element that are used to contain data.
I am talking about the properties that describe the instance of the element. To get your head around this consider a menu that has several items within it. There are three common properties added by default to all elements that are applicable here:

active
A boolean property, set this to true if this item points to the current page. The active item.
enabled
A boolean property again, set to true this says that the item is enabled and the user can perform the associated action. Set to false is like saying the user cannot interact with this menu item.
dimmed
A Moodle-esq property. Set to true if the item is visible to the current user but not to every other user. Think of it like viewing a hidden course because you have the capability to.

Properties can be added, and set by either a parent element, or a renderer if need be. They are used to convey properties that are applicable only in certain situations.
The ability for an element to add properties to its subelements allows us more re-use of elements within renderers so that we don't need dedicated objects in situations where it is simply a property or two that differs from an available element.

Properties can be interacted with the following methods and properties:

// Publicly accessable array of properties. Key => Value. $element->properties;

// Add a property to this element. $element->add_property(name, value);

// Add an array of properties to this element. $element->add_properties(array(n1 => value, n2 => value));

// Sets the value of a property. $element->set(name, value);

// Gets the value of a property. $element->get(name);

// Returns true is a property is set and is not empty. $element->is(name);

Step 3: Create the element class

Creating an element is really quite simple, the following headings explain what you need to know. Remember if in doubt there are a lot of examples that can be easily found in Moodle core (within lib/output).

Element location

All elements belong to the Output API and should be namespaced within it for autoloading and consistency with Moodle core elements. This makes locating elements very easy, core elements will be located within an output subdirectory of the classes directory as shown below:

lib/classes/output/myelement.php

Plugin elements will be located in a similar fashion within an output subdirectory of the classes directory. e.g.

mod/myplugin/classes/myelement.php

Class name and inheritance

Classes are namespaced for the output API and located in the file above. Because classes are namespaced the actual class name is simply the element name. The same name as was used for the file. They must however extend the appropriate element type, if you are creating a molecule it must extend \core\output\molecule, if its an organism it must extend \core\output\organism. For following is an example of how this would look for a core element:

<?php namespace core\output; defined('MOODLE_INTERNAL') || die();

class myelement extends organism {

And for an element you are creating within a module plugin:

<?php namespace mod_myplugin\output; defined('MOODLE_INTERNAL') || die();

class myelement extends \core\output\organism {

Class properties

We like to keep elements simple to interact with. For that reason we encourage people to store data and subelements that will be used during rendering as public class properties. This is done so that data is accessed in a consistent fashion when interacting with an element. For this reason we would rather not see developers adding methods to an element unless truly required.

Subelements are a good example. If you were writing a navigation bar organism for example you may have a title molecule, a menu molecule, and a search molecule. The title, menu and search molecules are the elements.
These will become public class properties of your element.

Class methods

Elements should only have methods to support their own construction. As expressed above all information useful to a renderer should be stored in publicly accessible properties, none of it should have to be accessed via method calls. This is done so that interaction with elements is consistent across all elements. Methods to aid the construction of the element are encouraged so that information can be easily added to the element.

Your constructor

The constructor for your element should allow the developer to pass in the required data and subelements. Consider when writing the constructor how developers will pass information into the element. In many cases there are going to be two types of data that will commonly be passed in:

  1. Elements (or arrays of) that make up parts of your element.
  2. Scalars (or arrays of) e.g. strings, integers, floats and booleans.

Make the data that is absolutely required part of the constructor and simply have publicly accessible properties for the optional data that can be set by calling code if required.

Its also worth considering if you are creating a molecule that perhaps data handling for the atoms that make it up may be worth including in your constructor.
For instance a dropdown consists of a trigger element (button, link, image) and a menu, the menu is a molecule that consists of items. The constructor of the dropdown could aid construction by accepting two arguments, the first a way to pass in a trigger, and the second either an already build menu element OR an array of items that get used to construct a menu element within the dropdown constructor.

Some points to remember:

  • Don't forget all properties should default to null if they do not have data set.
  • If you have a collection of something as a property consider adding add_xxx() and add_xxxs() methods to aid the construction of elements.

Step 4: Write the render methods

There are 3 categories of render methods that will exist within every renderer and depending upon the type of your element you will be creating one or more of these methods for it.

Why the three types of render method? There are two key reasons to take the above apporach.

Re-use
By ensuring we call the render method to produce elements and subelements when ever possible we will hopefully be making it easier to style Moodle as it won't be necessary to style absolutely everything individually. Instead if render has being used consistently to produce a button for example styling the HTML produced by render_button() should style all buttons throughout Moodle.

Make overriding renderers in themes more controlable
The three types of render methods are designed to separate the logic and display that is permissable in renderers.
Render method should contain as little logic and PHP as possible, however in many situations a bit of PHP and perhaps a bit of logic is going to be required in order to take data from one form and make it ready to present.
If overriding a renderer within a theme the theme developer can look at what they want to achieve and choose the suitable method to override.
If they are looking to change the markup for an element then they can override the render method, they will not need to know anything about how the element was constructed or what information went into it. They can focus on the data the element has and produce the HTML they desire.
If they choose to change data, or want to display something different to what is there by default then they can override the translator method and continue to hack away to their hearts content.


Hopefully as you read about the render methods below the advantages to this approach will become clear.

Render method

This is the easiest to understand and no matter what type of element you have created you will need to write a render method. The render method takes an element and returns HTML to display it.

The render method takes a strict format: /**

* Produce HTML to display myelement.
*
* @param \core\output\myelement $myelement The element to display.
* @return string An HTML version of the element.
*/

protected function render_myelement(\core\output\myelement $myelement) {

   // Generate HTML for the element.
   return $html;

}

The following are rules to follow when creating a render method.

  • It display the element, nothing else.
  • It is a protected method.
  • The name of the method is always "render_" followed by the non-namespaced name of your element.
  • There is only ever one argument, the element to render and it should be typehinted.
  • It will contain no logic.
  • It uses the public properties of the element for data.
  • It supplments this by using the available methods ONLY IF ABSOLUTELY REQUIRED
  • It returns a string, the HTML to display the element.

This method is very simple to understand, and providing you have properly researched and proposed your element it should be even easier to write.

If you are writing a render method for molecule or organism then you likely will have subelements that have being used within your element. Where possible you should call $this->render() on the subelements to produce HTML for them that can then be included in the HTML that you are producing for your element. Only if you absolutely must should you handle the generation of HTML for subelements directly within the render method for your element.
If you do produce the HTML for a subelement without calling render than you must manually call the subelements prerender method to ensure that it has an opertunity to complete and requisits it has before rendering.

This is done to ensure that where possible we re-use the HTML for an element. By doing it we reduce the number of elements that a theme must style if all it is doing is styling.
If a theme overrides a render method it is not obligated to take this same approach. Theme overridden renderers can do as they please, any duplication of structure they introduce is their own business.

Convenience method

The name for this type of method provide a big hint as to what it is, it is a method to conveniently construct and render an instance of your element. This method also takes a very simple, predicatable form.

/**

* Create and render a new myelement.
*
* @param mixed $arg1
* @param mixed $arg2
* @param mixed $arg3
* @return string HTML for myelement.
*/

public function myelement($arg1, $arg2, $arg3 = null) {

   $obj = new \core\output\myelement($arg1, $arg2, $arg3);
   return $this->render($obj);

}

This type of method always does three things:

  1. It takes the arguments necessary to create a new instance of myelement.
  2. It creates a new instance of myelement given the arguments it is given and sets it up as required.
  3. It calls $this->render() and gives it the object, returning the outcome.

There are a few things to observe when writing a convenience method:

  1. It is always public.
  2. Its arguments should be complete.
    • Meaning that they should be arguments that can be immediately to the element
    • OR can be checked in conditions to alter the element.
    • They should not be objects to support the generation of data. The data should be complete.
  3. It should not produce any HTML itself, the render method is responsible for this.
  4. It returns a string, the HTML to display for the given element.

In the case of molecules and organisms it is permissable for the convencience method to take actual subelements OR the arguments required to create necessary subelements. This is at the discretion of the developer and may be determinent on the number of arguments required to construct the element.
Complex elements that require a lot of data to set up are probably not ideal candidates to create convenience methods for.

Translator method

These methods take complex arguments such as data and objects from outside of the Output scope and manipulate/smooth the data into a complex organism or molecule.
They should be used to pass in the information the current element requires as well as any information that may be used by an overriding renderer to access additional data that may be desired.

These are likely to be rare for core elements, however just about essential for elements being introduced by plugins for example where having retrieving data from plugin objects for use in an element or subelements is going to be required.
If for example you consider how your would render a forum discussion the translator method would likely take a forum discussion object and use a method of it to retrieve a nested array of forum posts that can then be used to create a discussion element, and its post subselements.

Just like the above convenience method the translator method should not produce HTML itself, instead it should create the necessary element and any required subelements before calling $this->render() on the subelement.

Its important to note the pupose of having these methods as renderer methods and not having them abstracted to another layer of your code.
Because these methods exist within the renderer they can overridden by the theme in order to change the information that is used to construct the elements. This is also why translator methods should be given arguments that not just relate to what you immediately require for your idea of output, but also closely related things that may be required for others who wish to change the output.

Step 5: Enhance your output with JavaScript

If you've planned to add JavaScript to your project then now is the time to look at achieving this.

This section needs a lot more work, there is a tracker issue [https://tracker.moodle.org/browse/MDL-45854 MDL-45854 Define and document JavaScript output guide] which once complete should make writing this section easy.

Some notes for the time being:

  • JavaScript should be initialised by the renderer within the render method.
  • Simple element_actions can be attached to elements by calling $element->add_js_action().
  • When attaching events to an element it should be done by ID.
  • When delegating events to an element it should be done using a data attribute data-enhance="action" which requires the JS selector [data-enhance="action"]
  • If you need an ID on your element for JS call $element->require_id() which will generate an ID if one is not present (remember you are enhancing you can't assume one has or has not been set already)
  • JS should follow our JavaScript guidelines

Step 6: Write generator samples

More to come here as the Element_Library evolves.

Step 7: Style those samples in bootstrapbase and base

Hopefully when designing your element you have already considered how it is going to look, and had taken into consideration what is available in at least bootstrap base.
Because you have already written the element generator in the steps above you can easily refer to the element library when styling your element and testing.

Its recommended to start with bootstrapbase as this is the scaffolding theme that our default theme clean is build upon. All CSS for your element within the bootstrapbase theme should be added to theme/bootstrapbase/less/output_elements.less and be written in hierarchical less so that it is clear which styles apply to your element.
The CSS should be preceeded by a clear heading that identifies which element the styles belong to as well.

It is also necessary to style the element in the base theme.
All CSS for your element within the base theme should be added to theme/base/style/element.css and like above should preceeded by a clear heading that identifies which element the styles belong to.

The actual Less/CSS should be styled according to our Element HTML and CSS guidelines

Step 8: Write tests

Both acceptance and unit tests may be applicable to your element depending upon what you've done, and just like all of new code arriving for Moodle tests are now an expectation. You can not of course create tests to automatically check the display of your element, however the element library facilitates a user manually doing that.

PHPUnit tests If your constructor contains any logic for smooth data into its properties then this should certainly be tested.
Likewise if you've added any methods to aid the construction of your element they should be tested as well.

Acceptance tests These are particularly applicable if your element facilitates any kind of interaction. If so then it is worthwhile creating a test scenario for this interaction.
If the interaction triggers a visual response, like clicking a button and a dropdown appears then this can be easily tested within the element library.
If a more complex interaction is taking place then you should consider writing a test that belongs to a code that makes use of your element. For instance if your element is a search form and it is used within the forum consider writing an acceptance test for the forum testing your element if there is not already one there.

Step 7: Use your element

Congratulations! At this point you have written your element, you've written the required renderer methods and supporting generators and tests.
You are now ready to use your element within your code.

Peer-review checklist

The following is a checklist guide of what to look for when reviewing an element and/or element render methods. Items already on the peer-review checklist have being excluded.

The element class
[ ] The file is located in classes/output/elementname.php
[ ] Autoloading is used, the file has not being included anywhere.
[ ] The element is correctly namespaced to the Output API (namespace core\output OR mod_plugin\output).
[ ] The element name is accurate to its function and concise.
[ ] It is a unique element and not a duplicate of another element.
[ ] It extends either atom, molecule or organism
[ ] All data used during rendering is accessed through public properties.
[ ] All public properties of the class are data that can be used during rendering.
[ ] All optional public properties (not set within the constructor) default to null.
[ ] All/any methods the class has aid in its construction (importantly they don't return data)
Styles for a core element
[ ] The element has being styled in at least the bootstrapbase and base themes.
[ ] The styles in bootstrap base have being added to theme/bootstrapbase/less/output_elements.less
[ ] Bootstrapbase styles have been written in less format and are preceeded by a clear heading of the element they belong to.
Styles for a plugin element
[ ] The element has being styled in at least the bootstrapbase and base themes.
Renderer
[ ] Does the renderer conform to the Renderer best practices?
Renderer - render method (required)
[ ] A method has being written.
[ ] The method is protected.
[ ] The method takes a single argument, an element and and adequate typehint is in place.
[ ] The method contains no logic, no globals.
[ ] The method returns HTML.
Renderer - convenience method (optional)
[ ] The method is public.
[ ] All arguments are complete arguments (see above docs for details)
[ ] Contains no logic other than data smoothing if absolutely required.
[ ] Does not produce any HTML itself.
[ ] Call $this->render($element); and returns the output.
Renderer - translator method (optional)
[ ] The method is public.
[ ] Logic is minimal and the related to smoothing data from arguments into elements.
[ ] Produces a single element only/
[ ] Produces no HTML itself.
[ ] Call $this->render($element); and returns the output.

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 elements (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