MiniDoc: How Joomla pieces work together

Forum closed, please submit your tips and tricks to: http://docs.joomla.org/Category:Tips_and_tricks
Locked
merill
Joomla! Intern
Joomla! Intern
Posts: 62
Joined: Sun Apr 20, 2008 9:44 pm

MiniDoc: How Joomla pieces work together

Post by merill » Thu May 08, 2008 1:44 pm

Some weeks ago I was asked to confirm if a custom php web developement with a high budget was the right path to follow. After having a look at the goals of the project I thought that the custom path was overkill and told him that I beleived that any open source CMS customization could deliver the same for lot less money. Having made a selection a year or so before I recommended Joomla! as the right tool for the job expecting that my paper will end at this point. But I got finaly involved.

The only weak point of Joomla! at the time I made my selection (version 1.x) was that is was sloooooow because of the huge joomla.php library file but I thought when making my recomendation that the new hardware we have now would compensate.

But to my surprise the Joomla! 1.5.2 framework had just been released and a first look at it was promising. The problem was that there is very few, if no information at all about how the pieces that Joomla! has become to be connect each other. After having to go through the development for both of a component, a module and a plugin to achiev the goals of the project I had to look a lots of dispare small documents, source code and tantra to learn how this pieces work together to make the new Joomla! 1.5 a fabulous environment to develop web solutions in an easy and powerful way. My congratulations to the development group that has been able to envision such a magnificient tool.

In this document I try to express to the community what I have learnt while developing the project and both learn from the feedback and help others. Because I am quite sure that there are lots of things that need revision I humbly request the help of the Joomla! gurus outside there to take the time to read this somehow long disertation and feed me with their knowledge. And, not less important, I request your tolerance if my english is not Oxford like because I am not a native english speaking person.

Ok. Let's start. You enter the Joomla! framework by making calls to index.php. Joomla! is designed mainl to deliver the result of component files. When you call a page link like index.php?option=com_<name> the Joomla! framework tries to find and load the file components/com_<name>/<name>.php from whatever the folder you have installed Joomla! to. So if your component is 'com_read' you should have a 'com_read' folder and a file named 'read.php' inside it. I will call this file the 'base file' and it is in this file where you make the decision about going on with the old flat model, returning the HTML code for the requested page, or enter the new Model-View-Controller model or MVC.

This model walks over two legs: a file and a class. The Joomla! framework will usually look for a given file and, if found, try to register a given class that must exist inside this file. If either one is missing the call fails.

You start all the fireworks by including the a controller file in your base file. The controller file can be named like you want but, by convention, it is called 'controller.php'. So, in your base file (<name>.php), you write down something like this:

require_once(JPATH_COMPONENT.DS.'controller.php');

Now, to be coherent, we have to create a new file and name it controller.php. This file can be created anywhere you want just because we are including it by path but if you have written exactly the former line it should be created in the same location where your base file is located because JPATH_COMPONENT holds the path where the executing component base file is and DS represents the path separator translated to whatever is convenient for your OS, being it windows or linux.

So create controller.php and make a reference to the controller library inside by importing it with:

jimport('joomla.application.component.controller');

We have the file, we need the class so we have to define a class that extend the JController base class. This is the class leg we wrote before about and it is here where our action will happen. You can name this class as you like but, by convention too, it is named after your component so you write:

class <name>Controller extends JController
{
}


In this stage we have our first two files, the base file and the controller file. The base file loads the controller and the controller defines a class. So far so good and easy. Our next step is to create an object of this class and to put it to work. So we add this lines to our base file:

// Create the controller
$controller = new <name>Controller(); or whatever the name you gave your controller class

// Perform the Request task
$controller->execute(JRequest::getCmd('task'));


From this point on things start happenning by themselves. Up to now you were able to name files, except for the base one, and put them where you wanted, and name classes like you wanted because you were including the files by path/name and calling your classes by yourself (well, only one file and only one class actually but you could do it!). But from now on it will be the Joomla! framework the one that will begin loading your files and calling your classes automatically so we must be quite careful as where we put our files, how we name them and what classes we define because a single letter mistmatch will make Joomla! fail.

Where does the Joomla! framework get the data to play?. Well, the answer is easy: from the request, be it a GET request or a POST request. But we have NOT written anything else in the request except option=com_<name>. Where does the 'task' in the execute call comes from?. Do we really have a meaningful 'task' variable?

