MarkRS/cascading cheat sheets/components/preamble
Cascading cheat-sheets for the expert beginner.
Components deliver main areas of functionality, for example an event diary (there are many available as extensions), or the core functions of user management and displaying articles.
You'll find the code for components in the directories
The first one is for for front end functionality, the second for back end (administration) functionality. The code for each component is in a subdirectory of one of these named com_<component name>. Components, by definition, need functionality in both areas.
You should be able to find the, for example, content component ("com_content"), which is for displaying articles, the user component ("com_user"), which is for for managing website accounts, and several others.
This naming is one of those Joomla principles. You probably can hack it so that you can name a component directory “freds_diner”, but a whole load of defaults just won't work and you'll be fighting every step of the way.
We're going to zoom through the actions occurring from a website URL appearing to the beginning of a component running. We're going to start in the only possible place, the middle. It's going to look a little slow, but only for a very short while, and I think you'll find this will explain many of the Joomla idioms which will make your overall learning curve much quicker. Let's imagine we are looking at a component that allows website users to answer a questionnaire that is presented to them, stores their answers, and allows an administrator to look at their answers. To keep it nice and simple, we'll imagine our administrator has too much time on his hands and hard codes a new questionnaire into the front end every day.
Here's the process of events for the user
By selecting our questionnaire component, let's imagine that a URL like this
is generated. Whilst this is not something that Joomla can directly work with, this is quite possibly the way it'll be. It could be the case if you had, for example, a SEF module enabled.
Everything goes through index.php
This is the first step of every Joomla page. There are two different versions of index.php, one for the back end and a separate one for the front end. You'll find the front end file in the site root.
Have a look in this file and you'll see the first two active lines are
define('_JEXEC', 1); define('DS', DIRECTORY_SEPARATOR);
The first line defines a constant called _JEXEC and gives it the value “1”. The value is pretty irrelevant but its simple existence is part of the system security. You'll see that many Joomla code files start with a check for this (or some other) constant, exiting immediately if it's not found. This helps prevent miscreants from going directly to internal parts of the system.
The second line is about to disappear in Joomla 3.0, since php handles converting “/” to the requirements of the platform you're actually running on. My advice is don't use DS, it's just BS these days.
The next three blocks are dull, simply loading defines files that are required for the core running. Even the line after doesn't really concern us yet, just setting a marker point used during debugging.
The line after that,
$app = JFactory::getApplication('site');
might look fairly dull, but it creates the application object that contains the top level scaffolding that defines Joomla. You start to get a sense of this with the next line
which, it's easy to guess, will set up a whole bunch of things to prepare Joomla for the job at hand.
I know “factory”, but how does “JFactory” work?
Let's take a quick sidestep that helps make this very common Joomla style clearer. Just taking the case above, as an OOP-aware developer you're familiar with the idea of an object factory, that thing that allows OOP people to tell themselves that they're not using global objects. But what about the “J”?
When you see stuff like this in the code, and there's a lot of it (JFactory, JForm, JText, and on and on), Joomla goes to the directory
to look for something with that name (without the “J”). So, for example there is a file
that contains a class called JFactory, and, surprise surprise, it has a method named “getApplication”. This is a very standard way of Joomla calling core functionality. Some functionality is more detailed and so gets a whole directory in that location. For example the call
finds a file <site root>/libraries/joomla/user/user.php. That file contains the definition of a class JUser, and you won't be shocked to find that it contains a method "getInstance".
Any call that looks like “J<Something>::function” will be using this mechanism. Now you know where to go when you need to know what a function like this does and the only answer you can get from the Joomla cognescenti is “read the code”! It's the same location for back end code as well as front end.
And now, back to the records...
After another profiler call that I'm not going to talk about either, we come to the line
You remember I said that Joomla couldn't directly work with that URL we started with? The "route" method "decodes" the URL into something that Joomla can process. If we'd started with the URL
this "decoding" would have been at its simplest. Anything else will get converted back to this type of format, which is what the rest of the internals of the framework actually work with.
That all just brings us to the point where we can actually start doing something. You'll have realised that the line
means that the application class (which, of course, is defined in the file <site root>/libraries/joomla/application/application.php), that our factory class created for us initially, has a method “dispatch”. This method does a little bit of setting up and then starts the heavy lifting with the component. Having a brief look through that code, it's mostly easy to see this happening. But no, wait! Clearly the critical line doing this is
$contents = JComponentHelper::renderComponent($component);
but not only did we not pass in a value for $component to this method, but there's no file <site root>/libraries/joomla/componenthelper
Well, no, that seems to be more of the internal wiring that does so much for you, you want to look in
where you'll find the file you want, “helper.php”.
And, when the framework doesn't find a component name stored in that variable, the dispatch method finds the component to load from the data that was stored during the "route" method. And, in case, like me, you're confused by this use of words; the not-so-obvious piece of information is that "renderComponent" is not the same as "render". The first one generates the output from a specific component. The second one takes that component output and fits it into the overall page that your user sees on screen.
So now we have arrived at the point that the component can start to do its work. The dispatcher has brought us there. Time to look at the details of component design!
I'm going to start developing an example of a simple component that looks after a little bit of data, shows it to some people and allows some people to edit it. In short, a "hello world" program for people who actually want to do something.
Follow along at Component Overview.