Académique Documents
Professionnel Documents
Culture Documents
developers
A collection of basic tips for anyone who writes Joomla extensions (or plans to do it shortly)
Written by Francesco Abeni
Published by GiBiLogic
(https://extensions.gibilogic.com)
A call to action
Joomla developers: the time has come for a global quality improvement of the Joomla extensions code. So, if you
develop extensions (or you're thinking about doing it) please read on. All the world will be grateful sooner or later.
In this long book, you will learn a lots of basic tips about how to get the most out of your development time: I will
tell you about all the good practices that I've come to learn by myself or picking from fellow Joomla devs. Those
practices will speed up your coding and/or let you produce a better result, so you win in any case.
A disclaimer. Coding is the art of solving problems by creative thinking, and if you cannot do that, I cannot teach
you anything. In other words, this article is for developers. If you have never coded in your life, you should read other
books / articles first.
And another disclaimer: most of these best practices are written and tested on Joomla 2.5, which is still where I do
most of my development work. There are a few slight changes for Joomla 3.x and this book will be updated in the near
future to reflect them.
This book is organized as a series of steps, from the most basic (get a decent editor) to the most complex (do real
object-oriented programming, please). At each step you will find links to look for if something is not clear. So the pace
at which you will read the article will be determined by your own level of knowledge. Experienced developers will go
through it in a breeze, picking some suggestions here and there. Beginners may have to stop more frequently to learn
something more about the tools / techniques referenced in the article.
Feedback
In any place, if you find mistakes or if you disagree with my suggestions, please let me know. You can contact me:
via e-mail at f.abeni@gibilogic.com
via Twitter at @f_abeni
I will be happy to receive any kind of feedback and discuss it with you, so that future versions of this book may be
updated if I feel I have learned something new.
Summary
As I mentioned before, we're going through a series of well defined steps, starting from the basics. You may have
already dealt with some of the proposed topics, and have nothing more to learn: in that case you can just skip that step
or possibly read it very quickly just to confirm you're not missing anything.
Here's the topics we're going to talk about:
PART 1: prepare your environment
use a good IDE
use a good versioning tool
use standards
learn
PART 2: everything in its right place
the files
css and javascript for your extension
the joomla framework
PART 3: MVC
what MVC is really about
MVC sample code
other useful files in your MVC component
PART 4: other tips
basic error management
naming conventions
comments
documentation
smaller extensions
shared libraries
about version numbers
Conclusions
wins hands down for the development style needed when working on a Joomla extension.
Git it's incredibly easy: you can install a Git client like SmartGit or TortoiseGit or even the command line (if you're
comfortable with it) and be up and running in no time. At the same time, it will become incredibly powerful once you
get comfortable with it.
If you use Git you will surely want to have a look at GitHub (github.com), an online service which lets you create
remote, web-based Git repositories. It's free up to 5 repos and they have commercial plans for more repos and
advanced features. GitHub is really handy if you want to:
share your work and accept contributions
cooperate from the start with other developers
have a central repo so you can work from different workstations
have a backup copy of your work
Nowadays many Joomla related projects, and the Joomla core code itself, are hosted on GitHub. The interesting
thing is that you can comment and follow other developers work, so it all makes for a more social coding.
If you like to read a good book about it, look at the free Pro Git Book (http://git-scm.com/book) written by one of
GitHub co-founders.
Use standards
You're not alone, even when you think you are: your code may be read by others for several reasons. They may
want to change something for their own needs, or change something and contribute back, or just want to evaluate how
good you are as a developer. By making your code easier to read, you are making the life of these people easier, and
they will be grateful.
Also, don't forget that there is always at least one other person: it's yourself, two years in the future, that will swear
back at you because he/she is having a hard time fixing a bug or implementing a new feature and cannot understand
what the hell did you meant when you write that piece of ugly and unreadable code.
So the golden rule here is: use a standard whatever it is. We'll come back later to naming conventions,
indentations, and so on, and give you some suggestions, but the basic line is: choose one standard, possibly from the
Joomla guidelines (http://developer.joomla.org/5-policies/3-Joomla-Coding-Standards.html), and stick to it for all your
projects. You will make a lot of people happier, including yourself.
Learn
All topics mentioned so far are one-time tasks: you choose a good IDE and a good versioning tool, and you're done;
you set a standard and start to use it, and won't ever come back to it. But there is a task which never ends, and it's
learning.
There are lots of places: you can attend conferences, browse forums, read books, watch videos, or - even better look at the code from other extensions. A good developer always tries to improve!
You should be able to look back at what you did just one year ago and think how much better is your code now.
That is a good sign.
Joomla and Joomla extensions are moving forward all the time. You should be prepared to keep a steady
improvement pace, or your work will be obsolete very soon.
That is not so difficult as it sound: mainly it's about accepting that you'll have to change and learn new things. Once
you've entered into the right attitude, it will come quite natural.
Assets
Assets are all those additional static files that your component may need. The most common types of assets are
stylesheets, javascripts, and images. I've seen them put in so many different places that it made my eyes fill with tears.
First of all, don't put them all in one single folder but separate them in three folders called css, img a n d js
respectively. These names are short and easily recognizable, and they've become a widely used standard so it's a good
choice: forget any other names like styles, scripts, images, and so on.
After that, you have to decide where to put those folders. You have two acceptable options:
an assets folder in the frontend of your component
For example, /components/com_componentname/assets/. Please note that I said "in the frontend". We strongly
suggest to have all assets in the frontend, even when you use them in the backend pages.
a com_componentname (or mod_modulename, and so on) folder in the media main folder
For example, /media/com_componentname.
The second option (using the media folder) is definitely my preferred way to handle it; that way, all medias for all
extensions are easy to find and located in a single place.
You may also decide to have a set of assets shared between several extensions; in that I would still suggest to put it
in the media folder with a common name, for example /media/gibilogic/.
Images
7
External stylesheets
When coding the layouts of your component, you should not have any kind of style information mixed in your
HTML code: put it in external CSS files instead. In the layout, use HTML classes and ids, and let the CSS stylesheets do
all the rest. This is true even for small, innocent styles like
<br style=clear: both />
Anyone who's using your extension should not be forced to do a template override just because you put some inline
style which is breaking the overall layout. For web designers and integrators, applying an additional CSS rule to change
the style is way easier than write a template override of the whole layout.
This kind of development also comes handy if you want to provide some kind of theming framework for your
extensions, i.e. provide different skins for your extension. It's much easier to provide a different set of CSS files instead
of different PHP files, so when you change the logic of your component you don't need to modify different files.
So: no inline styles in your HTML, all styles go in a different stylesheet file.
Unobtrusive JavaScript
Since JavaScript entered the web many years ago, we've all got used to seeing it used inline with additional tag
attributes like onclick, onsubmit, and so on.
But what we said about CSS stands true for JavaScript as well: that is hard to change and require a template override
even for very small changes. The best way to go is to use unobtrusive JavaScript.
To simplify as much as possible, the term unobtrusive JavaScript refers to the good practice of applying such
events at at runtime by using the document.onload command.
An example will make it very clear. Instead of writing:
<button id="submit"
type=submit"
value="ClickMe!"
onclick="validateForm()" />
and then assign the event at runtime, as below (this is a sample in jQuery style, but you can do that with many
different libraries and even with JavaScript core commands):
jQuery(document).ready(function($){
$('submit').click(function(){
validateForm();
});
});
If you're not comfortable with jQuery, the above code basically listens for the document (the whole page) to be
ready; when that happens, a listener is attached to the HTML element with id "submit", so that some other JavaScript
code will be run when that element is clicked.
For a very simple example like this, of course, the new code seems uselessly bigger and more complex than the
original one. One can wonder what's the good in that. But:
keeping all the JavaScript logic in one place simplify the debug (especially for other people)
it is much easier for other to change that behaviour with some additional JavaScript, without changing the
original file
as soon as your JavaScript does slightly more than that, you will see that being able to attach / detach / fire
JavaScript events without the need to modify your HTML code is a big bonus.
Of course, all the JavaScript code should be placed in a separate JS file and not just above the HTML code in your
layout.
Joomla framework
In this context, a framework is intended as a set of libraries and classes that take care of common tasks, so you don't
have to rewrite them from scratch.
If you're an extension developer, you will surely have heard about the Joomla framework. This is an intermediate
layer between the PHP native code and your application, that gives you several advantages:
you have to write less code to do the same tasks
you may write simpler code, because the framework handles most of the complexity
you can also have extended options in comparison to core PHP methods / classes
As a very simple example, I guess all of you use the JDatabase class: this Joomla class makes it very easy to access
any table in your Joomla db to get and write data. There are many JDatabase methods and that offers you a lot of
flexibility and security (for example the Quote and nameQuote methods) without the need for you to take care of it.
Much in the same way, there are many other classes that can help you deal with things in such a simple,
straightforward way. Just to mention a few:
JFactory is a factory class to access most objects in the framework
JApplication read and controls the whole Joomla application (either frontend or backend)
JUser access the current user or any other existing user and get any related information; it can also help you
create / modify a user from your code
JSession quickly get and set session data
JDocument is a very neat tool to deal with your page, e.g. to add stylesheets and scripts to the head of the
page
JHtml offers many methods to quickly build HTML elements
JLog makes your debugging much easier because you can write down what's happening
JFilterInput analyze and sanitize your input
JDate is very helpful in handling dates and timezones
JFolder and JFile can access and check your filesystem objects
JUri deals with URLs and current site information
JVersion gets info about the current Joomla version
There are even more, this is just a short list of the most commonly used.
By using these classes you can get info or run a task with a couple of lines of code. If you don't use them, you are
wasting in your time in writing code that's already there, usually better and safer than yours because it's been reviewed
by many and fixed along the way.
10
PHP 5.2 has reached its end of life 16. Dec 2010
PHP 5.3 has reached its end of life 11. Jul 2013
PHP 5.4 has been released 1. Mar 2012
PHP 5.5 has been released 20. Jun 2013
Each new version brings new features and significant performance improvement, so you should always encourage
yourself, your colleague and customers to keep their hosts updated to later PHP releases.
Keeping a little backward-compatibility with previous versions of PHP it's not difficult since, as we stated before,
PHP changes quite slowly - but should not become your main focus. Try to code for current stable release, and use the
new features when you can.
11
Part 3. MVC
What MVC is really about
A few pages ago I suggested you to check a tutorial about creating an MVC component
(http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Introduction) . I hope you read it or
anyway that you are able to create at least a very basic component with a Model, a Viev and a Controller. If you do,
you are using MVC (Model - View - Controller) design pattern as any decent Joomla component does.
Basically, a design pattern is a standard way to structure your code; but that is only the beginning.
Object-oriented programming
On top of the suggested tutorial, you may find many others about building a Joomla component. Also some books
have been written about that topic. Some of them are quite good in explaining the relationships between models, views
and controllers, my favourite being the one by Joseph Le Blanc that uses an interesting analogy with restaurants.
But now that I have learned a lot more event from outside Joomla I can defnitely say that none of those tutorials
and books put enough attention on an important fact: MVC is based on object-oriented programming, and if you want
to use it effectively you should be thinking carefully about your objects.
Models, views and controllers are not independent. Usually they go in triplets: you have one model, one view and
one controller strictly related to each other. In your component, several of these MVC triplets may exist; but each one
of them should handle a specific object.
If in your component you have MVC triplets named like "list", "update", "editsite", "search", you are definitely on
the wrong path and you should read carefully the next section.
What is an object?
An object is... well, a thing: a resource, something. Definitely not an action. So if your site is about books, you'll
have to think about objects like book, author, editor. For each object you may have a display task (single or list) a
search task, an add and/or edit task, and so on. As I said just a little while ago, each object will have its own MVC
triplet: its controller, its model and its view. There are exceptions to this, but they are... well, exceptions :-).
Please note the important difference: book is a decent object, editbook is not. Don't mix objects with tasks. You
don't have to create a new MVC triplet for any new page you need on your site.
For example, if you want your component to display a new page with the 10 most sold books, you should not create
a votedbooks MVC, but add a new task and layout to your existing book MVC object.
Now that we have cleared the air a bit about objects, let's focus on how the MVC should really work.
Dispatcher
In the overview of the component structure (part 2) I said there is no global controller and that each object has its
own controller. But we still need to choose what object has been requested, so that we can call the appropriate
controller. This part of code is called dispatcher and in my component it's usually included in the entry point
(componentname.php).
Controller
The controller is often under-rated, while it's probably the most important part of your component. Here the most
important decisions and actions happen. Amongst other things, the controller:
filters the input
decides what task has been called and if it's a valid task
checks if the user is allowed to do that
optionally, calls the model to do some process or get some data
switches the control to the relevant view
12
Too many times, while looking at some extension code, I have seen only very basic code in the controller, while the
corresponding model and view are overstuffed with auth checks and processing logic. By moving more code into the
controller, which is the first step in the process, you will make yourself a big favour because your processing logic will
run early and will not be mixed up with data access and display stuff.
The model
The model is a very focused character. You may think of it as a librarian. It is not usually concerned with the overall
picture: he just gets the requested data and returns it. It relies on the controller to know what data should be taken and if
the user is allowed to get such data, so it just goes on with it and returns the requested data.
You can correctly deduce that the model is the place for the queries: in fact, all the SQL in your components should
be in your models, and nowhere else.
The view
The view should take care of the display part, so it should not have any input processing o r sql query. Compared
with other frameworks, in Joomla the view is a bit more powerful, and takes care of some tasks that should really be
handled by the controller. For example, in Joomla the view iself calls the model to get the data; in other framework, the
controller does that and passed data to the view, which just shows them. Anyway, this is how it works with Joomla so
let's stick with it.
It's important to understand that a single view can handle different types of page, by a combination of different
methods and different layouts (the files in the tmpl subfolder). In a single view class you may have for example a
displayItem and displayList methods, that request different data and load different layouts.
13
I left the initial header comment on purpose: i suggest to always include some meta info about the file. I use and
recommend to use the standard PHPDoc format, which you can then parse with existing tools.
Browsing the code you can see that, after the basic _JEXEC check, the code:
includes the base controller class
gets view and task info from the request and convert them into a full task in the format object.task
loads the relevant controller, executes the task and redirects to the final page.
An important note here. Using the view parameter to define which object we want is a common convention in
Joomla components, but we may have passed a controller parameter instead, or just a full task in the object.task
format. That convention is a reminiscence of the single controller way, which I don't use anyway. In fact, we are not
calling directly any view: we use that parameter just to know which controller to pass the control to, or in other words
to do the dispatching.
If your component grows complex, you may have here in the entry point some additional initialization code, for
example you may want to include additional JS / CSS libraries or just common classes you have developed for your
component. For a simple component, though, the above code will be enough.
The controller
In the following code you may see a sample controller; you will have a controller for each object that your
component handles. This time I removed the initial header comment to keep the code listing short, but I left some
comments above each method to show you additional PHPDoc keywords.
Listing 2: book controller
<?php
defined('_JEXEC') or die();
jimport('joomla.application.component.controlleradmin');
/**
* MyBooksControllerBook class.
*
* @see JControllerAdmin
*/
class MyBooksControllerBook extends JControllerAdmin
{
/**
* Controller's view.
*
* @var JView
*/
private $view;
/**
* Class constructor.
*
* @param type $config
*/
public function __construct($config = array())
{
parent::__construct($config);
$this->model = $this->getModel();
$this->view = $this->getView(
JFactory::getApplication()->input
->get('view', 'book'), 'html'
);
$this->view->setModel(
$this->model, true
);
$this->view->setModel(
$this->getModel(
'Author', 'MyBooksModel'
), false
);
$this->view->setModel(
14
$this->getModel(
'Editor', 'MyBooksModel'
), false
);
}
public function display()
{
$this->view->display();
}
public function index()
{
$this->view->setLayout('index');
$this->view->display();
}
public function edit()
{
$this->view->setLayout('edit')
$this->view->display();
}
public function add()
{
$this->view->setLayout('edit')
$this->view->display();
}
public function save()
{
$data = JFactory::getApplication()->input
->get('jform', null);
$url = JRoute::_(
'index.php?option=com_mybooks&view=book'
);
if (!$data || !$this->model->validate($data))
{
$this->setRedirect(
$url, 'Invalid data!', 'error'
);
return false;
}
if (!$this->model->save($data))
{
$this->setRedirect(
$url, 'Error while saving!, 'error'
);
return false;
}
$this->setRedirect($url, 'Saved ok!');
}
private function getModel($name = 'Book', $prefix = 'MyBooksModel', $config = array())
{
return parent::getModel($name, $prefix, $config);
}
}
This is still a simple controller, but you can already see some meaningful code. For example, in the __construct
method I get several different models and assign them to the view, so it will be able to get data about different objects.
This is an important distinction, because each model should take care of one object and one object only. For example,
if in your book view you want to get additional data about the author, do not create a getAuthorData method in the
book model; you can and should request those data directly to the author model.
The model
This time I removed all comments to make it even shorter.
Listing 3: book model
<?php
defined('_JEXEC') or die();
15
jimport('joomla.application.component.model');
jimport('joomla.html.pagination');
class MybooksModelBook extends JModel
{
private $table = '#__mybooks_book';
private $app;
public function __construct($config = array())
{
parent::__construct($config);
$this->app = JFactory::getApplication();
$limit = $this->app->getUserStateFromRequest(
'global.list.limit',
'limit',
$app->getCfg('list_limit'),
'int'
);
$limitstart = $this->app->input->get(
'limitstart',
0,
'',
'int'
);
$this->setState('limit', $limit);
$this->setState('limitstart', $limitstart);
$this->setState(
'author_id',
$this->app->getUserStateFromRequest(
'com_mybooks.filters.author_id',
'author_id',
0,
'int'
)
);
}
public function getList()
{
return $this->_getList(
$this->buildQuery(),
$this->getState('limitstart'),
$this->getState('limit')
);
}
public function getLast()
{
$query = $this->_db->getQuery(true);
$query->select('*')
->from($this->table)
->orderby('created_at DESC');
$this->_db->setQuery($query,0,1);
$results = $this->_db->loadObjectList('id');
return $results ? $results : array();
}
public function getLastByAuthor($author_id)
{
$query = $this->_db->getQuery(true);
$query->select('*')
->from($this->table)
->where('author_id='.$id)
->orderby('created_at DESC');
$this->_db->setQuery($query,0,1);
return $this->_db->loadObject();
}
public function save($data)
{
if (!$data)
{
return 0;
}
16
This is not meant to be complete; a few other methods may be present. There are many more things that you can do
with the data (for example reorder them) so the model often ends up as the longest class. What you see above is just a
sample of the the kind of code you should put in a model.
You may have noticed that I use the JDatabaseQuery object to build my queries. For several reason that's way better
than to build your query by yourself as a string; I strongly suggest you to try it so you will see for yourself.
The view
Listing 4: book view
<?php
defined('_JEXEC') or die();
17
jimport('joomla.application.component.view');
class MyBooksViewBook extends JView
{
public function display($tpl = null)
{
$this->pagination = $this->getModel()
->getPagination();
$this->filter_author_id = $this->getModel()
->getState('author_id');
$this->books = $this->getModel()->findAll();
$this->authors = $this->getModel('Authors')
->getList();
$this->editors = $this->getModel('Editors')
->getList();
$this->addToolbar($tpl);
parent::display($tpl);
}
protected function addToolbar($tpl)
{
$methodName = 'addToolBar';
if ($tpl)
{
$methodName .= ucfirst($tpl);
}
else
{
$methodName .= 'Default';
}
$this->{$methodName}();
}
private function addToolBarDefault()
{
JToolBarHelper::title(
JText::_('COM_MYBOOKS') . ': ' .
JText::_('COM_MYBOOKS_BOOK_LIST'));
JToolBarHelper::addNew('create');
JToolBarHelper::preferences('com_mybooks');
JToolBarHelper::divider();
JToolBarHelper::deleteList(
'COM_MYBOOKS_BOOK_LIST_DELETE_CONFIRM',
'delete');
}
private function addToolBarAdd()
{
JToolBarHelper::title(
JText::_('COM_MYBOOKS') . ': ' .
JText::_('COM_MYBOOKS_BOOK_NEW'));
JToolBarHelper::apply('save');
JToolBarHelper::divider();
JToolBarHelper::back(
'JTOOLBAR_BACK',
'index.php?option=com_mybooks');
}
}
Nothing much to say; here you can see the view getting data from different models, and preparing different pages
in this case only a different toolbar - according to the selected template.
Helpers
If you've put into practice everything that you read so far in this article, you should now be using correct objectoriented code. Amongst other things, that means that any model in your component is related to a specific object and
all its methods apply to that object and to that object only.
What comes from this is that if you want to build a generic-purpose method, for example getCurrentDate or
18
formatCurrency, the model is not the better place for it. If the method does not apply to a specific object, you don't
have any model to put it into. Here is where helpers come to... well, help.
An helper is a class with some generic methods which can be used in several parts of your component. In most of
the cases, a single helper for your component may be enough; for complex components, you may have additional
helpers, each of one takes care of a specific group of tasks. It's not unusual to see an helper specifically dedicated to
handling images (uploading, fetching, resizing and so on).
This is the kind of helper you may write:
class mybooksHelper
{
public function getCurrentDate() {
// some code here
}
public function formatCurrency($value) {
// some code here
}
}
You will place this code in a file called mybooks.php into the helpers subfolder of your component. You can then
call it from any view with the following code:
$this->loadHelper('mybooks')
$helper = new mybooksHelper();
$this->date = $helper->getCurrentDate();
Table classes
The table class in Joomla is an hybrid object. It is mainly an implementation of the ActiveRecord pattern, but with
some additional responsabilities. Anyway, this is not really important: the important thing is that you do use table and
relieve your model of one of its burden.
Basically, the table class will act as a bridge between your application and a defined record in the database, which
can also a be a new record.
Listing 5: book table class
<?php
class TableBook extends JTable
{
function __construct(&$db)
{
parent::__construct( '#__books', 'id', $db );
}
}
The file containing this code should be named as the class name without the "Table" prefix, and all lowercase: in the
above example, it would be book.php inside the tables subfolder in the backend of your component:
/administrator/components/com_componentname/tables/book.php.
Starting from Joomla 2.5, the object will automatically get the fields from the database table and expose them as its
own properties. In previous versions, you had to define each of the individual fields.
After instancing a table class object, you will be able to create, read, update and delete a record without building
any query.
Views layouts
Layouts are those files that you can see in the tmpl subfolder of any view, and represent the different possible
display for your data.
In a correct MVC you have a single view.html.php file for each object. As I said before, the view acts a bit like a
sub-controller: you get data, build lists, and do other "data-preparation" stuff, but don't put any HTML in it. Instead, the
HTML code is placed into the layouts file.
19
20
Very simple, huh? You basically open a logger on a custom file and them you write in it whatever you need.
JError and JException
JError and JException are still widely used for more complex error management: they allows you, amongst other
things, to set HTTP errors status codes. But these classes have been deprecated and will be removed from next versions
of Joomla.
Since this book is about best practices, I won't put in it things that I haven't tried extensively. So currently I have no
suggestions about how the best way to replace those classes. As soon as a new standard comes up in the Joomla world,
I will definitely update this book.
Meanwhile, you may want to get some info about the PHP core classes to handle exceptions.
21
Naming conventions
As part of using a good coding standard, you'd better never underestimate the importance of names in your code.
Picking the right name for a variable or a method can be extremely useful later on, when you have to understand what a
given piece of code is meant to do. It only takes a few more seconds to think of a good name. Think carefully about
what a variable actually contains, and about what a method actually do: the choice of the name should come quite
easy.
Some examples from our experience:
avoid abbreviations: use $version instead of $ver, or $joomla_version instead of $jVer
use prefix to differentiate and clarify: use $previous_items, $retrieved_items, $saved_items in different part
of your code instead of just $items all the time
avoid similar names for different meanings: don't use $site_url and url when the second variable refers to
something more specific, for example the URL for your component; use $my_component_url instead
stick to a standard for separating words: a safe choice is to use camelCase for methods name and
$under_score for variable names. The coding standards for Joomla (see link at the end of the article) include
more info about this topic.
With a well chosen naming, your code will almost automatically explains itself. And that brings us to the topic of
comments.
Comments
An important consequence of a good naming convention is that the number of comments you have to put in your
code should drastically drop. Let us have an important distinction here.
There are header comments, placed at the top of a file or just before a class or a method.
This is an excellent way to document your code at the same time that you're writing it. Such comments are
also used to automate stuff, for example you can give test informations about the method, and so on. Thus, they
are encouraged, as long as you follow a standard like phpDoc.
Then there are inline comments, placed in the middle of your code.
These have to be used more carefully. They should not be an alibi for a bad written code: if you're code is so
ugly that you cannot understand what it does except with a comment above, you should consider improving your
code in the first place.
Also, do not write useless comments. The following comment is definitely not needed, since the code is quite
obvious and you're just wasting space in your source code:
// getting old items from database
$old_items = getPreviousItems();
So basically:
use header comments
do your best to avoid using inline comments
if you have to, spend a little time in making sure they're clear and useful
Documentation
If you followed carefully until here, you already wrote some documentation without even knowing it: with phpDoc
blocks, you wrote info about variables and methods that can be then parsed to build automatically a quick reference on
your code. That, and a good naming convention, are still the best way to document your code since any developer will
be able to understand most of it.
22
Of course you may still need to write some additional documentation after that. The amount of can change greatly
depending on how many people are going to use your tool, and what level of development knowledge they got. You
may have just a little README.txt in your root folder, or a 100 page manual; that's up to you.
But be sure to document at least any custom requirement / procedure needed to make your software work. If your
software needs additional libraries, or custom settings in Joomla, or if there are known bugs on certain conditions, you
have to write it down. Do that immediately, as an additional paragraph in your @description header, or as a separate
README.txt.
It's never too early to write this kind documentation: if the bugs you describe are fixed later on, it's quite easy to
delete a paragraph.
Smaller extensions
Another important step to make your time more effective is to build smaller extensions.
If you're going to build an extension that does a lot of things, it's always a good idea to split it into a set of smaller
extensions, for example by putting most interchangeable options into plugins (think of payment methods). This not
only reduce the complexity of the code, but also allows you to reuse some of it for other projects.
As an example, lately we had to create a system for users to edit a document online and generate a PDF from the
resulting text. The main task could be splitted into several sub-features:
allow the user to edit the document
allow the administrator to see a summary of the inserted fields
allow both the users and the administrator to generate a PDF from the resulting document
So we decided to create three different extensions:
a content plugin that makes only some part of an article editable (basically creating a set of fields)
a backend component that handle those fields
another component that takes each article and its fields and creates a PDF
Each of this part is easily reusable, for example, the dynamic editing of articles can also be used on its own.
Try to move out of the main component each feature that is not a core feature and/or that is isolated enough to make
sense even as a stand-alone feature. Since you're at it, make it as generic as possible so you will quickly reuse it later
on.
Shared libraries
If it makes sense to create smaller extensions that has specific purposes, it makes even more sense to keep out of
your component external libraries.
I already told you that you should search for existing libraries both for Joomla and PHP. For example, in the same
project that we talked about a few lines above we had to use a PDF library. We choosed TCPDF since we are quite
familiar with it.
This excellent library was included in Joomla 1.5 but it's not in Joomla 2.5. Browsing through the Joomla
Extensions Directory (JED), we were able to find an extension that packages the TCPDF library into a Joomla library,
so we went for it. If it hadn't existed, we would have created the package ourselves, because it just doesn't make sense
to include it in our main component package.
This way, we can keep our package small and don't need to update it in case a new version of TCPDF comes out:
we just have to suggest to update the related package.
Do not package everything inside your component: make use of existing libraries and, if necessary, create
additional Joomla packages to be able to easily install more libraries.
23
seen different formats to define the version, but the most used and suggested is a triplet of numbers X.Y.Z, where X, Y
and Z are defined as follows:
the first is the major version: it's changed only when a significant change has been made to the overall
features or structure of the software (think about Joomla 2.x vs Joomla 3.x)
the second is the minor version: it's changed everytime one or more new features or minor changes are
introduced
the third is the release: it's usually changed at each release of the code, and often it only includes bug and
security fixes
You should try to use them for what they really mean, and not just randomly. To use an example dear to us all, the
difference between Joomla 1.0 and Joomla 1.5 was more than enough - in our opinion - to require a major version
change. In that case, Joomla 1.5 should have really been called Joomla 2.0.
Another important thing to remember, the three numbers are not mathematically related. I've seen people switch to
2.0 because they've reached 1.9 and loved too much the decimal system to think differently; but the truth is that you
can have 1.10, 1.11, and so on. It's perfectly allowed and in fact suggested. Unless of course you want to change
version only for marketing reasons (like most of the browser do).
Apart from versions, you may also have variants. The word "variant" is just my own term to define a different
flavour for a software. Most known example: the "Free" or "Pro" different packages for an extension. While version
number imply an historical evolution (one version comes after another), this is a different distinction so I don't like to
call them versions. This is especially true since most extensions developers keep all their different packages (variants)
at the same version. For example, when our own GiBi AddCSS 3.6.0 will be released, it's guaranteed that GiBi AddCSS
Pro 3.6.0 will also be released.
There are some who fix the variant issue by treating them as different extensions, and append the Pro suffix to the
extension name. That's not what I like. If I had to decide, the variant field should become an additional field in the
Joomla installer and updater. The lack of it is what pushed some of the most known Joomla extensions developers to
drop the Joomla Core updater system and roll out their own.
Joomla version
Now that we know about version number, let's see how we can use this knowledge when dealing with Joomla
version. You already know that there is a JVersion class that will quickly tell you which Joomla version you're on.
Since the third digit refers to changes which are usually very minor and don't break backwards compatibility, most
of the time we only care about the first two digits. In other words, almost always you want to know if you're on Joomla
2.5 or 3.0, you don't - usually - care if it's 2.5.10 or 2.5.11.
The property you're looking for is "RELEASE", as in
$jversion = new JVersion();
echo $jversion->RELEASE;
This internally uses the "version_compare" PHP operator to tell you if the current version is equal or newer than the
one you're comparing it to.
24
Conclusions
Well, we've seen a few things, haven't we? And this is just the start.
I hope that by reading this book you will avoid all those little traps that beginners encounter while starting to
develop Joomla extensions. Or, if you're already an experienced developer, maybe you have finally found the answer
to some doubt that had been nagging you all along.
As I have noted before the best amongst the best practices is the one called Learn. By reading books, attending
conferences and studying the work of others you will always continue to improve yourself, your time, and your code,
and that is something you must never stop doing.
Updates
I hope to update and complete this book with additional informations, so keep an eye on
http://extensions.gibilogic.com/blog.html or follow @GiBiLogic on Twitter to know when a new version is released.
Contacts
I would love to get any kind of feedback on this book. So if you have requests, critics, suggestions, you can reach
me:
via e-mail at f.abeni@gibilogic.com
via Twitter at @f_abeni
Thank you and have fun coding!
25
http://extensions.gibilogic.com
GiBiLogic extensions site
http://www.joomla.org
Joomla site
http://extensions.joomla.org
the Joomla Extensions Directory
https://netbeans.org
NetBeans site
https://github.org
GitHub site
http://developer.joomla.org/5-policies/3-Joomla-Coding-Standards.html
Coding standards for Joomla
http://docs.joomla.org/Developing_a_Model-View-Controller_Component/2.5/Introduction
tutorial about how to write an MVC component in Joomla
http://extensions.joomla.org/extensions/core-enhancements/performance/jquery-scripts/18327
JQuery Easy plugin
26