Yes, and this is the 'problem': Whether you pass or do not pass a full request, Joomla! will use its defaults to complete one making some errors difficult to spot.

The controller->execute() call will make the Joomla! framework try to do the requested job that, in this case, will be the default task 'display', just because we have not specified another one.

class <name>Controller extends JController
{
function display()
{
echo 'displaying';
}
}


So that if your request contained a 'task=jump' parameter the controller would have tried to call a function named jump in your controller class:

class <name>Controller extends JController
{
function jump()
{
echo 'jumping';
}
}

Up to now we have delved with the controller part of the model. This is a new point of decision. We can stop here or we can go a step further and enter the view part of it. Stopping here will, at least, simplify your base file. Up to now we usually had a switch statement that depending on the given task, or whatever passed variable, called a function with several arguments to deliver the HTML result.

Now the switch is gone and our different tasks are functions in the controller.php file. Arguments are lost but all the needed variables are available from the framework so we will be able to rertieve them easily.

There is nothing that forces us to use the 'task' variable to drive the call because we can pass the value of any variable as the parameter to the execute function call but to stick to the non-written rules, 'task' is usually used (and as it is treated specially by the system it is a good idea to stick with it).

To trigger the views we only have to call the display() function of JController. We do this by inserting in our function a call to parent::display() as the last line. At the minimum our controller file should contain the following:

jimport('joomla.application.component.controller');

class <name>Controller extends JController
{
function display()
{
parent::display();
}
}

But what's a view? A view is a subset of data. It's the same concept as views in SQL parlance. You deliver different parts of your data with different views. So you could have a detailed data view and a resumed data view, the later presenting a subset of the whole data presented in the former.

As you can have multiple views Joomla! uses the 'views' folder in your component's base directory to keep things tidy. This folder is only a placeholder of your views. This means that you have to create the views folder and now you could have something like in your disk:

<name> base folder
controller.php
<component_name>.php
'views' folder
view1
view2
...

Inside the views folder other folders hold the files that build each view. What does the Joomla! framework do with this?. To include a file named view.html.php that should exist in your view directory. A bit messy I know so I'll try to explain.

When you built your request you included a variable named, guess... yes, 'view' that told the MVC model what view you wanted. Or if you did not include it you better include it now because there is not such a thing like a default view. So your URL was something like:

http://my.site.com/index.php?option=com ... ew=<myview>[&task=<mytask>]

The task part may or may not exist. Remember that if you omit it you are defaulting to task=display. With this URL Joomla! is importing a file located at <site root dir>/components/<name>/views/<myview>/view.html.php. If this files or the path does not exist Joomla! will fail. By simply swapping the value of the view you deliver different views of your data with no effort. Cute, isn't it?.

Every request for a view require that you also specify the format you are serving the view. There exist several well known formats such as html (the default one if none is specified), rss, etc. but you can use your own. If no format is specfied in the request with the 'format=<myformat>' parameter a default value of 'html' is used.

The 'html' format makes the Joomla! framework wrap the response in whatever template your site is using so that you get a fully built HTML page. This way, with very few effort from you side, you get back your page fully loaded with modules or whatever you had configured.

The specific format you are using is what you have written in the middle part of the name of the file in your view folder (The file we talked about a few lines before 'view.html.php'). If you use a different format like 'rss' your file should be named after it like view.raw.html, get it?

As told before, you can have other formats than html and Joomla! will not wrap the template on them. You could have a 'pdf' format to deliver your data in pdf format or even an 'ajax' format to deliver ajax responses to the front-end easily. Just construct your URL like

http://my.site.com/index.php?option=com ... ormat=ajax

to make the Joomla! Framework look for, and load, a file view.ajax.php located at <site root dir>/components/<name>/views/<myview>/ from where you can echo anything you want. It's that easy.

Anyway, to achieve your goal we need some code inside the view.<format>.php file. We have the file, now we need the class. And truly you have to extend the JView class with your own following the strict rules we said before that we should follow. In this case your must build your class by concatenating the component name with the word 'View' and with the view name. So our class name will be a capitalized <name>View<myview>. If your component is named travels and your view is named detail (URL ...?option=com_read&view=detail) your view class must be:

class TravelsViewDetail extends JView
{
function display($tpl=null)
{
echo 'blah, blah';
}
}

