User

Difference between revisions of "MarkRS/cascading cheat sheets/components/overview"

From Joomla! Documentation

< User:MarkRS
m (Changed absolute link into relative link)
 
(6 intermediate revisions by 2 users not shown)
Line 1: Line 1:
{{incomplete}}
+
{{inprogressbyuser}}
 
= Component Overview =
 
= Component Overview =
  
Line 7: Line 7:
 
Cascading cheat sheets for the expert beginner.
 
Cascading cheat sheets for the expert beginner.
  
The previous article in this series was [[User:MarkRS/cascading_cheat_sheets/components/preamble|Component Preamble]]
+
The previous article in this series was [[{{#titleparts:{{FULLPAGENAME}}|-1}}/preamble|Component Preamble]]
  
 
== Ready... ==
 
== Ready... ==
Line 15: Line 15:
 
== Steady... ==
 
== Steady... ==
  
To show something to your user, the dispatcher looks for a file called “controller.php” in the component main directory.  You will, of course, remember that the component is to be called “com_questions”.  Just to be clear, that means that the controller file is
+
To start your component Joomla looks for a file
  
<source lang="php" highlight="33">
+
<tt><site root>/components/com_<component-name>/<component name>.php</tt>
<site root>/components/com_questions/controller.php
+
 
</source>
+
This is where your component takes over.
 +
In the simplest case, Joomla already has the rigging to do most of what you want.
 +
 
 +
Your file can be as simple, and standard, as
 +
 
 +
<span id="questions.php">
 +
'''<tt><site root>/components/com_questions/questions.php</tt>'''
 +
<source lang="php" highlight="18">
 +
 
 +
    // No direct access to this file
 +
defined('_JEXEC') or die('Restricted access');
 +
 +
    // import joomla controller library
 +
jimport('joomla.application.component.controller');
 +
 +
    // Get an instance of the controller prefixed by the component name
 +
$controller = JController::getInstance('questions');
 +
 +
    // Perform the Request task
 +
$controller->execute(JRequest::getCmd('task'));
 +
 +
    // Redirect if set by the controller
 +
$controller->redirect();
 +
</source></span>
 +
 
 +
The base controller class (from the third line above. You know where to find that if you've been following this series) just looks for a file called “controller.php” in the component main directory.  Just to be clear, in this case that means that the controller file is
 +
 
 +
<tt><site root>/components/com_questions/controller.php</tt>
 +
 
 +
Provided that is an instance of a controller class called QuestionsController then everything will be set for the next phase.
 +
 
 +
Of course, at the moment the URL doesn't contain "task=<something>" for the command JRequest::getCmd('task') to find, so the default setting is to display the first view of the component.  What's the first view?  Of course you'd guess (correctly) that the default view is "questions", nice and simple.
  
 
== Go... ==
 
== Go... ==
Line 102: Line 133:
 
</source>
 
</source>
  
Again, although this is very easy to follow in a general "sing-along-a-Joomla" way, there is a lot of organised paddling going on here.
+
Although this is very easy to follow, there are a lot very specific things going on here.
I have very carefully called this view "questions", plural.  This is because we are going to show the user a list of some-number-more-than-one questions.  I could have called it "questionnaire", but that's a singular thing, and Joomla is set up not only to distinguish between singular things (ie one row from a table) and multiple things (ie a list containing several rows from a table!), but also to guess the singular from the plural.  I'm fairly sure it can guess "question" from "questions", but I don't think it would get there from "questionnaire".  But we're getting ahead of ourselves.
+
I have very carefully called this view "questions", plural.  This is because we are going to show the user a list of questions.  I could have called it "questionnaire", but that's a singular thing, and Joomla is set up not only to distinguish between singular things (ie one row from a table) and multiple things (ie a list containing several rows from a table!), but also to guess the singular name from the plural name.  I'm fairly sure it can guess "question" from "questions", but I don't think it would get there from "questionnaire".  But we're getting ahead of ourselves.
  
 
In order to make our display easy, ie get Joomla to do most of the work for us, we'll define our "questions" class like this.
 
In order to make our display easy, ie get Joomla to do most of the work for us, we'll define our "questions" class like this.
  
<span id="site/models/questions.php">
+
<span id="site root/components/com_questions/models/questions.php">
'''<tt>site/models/questions.php</tt>'''
+
'''<tt><site root>/components/com_questions/models/questions.php</tt>'''
 
<source lang="php" highlight="31">
 
<source lang="php" highlight="31">
 
jimport('joomla.application.component.modellist');
 
jimport('joomla.application.component.modellist');
Line 130: Line 161:
 
return $query;
 
return $query;
 
}
 
}
</source>
+
}
 +
</source></span>
  
 
Looks simple, but again, take notice of the little details and suddenly a lot more becomes clear.
 
Looks simple, but again, take notice of the little details and suddenly a lot more becomes clear.
We're extending a class called "JModelList", a class that's specifically set up for handling result sets of multiple rows.  You'll be pleased, and unsurprised, to know there's a JModel class for single row result types, but you'll probably be able to guess a lot about that class from seeing this one.
+
We're extending a class called "JModelList", a class that's specifically set up for handling result sets of multiple rows.  You'll be pleased, and unsurprised, to know there's a JModel class for single row result types, two of them in fact, but you'll probably be able to guess a lot about them from seeing this one.
 
 
We have to import the base class (the jimport line), as usual, but this way we get a load of features specifically for this type of case.
 
  
So what's going on here?  This is the only part of a chain of actions that we need to concern ourselves with in this simple instance.  This method just defines the query object that the framework needs to select the precise pieces of data we want to see.  You can guess that we've set up a "questions" table that has a field which groups questions into individual questionnaires.  I've cheated here, our fictitious admin with too much time on his hands puts these rows into the table manually, and changes this class every day.  On other days he may select a different questionnaire number, just so we don't have to worry about how to pick one!
+
So what's going on here?  This is the only part of a chain of actions that we need to concern ourselves with in this simple instance.  This method just defines the query object that the framework needs to select the precise pieces of data we want to see.  You can guess that we've set up a "questions" table that has a field which groups questions into individual questionnaires.  I've cheated here, let's pretend our fictitious admin with too much time on his hands puts these rows into the table manually, and changes this class every day.  On other days he may select a different questionnaire number, just so we don't have to worry about how to pick one!
  
This query gets put back into the chain of actions and will return the list of questions in questionnaire "1" back to our view.  How easy is that!
+
A protected function?  Yes, it's internal to the chain of actions already in place to give us the list of questions in questionnaire "1" ready to display, and all we had to do was write one little query.  How easy is that!
  
 
[[Category:Development]]
 
[[Category:Development]]
 
[[Category:Tutorials]]
 
[[Category:Tutorials]]
 
[[Category:Joomla! 2.5]]
 
[[Category:Joomla! 2.5]]

Latest revision as of 15:22, 27 August 2012

Note

This user subpage is a work in progress being written by User:MarkRS. Please contact this user before editing it.

Component Overview[edit]

Let the Frame(work) Take The Strain Joomla 2.5

Cascading cheat sheets for the expert beginner.

The previous article in this series was Component Preamble

Ready...[edit]

The framework has set the scene, it's ready and waiting to swing into action for you, you've just got to string the right sequences together.

Steady...[edit]

To start your component Joomla looks for a file

<site root>/components/com_<component-name>/<component name>.php

This is where your component takes over. In the simplest case, Joomla already has the rigging to do most of what you want.

Your file can be as simple, and standard, as

<site root>/components/com_questions/questions.php

    // No direct access to this file
defined('_JEXEC') or die('Restricted access');
 
    // import joomla controller library
jimport('joomla.application.component.controller');
 
    // Get an instance of the controller prefixed by the component name
$controller = JController::getInstance('questions');
 
    // Perform the Request task
$controller->execute(JRequest::getCmd('task'));
 
    // Redirect if set by the controller
$controller->redirect();

The base controller class (from the third line above. You know where to find that if you've been following this series) just looks for a file called “controller.php” in the component main directory. Just to be clear, in this case that means that the controller file is

<site root>/components/com_questions/controller.php

Provided that is an instance of a controller class called QuestionsController then everything will be set for the next phase.

Of course, at the moment the URL doesn't contain "task=<something>" for the command JRequest::getCmd('task') to find, so the default setting is to display the first view of the component. What's the first view? Of course you'd guess (correctly) that the default view is "questions", nice and simple.

Go...[edit]

Well, almost go.

In fact, certainly for the front end, it may well be that you don't need to add anything at all to the existing controller class except a name of your own. Your controller class could be as simple as

defined('_JEXEC') or die('Restricted access');

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

class QuestionsController extends JController

{
}

Just an empty class definition to establish our own component controller class, but not adding anything to the base class.

Even so, there's already a bit of Joomla idiom and scaffolding going on. Clearly the class that we're subclassing here is Jcontroller, but the less obvious part is that the name of our controller class is quite important, get it right and the framework will make all sorts of correct guesses for us. The class naming convention that gives you all this extra magic is

{component name}{type name}{element name}

Our component name, without its "com_" prefix, is questions. This class is a controller and, because it's such an easy (or perhaps “simple”) thing, there's no element name in this case. By convention Joomla class names are in camel case. Php ignores case in class names. Beware, it does not do the same thing to filesystem names, the simple rule is camel-case class (&tc) names, lowercase file and directory names. No, you don't have to, but do yourself a favour and do do.

The check for _JEXEC is a really good idea for the top of every file, and the import line is fairly obvious, why use dots instead of slashes? I don't know, but it's easy to put two and two together from our previous discussion of “Jfactory” and come up with the correct supposition that jimport(some.dotted.path) imports a file <site root>/libraries/some/dotted/path.php into the current file.

Really Go[edit]

From here, the controller loads your first view, which probably gets some data out of your model, for your user to interact with.

The simplest way this happens is that you just let the controller set up its defaults so that it loads you initial view file. If you just let it do this it will assume you want a view called “questions” (it got this from the first part of its own name, “QuestionsController”, see, I told you it was a good idea).

A view? How does that work?[edit]

Like this. In short the framework tries to load a view class file, which pulls in the data it needs to show and displays it using a layout file. Easy. Of course, the framework will make a whole load of assumptions for you about how to pull that all together. If you don't give it any further clues or directives, the assumptions it makes are as follows.

It looks for the view definition file

<site root>/components/com_questions/views/questions/view.html.php

From what you know already you'd be quite happy with all of that. If you guessed that the “html” in the middle of the filename means this file is the default for a normal webpage view and you could have all sorts of different files with things like “pdf” or “rss” in the names to make different types of output, then you'd really be ahead of the game!

Anyway, let's stick with html for the moment. The bare bones of the file look like this

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

	/**
	 * HTML View class for the Questions Component front screen
	 */

class QuestionsViewQuestions extends JView
{

	function display($tpl = null)
	{
		$this->questions = $this->get('Items');

			// Display the view
		parent::display($tpl);
	}
}

JView is the base view class, and we've given our subclass of it a name matching the template I gave you above {component}{type}{element}, nice and consistent.

We load our questions and display them. Very little for us to do, with Joomla's little legs flailing along like crazy under the surface, just the way it ought to be!

The view's "get" function is a highly flexible piece of code, "getting" all manner of things. In this instance though what it's doing is getting data out of the data model, using what might appear a long winded route. However, by carefully picking the places to intervene in this pathway, Joomla does the grubby work of loading our data and we can just do the fun bit!


Load our questions? That sounds like data! Is that the “model” bit?[edit]

Yup, here comes the first part of the "model" interaction.

The view already has enough information to find the corresponding data model, if you handled your naming conventions correctly! From the name of this view, the framework will look for a file

<site root>/components/com_questions/models/questions.php

Although this is very easy to follow, there are a lot very specific things going on here. I have very carefully called this view "questions", plural. This is because we are going to show the user a list of questions. I could have called it "questionnaire", but that's a singular thing, and Joomla is set up not only to distinguish between singular things (ie one row from a table) and multiple things (ie a list containing several rows from a table!), but also to guess the singular name from the plural name. I'm fairly sure it can guess "question" from "questions", but I don't think it would get there from "questionnaire". But we're getting ahead of ourselves.

In order to make our display easy, ie get Joomla to do most of the work for us, we'll define our "questions" class like this.

<site root>/components/com_questions/models/questions.php

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

    /**
     * Questions list Model ie a questionnaire
     */
class QuestionsModelQuestions extends JModelList
{
	protected function getListQuery()
	{
		$db = $this->getDbo();
		$query = $db->getQuery(true);

			// Select the required fields from the table.
		$query->select('*');
		$query->from('#__questions_questions');

		$query->where('questionnaire_id=1');

		return $query;
	}
}

Looks simple, but again, take notice of the little details and suddenly a lot more becomes clear. We're extending a class called "JModelList", a class that's specifically set up for handling result sets of multiple rows. You'll be pleased, and unsurprised, to know there's a JModel class for single row result types, two of them in fact, but you'll probably be able to guess a lot about them from seeing this one.

So what's going on here? This is the only part of a chain of actions that we need to concern ourselves with in this simple instance. This method just defines the query object that the framework needs to select the precise pieces of data we want to see. You can guess that we've set up a "questions" table that has a field which groups questions into individual questionnaires. I've cheated here, let's pretend our fictitious admin with too much time on his hands puts these rows into the table manually, and changes this class every day. On other days he may select a different questionnaire number, just so we don't have to worry about how to pick one!

A protected function? Yes, it's internal to the chain of actions already in place to give us the list of questions in questionnaire "1" ready to display, and all we had to do was write one little query. How easy is that!