Joomla Extensions
Development Best
Practices
Francesco Abeni
GiBiLogic
extensions.gibilogic.com
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
¡Hola, mundo!
Shameless self-promotion
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Francesco
Aben...
About this speech
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
The quality of code i...
Today roadmap:
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Tools
● Files and fold...
No dev course
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Our target
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Good = not bad
Excellent = a...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
IDE basic features
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● multiple files edi...
Some IDEs
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Versioning
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
http://git-scm.com/book
Standard
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Everything in its right place
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Backend ●...
Everything in its right place
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Backend ●...
● media
○ com_componentname
■ css
■ js
■ img
● components
○ com_componentname
■ componentname.php
■ controllers
■ models
■...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
CSS / JS
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Use existing libraries
JavaScr...
CSS out of the door
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Don't:
<div>...</di...
JS out of the door
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<button id="submit" ...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Joomla framework
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● JApplication
● JData...
PHP functions and classes
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● pcre
● trim...
PHP version
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● 16. Dec 2010: PHP 5.2 end...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Real objects
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
book writer library
Bad design sample
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● views/search
● view...
The controller
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Filters input
● Decide...
The model
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Retrieves object data
● Val...
The view
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● Ask the model for data
● Dis...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Header comment
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
/**
* @version myb...
Entry point
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
defined('_JEXEC')...
Controller - part 1
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
defined('...
Controller - part 2
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
/**
* Cla...
Controller - part 3
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
public fu...
Model - part 1
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
defined('_JEXE...
Model - part 2
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
public functio...
Model - part 3
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
public functio...
Model - part 4
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
public functio...
View - part 1
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
defined('_JEXEC...
View - part 2
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
...
protected funct...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Helpers
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Common (usually static) functio...
Table classes
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Interface to and from the...
Table classes - sample code
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
<?php
class...
Layouts
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Page types related to a single ...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
System messages
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
$app = JFactory::getApp...
JError / JException / JLog
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Error handli...
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Visibility
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Variables and methods
● "var...
Constants
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● constants instead of variab...
Versioning
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
● version format: major.mino...
And the road goes on and on
Francesco Abeni for GiBiLogic
http://extensions.gibilogic.com - info@gibilogic.com
Thanks :)
f.abeni@gibilogic.com
@f_abeni / @gibilogic
http://www.slideshare.net/FrancescoAbeni/best-practices-for-joomla-e...
Upcoming SlideShare
Loading in …5
×

Best practices for Joomla extensions developers - Joomla Day 2013

2,499 views

Published on

Do you write extensions for Joomla? Do it the *right* way. You will save time and make friends amongst fellow developers (because they won't hate you when they have to read your code).

In this session we will share standards and suggestions about the best practices to adopt when you code your extensions.

Based on a true story. Our own.

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
2,499
On SlideShare
0
From Embeds
0
Number of Embeds
7
Actions
Shares
0
Downloads
38
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Best practices for Joomla extensions developers - Joomla Day 2013

  1. 1. Joomla Extensions Development Best Practices Francesco Abeni GiBiLogic extensions.gibilogic.com
  2. 2. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ¡Hola, mundo!
  3. 3. Shameless self-promotion Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Francesco Abeni sPrintAddCSSPizzaBox
  4. 4. About this speech Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com The quality of code in the Joomlasphere
  5. 5. Today roadmap: Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Tools ● Files and folders ● Reuse software ● MVC ● Other tips ● Conclusions Feedback please!
  6. 6. No dev course Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  7. 7. Our target Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Good = not bad Excellent = above the average Good is enough for today
  8. 8. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  9. 9. IDE basic features Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● multiple files edit ● syntax highlighting ● index for methods and variables ● autocompletion ● autoformatting ● compiler ● versioning / unit testing / phpdoc / ...
  10. 10. Some IDEs Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  11. 11. Versioning Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com http://git-scm.com/book
  12. 12. Standard Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  13. 13. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  14. 14. Everything in its right place Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Backend ● administrator ○ components ■ com_componentname ● componentname.xml ● componentname.php ● controllers ● models ● views
  15. 15. Everything in its right place Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Backend ● administrator ○ components ■ com_componentname ● ... ● config.xml ● install.php ● sql ● tables ● helpers
  16. 16. ● media ○ com_componentname ■ css ■ js ■ img ● components ○ com_componentname ■ componentname.php ■ controllers ■ models ■ views Everything in its right place Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Frontend ● images ○ com_componentname
  17. 17. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  18. 18. CSS / JS Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Use existing libraries JavaScript ● MooTools (since Joomla 1.5) ● JQuery (since Joomla 2.5) CSS + JavaScript ● Bootstrap (since Joomla 3.x) P.S. got conflicts? Use JQueryEasy plugin.
  19. 19. CSS out of the door Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Don't: <div>...</div> <br style="clear: both"> <div style="height: 200px">...</div> Do: <link rel=”stylesheet” href=”/media/componentname/styles.css”> ... <div class=”clearfix”>...</div> <div class="fixedheight">...</div> .clearfix { … } .fixedheight { height: 200px }
  20. 20. JS out of the door Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <button id="submit" type=submit" value="ClickMe!" onclick="validateForm()" /> Do: <script src=”/media/componentname/js/script.js”> <button id="submit" type=submit" value="ClickMe!"/> document.addEvent('load',function(){ $('submit').addEvent('click',function(){ validateForm(); }); }); Don't:
  21. 21. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  22. 22. Joomla framework Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● JApplication ● JDatabase ● JUser ● JSession ● JDocument ● JHTML ● JForm ● JConfig ● JUri ● JFile ● JFolder ● JLog ● JFilterInput ● JError and JException ● JDate ● JUtilities ● JVersion ● JLayout
  23. 23. PHP functions and classes Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● pcre ● trim ● usort ● array_map ● array_unique ● json_encode ● json_decode ● microtime(true) ● glob ● curl ● DateTime ● Standard PHP Library ● Exception ● SimpleXML ● TCPDF ● PHPMailer
  24. 24. PHP version Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● 16. Dec 2010: PHP 5.2 end of life ● 11. Jul 2013: PHP 5.3 end of life ● 01. Mar 2012: PHP 5.4 released ● 20 Jun 2013: PHP 5.5 released ● PHP 5.4 is 40% faster than PHP 5.2
  25. 25. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  26. 26. Real objects Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com book writer library
  27. 27. Bad design sample Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● views/search ● views/editbook ● views/book ● views/books ● views/booksauthor ● views/topten Don't:
  28. 28. The controller Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Filters input ● Decides what to do ● Checks access permissions ● Executes task(s) ● Optionally, calls the view
  29. 29. The model Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Retrieves object data ● Validates object data ● Gets object data ● Saves object data ● Hates to be mistaken as an helper
  30. 30. The view Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● Ask the model for data ● Display object(s) ● Uses layouts!
  31. 31. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  32. 32. Header comment Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php /** * @version mybooks.php 2013-08-10 15:23:00Z zanardi * @package GiBi MyBooks * @author GiBiLogic * @authorUrl http://www.gibilogic.com * @authorEmail info@gibilogic.com * @copyright Copyright (C) 2013 GiBiLogic. All rights reserved. * @license GNU/GPL v2 or later * @description Backend entry point */
  33. 33. Entry point Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... defined('_JEXEC') or die(); jimport('joomla.application.component.controller'); $view = JFactory::getApplication()->input->get('view', 'book'); $task = JFactory::getApplication()->input->get('task', 'index'); JFactory::getApplication()->input->set('task', "$view.$task"); $controller = JController::getInstance('MyBooks'); $controller->execute($task); $controller->redirect();
  34. 34. Controller - part 1 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... defined('_JEXEC') or die('The way is shut!'); jimport('joomla.application.component.controlleradmin'); /** * MyBooksControllerBook class. * * @see JControllerAdmin */ class MyBooksControllerBook extends JControllerAdmin { /** * Controller's view. * * @var JView */ private $view; ...
  35. 35. Controller - part 2 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... /** * 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($this->getModel('Editor', 'MyBooksModel'), false); } ...
  36. 36. Controller - part 3 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... public function index() { $this->view->setLayout('index') $this->view->display(); } public function create() { $this->view->setLayout('create'); $this->view->display(); } public function save() { $data = JFactory::getApplication()->input->get('jform', null); if (!$data || !$this->model->validate($data)) { $msg = 'Invalid data!'; $type = 'error'; $this->setRedirect('index.php?option=com_mybooks&view=book&task=create', $msg, $type); return false; }
  37. 37. Model - part 1 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... defined('_JEXEC') or die('The way is shut!'); jimport('joomla.application.component.model'); jimport('joomla.html.pagination'); class MybooksModelBook extends JModel { private $table = '#__mybooks_book'; public function __construct($config = array()) { parent::__construct($config); $app = JFactory::getApplication(); $limit = $app->getUserStateFromRequest('global.list.limit', 'limit', $app- >getCfg('list_limit'), 'int'); $limitstart = $app->input->get('limitstart', 0, '', 'int'); $this->setState('limit', $limit); $this->setState('limitstart', $limitstart); $this->setState('author_id', $app->getUserStateFromRequest('com_mybooks.filters. author_id', 'author_id', 0, 'int')); }
  38. 38. Model - part 2 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... 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 = '$author_id'”)- >orderby('created_at DESC'); $this->_db->setQuery($query,0,1); return $this->_db->loadObject(); }
  39. 39. Model - part 3 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... public function create($data) { if (!$data) { return 0; } $data['created_at'] = date('Y-m-d H:i:s'); $query = $this->_db->getQuery(true); $query->insert($this->table)->columns(array_keys($data))->values(sprintf("'%s'", implode("','", array_values($data)))); $this->_db->setQuery($query); return false === $this->_db->execute() ? 0 : $this->_db->insertid(); } ...
  40. 40. Model - part 4 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... public function delete($ids) { $query = $this->_db->getQuery(true); $query->delete()->from($this->table)->where('id IN '.implode(',', $ids)); return false !== $this->_db->execute(); } public function getPagination(){ return new JPagination( $this->_getListCount($this->buildQuery()), $this->getState('limitstart'), $this->getState('limit') ); } private function buildQuery(){ $where = $this->buildWhere(); $query = $this->_db->getQuery(true); return $query->select('*')->from($this->table)->where($where)->orderby ('created_at DESC'); } ...
  41. 41. View - part 1 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... defined('_JEXEC') or die('The way is shut!'); 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); }
  42. 42. View - part 2 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php ... protected function addToolbar($tpl){ $methodName = 'addToolBar' . ucfirst(!$tpl ? 'default' : $tpl); $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 addToolBarCreate(){ JToolBarHelper::title(JText::_('COM_MYBOOKS') . ': ' . JText::_ ('COM_MYBOOKS_BOOK_NEW')); JToolBarHelper::apply('save'); JToolBarHelper::divider(); JToolBarHelper::back('JTOOLBAR_BACK', 'index.php?option=com_mybooks'); } }
  43. 43. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  44. 44. Helpers Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Common (usually static) functions not related to a specific object ● Get date / time / external info ● Format date and numbers ● Build title and/or other HTML snippets ● Log/error management ● Handle CURL connections
  45. 45. Table classes Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Interface to and from the database Active Record pattern ● Define table name and unique id ● load, store, delete, and so on
  46. 46. Table classes - sample code Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com <?php class TableBook extends JTable { public function __construct(&$db) { parent::__construct(‘#__books’, ‘id’, $db); } }
  47. 47. Layouts Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Page types related to a single view (object) "tmpl" subfolder (template override) ● List ● Single item (readonly) ● Single item (edit form) ● Blog ● ...
  48. 48. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  49. 49. System messages Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com $app = JFactory::getApplication(); $app->enqueueMessage( $msg, $type )
  50. 50. JError / JException / JLog Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Error handling vs. logging ● JError is deprecated ● JException is deprecated ● Use PHP Exception class(es) ● JLog is a way to track what's happening
  51. 51. Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  52. 52. Visibility Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Variables and methods ● "var ..." is deprecated since PHP 5.1.2 ● public : available from other classes ● private : available only from the class ● protected : available from the class and from inherited or parent classes
  53. 53. Constants Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● constants instead of variables ● drop DS ● drop DIRECTORY_SEPARATOR ● use Joomla constants: http://docs.joomla.org/Constants ● warning: JPATH_SITE vs JPATH_BASE vs JPATH_ROOT vs JPATH_ADMINISTRATOR
  54. 54. Versioning Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com ● version format: major.minor.release (es. v3.1.5) ● variant: v3.1.5 Free, v3.1.5 Pro
  55. 55. And the road goes on and on Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com
  56. 56. Thanks :) f.abeni@gibilogic.com @f_abeni / @gibilogic http://www.slideshare.net/FrancescoAbeni/best-practices-for-joomla-extensions-developers-25353320 Francesco Abeni for GiBiLogic http://extensions.gibilogic.com - info@gibilogic.com Feedback please!

×