Within this class you only have to feed the data you want to display for your component under this specific case. You can do this directly by delivering the [x]HTML code directly, or through calls to echo inside php tags, or be more subtle and use a layout (more on this later).

Can you have other functions besides display? I don't know. This is something that the gurus must respond. Where does the display function come from? Again, I don't know. Hope that someone else can help here.


But we can go a bit further. Up to this point we have a distributed framework that dissects our request in such a way that allow us to create small and very specific files to react only to specific types of requests. In this way the files that we must process can be very small and adjusted to the situation we are treating, speeding up the global response time of the system by not loading lots of code that will not ever be used with this kind of requests (as in Joomla! 1.x).

Having reached this point we can dissect a bit more and have another layer of detail: the final layout for the data we deliver.

A layout is a way to present the data for the view. The same data can be delivered under different visual aspects so that the same preparation code (inside the display function of your view class) can present the same data in different ways simply using different files. You 'inject' the view data in the layout template and use the template code to visually format it before reverting to the user.

As before, if you do not specify a layout you go with the 'default' layout. To use layouts you need to create a new folder under the related view folder named 'tmpl' and create a file named <mylayout>.php, nothing more nothing less. If you are using the default layout this file will be named 'default.php'.

The desired layout can be specified in the request by means of a 'layout=<mylayout>' variable or can be injected in the call if you manage to get the layout you want to use from other sources.

To use a layout your view class must call 'parent::display();' and pass the layout template name as a parameter. So your class should be:

class <Name>View<Viewname> extends JView
{
function display($tpl=null)
{
// Prepare the data
$data1 = ....
$data2 = ....
$moredata[] = array....

// Inject the data
$this->assignRef('variablename', $data1);
$this->assignRef('variablename2', $data2);
$this->assignRef('variablename3', $moredata);

// Call the layout template
$tpl = 'myTemplate';
parent:display($tpl);

or more directly

parent::display('myTemplate');
}
}

This way Joomla! will look for a file named 'myTemplate.php' in the 'tmpl' folder of the given view. Inside this template file you get a '$this' object that has access to the variables you have injected by means of '$this->variablename' that you can use in your constructions to deliver your [x]HTML *FINAL* code.

As you surely will have determined by this moment by yourself you can have different layouts files in your tmpl folder thus driving easily your output with simple, small, very specific files.


If you have been observant you will have noticed that we have not 'used' the 'model' part of MVC model. Here you have the last point of decision. You can go without this part or apply fully the model but I think I will keep this tale for another session. For sure I have already abused of my audience.

I wait forward for your replies, complaints and the like.

Thanks.

merill
Joomla! Intern
Joomla! Intern
Posts: 62
Joined: Sun Apr 20, 2008 9:44 pm

Re: MiniDoc: How Joomla pieces work together

Post by merill » Sat May 10, 2008 12:33 pm

From the date this MiniDoc was written I have learnt that I was a bit mistaken so here I fix my error. I have not edited the original text just for you to have a reference of what was wrong.

The desired layout can be specified in the request by means of a 'layout=<mylayout>' variable or can be locally injected in the function if you manage to get the layout you want to use from other sources.

To use a layout your view class must call 'parent::display();' and pass the layout template name as a parameter. So your class should be:

class <Name>View<Viewname> extends JView
{
function display($tpl=null)
{
// Prepare the data
$data1 = ....
$data2 = ....
$moredata[] = array....

// Inject the data
$this->assignRef('variablename', $data1);
$this->assignRef('variablename2', $data2);
$this->assignRef('variablename3', $moredata);

// Inject the layout if not using the request
$this->setLayout('mylayout'); // Local layout injection
parent:display($tpl);
}
}

This way Joomla! will look for a file named 'mylayout.php' in the 'tmpl' folder of the given view. Inside this template file you get a '$this' object that has access to the variables you have injected by means of '$this->variablename' that you can use in your constructions to deliver your [x]HTML *FINAL* code.

You can also use sort of 'layout templates'. The file that Joomla! will look for in the tmpl folder is composed by the name of the layout concatenated with underscore and the contents of the $tpl variable. If $tpl is null as in the example before the final name is simply mylayout.php but, if $tpl equals template1, the final name will be mylayout_template1.php thus being able to go a finer grain thus driving easily your output with much simpler, small and very specific files.


Locked

Return to “Submit Your Suggested Tips & Tricks to Docs.joomla.org now please.”