Actions

Difference between revisions of "Development Best Practices"

From Joomla! Documentation

m (Minor spelling)
m (General Development Guidelines: some style)
 
(16 intermediate revisions by 5 users not shown)
Line 1: Line 1:
== Where should I place JavaScript files that belong to my Component? ==
+
Here are a collection of the Joomla! Development practices you should observe when developing a component, plugin or module for Joomla.
  
Information in response to the question:
+
== General Development Guidelines ==
In com_media, we have an asset folder contains js files; however, is it the proper place for the javascript files for future component development?
+
  
The idea was that the asset folder would hold any component asset that would need to be reachable directly by the client. For example, css, img, javascript etc. Initially this was just done to separate them.
+
* Don't use the <code>DS</code> or <code>DIRECTORY_SEPARATOR</code> constant when including files. It is no longer needed, as pointed out by [http://us2.php.net/manual/en/ref.filesystem.php#73954 Christian on php.net]
 +
* Don't depend on <code>register_globals</code>. This is a HIGH security risk, and the feature has been deprecated in PHP 5.3 and removed in 5.4.
 +
* Don't access the <code>$_GET, $_POST, $_REQUEST, $_FILES and $_SERVER</code> superglobals directly. Use <code>JInput</code> (typically: <code>JFactory::getApplication()->input)</code> instead. <code>JInput</code> filters the input, helping you to easily write more secure software.
 +
* Don't hardcode your SQL queries and do not include unescaped raw data into them. Always use <code>JDatabase</code> / <code>JDatabaseQuery</code>. It's as simple as <code>JFactory::getDbo()->getQuery(true)</code>.
 +
* Don't use arbitrary entry points, i.e. .php files which must be accessible outside Joomla!, directly from the web. Typically used to accommodate for payment processors and image resizers, this practice is extremely insecure and strongly discouraged. Use a Joomla! component or a system plugin instead.
 +
* Don't reinvent the wheel. If there's a Joomla! class to do that try using it before you roll your own. Chances are the core class is already good enough and much better tested.
 +
* Do use sensible prefixes for your table names. If your component is called '''com_foobar''' it stands to reason that its tables follow the naming pattern:{{-}}
 +
<source lang="sql" style="margin-left:3em;">
 +
// Good
 +
#__foobar_something
  
Later on in the development of 1.5 we create a general media folder to all assets. At the moment this folder only holds the none-BC system
+
// Bad
assets. The idea was that the installer would push component specific assets in this folder during the installation process.
+
  #__fbr_something
  
In JInstaller around line 780 we see the following in the parseMedia() method:
+
  //Really Bad!
 
+
  #__something
<source lang="php">
+
/*
+
  * Here we set the folder we are going to copy the files to.
+
*    Default 'media' Files are copied to the JPATH_BASE/images folder
+
  */
+
$folder = ($element->attributes('destination')) ? DS.$element->attributes('destination') : null;
+
$destination = JPath::clean(JPATH_ROOT.DS.'media'.$folder);
+
 
</source>
 
</source>
 +
* Do test your extensions with pre-release versions of Joomla! and/or the "staging" branch of the Git repository. Making sure that users of your extension can update Joomla! safely is your responsibility.
 +
* Do provide documentation for your extensions. Even a short video with less than stellar English is better than nothing.
 +
* Do use <code>JText</code> to translate the output of your extension instead of hardcoding text. The vast majority of Joomla! users are not native English speakers and they will thank you for your consideration.
 +
* Do comment your code. Not just for the people who have to work with it, but also yourself six months from now.
 +
* Do test your code under real usage conditions, with real world data sets. You might be surprised at what you find.
 +
 +
== Where should I place JavaScript, CSS, and Image files that belong to my Component? ==
 +
You can see in your root a general media folder to hold all assets.
 +
 +
What this means in real terms is that when in your XML install manifest, if you put files inside a <media> tag instead of a <files> tag then they will be sent to the JPATH_ROOT/media folder.  If you give it <media destination="com_foo"> then it will put the files in JPATH_ROOT/media/com_foo
 +
 +
In some cases you have a component, we'll say com_foo, and then you have a few modules that go along with com_foo... for sake of the example we'll call them mod_foo_1, mod_foo_2 and mod_foo_3.  There is no reason to package media elements for the three modules if they are all the same and they depend upon the component anyway.  The best and most logical way to do things is to put them all in a central place that is namespaced appropriately.
 +
 +
By storing media in the media folder, this enables templates to override it with template overrides versus being required to modify the files shipped with your extension, causing those customizations to be lost during updates.  By loading your media using the [http://api.joomla.org/cms-3/classes/JHtml.html#method_image image], [http://api.joomla.org/cms-3/classes/JHtml.html#method_script script], and [http://api.joomla.org/cms-3/classes/JHtml.html#method_stylesheet stylesheet] methods in the JHtml class instead of loading the media directly with JDocument or hard coded tags, this enables easy overrides of your extension's media so that its output can be customized to the site it is used on.  See [http://www.babdev.com/blog/139-use-the-media-folder-allow-overridable-media this blog post] for more details.
 +
 +
== Where should I place files generated by my Component? ==
 +
It depends on the nature of these files. There are two decisive factors:
 +
 +
* The permanence of the file: temporary, cache or permanent. Temporary files are files which are supposed to be removed immediately after use, before the page load completes. Cache files will be stored on the server for a while, at most until their expiration date. Both temporary and cache files can be deleted without prior warning and your code must anticipate that. Permanent files, on the other hand, are not meant to be removed automatically.
 +
* The disposition of the file: web accessible or web inaccessible. The web accessible files are those which MUST be able to be accessed over the web, e.g. when you type their URL in a web browser. The web inaccessible files are those which NEEDN'T be able to be accessed over the web.
 +
 +
This gives us the following possibilities:
 +
* Temporary, web inaccessible. Use Joomla!'s temp-directory. You can get it by doing JFactory::getConfig()->get('tmp_path'). Hardcoding the path as JPATH_ROOT . '/tmp' is a bad practice and you must not do it.
 +
* Temporary, web accessible. That's not acceptable! Temporary files are by definition inaccessible from the web. Maybe you really meant "cache" instead of "temporary"?
 +
* Cache, web inaccessible. Use the defined Joomla! cache directory. Use the JPATH_CACHE constant to find its location. Please note that the cache directory may be different in the front-end and back-end of your site.
 +
* Cache, web accessible. Use a subdirectory of the media folder. See the section about Javascript and CSS files, it's the same thing.
 +
* Permanent, web inaccessible. Use a folder under your extension's main directory. If you really want the files to be completely inaccessible from the web remember to place a .htaccess file or, better yet, give your users the option to use a directory outside the site's root.
 +
* Permanent, web accessible. Use a subdirectory of the media folder. See the section about Javascript and CSS files, it's the same thing.
  
What this means in real terms is that when in your xml install manifest, if you put files insite a <media> tag instead of a <files> tag then they will be sent to the JPATH_ROOT/media folder. If you give it <media destination="com_foo"> then it will put the files in JPATH_ROOT/media/com_foo
+
This applies to all files handled by your Component, including files your code generates and files the users of your component upload / generate.
  
In some cases you have a component, we'll say com_foo, and then you have a few modules that go along with com_foo... for sake of the example we'll call them mod_foo_1, mod_foo_2 and mod_foo_3.  There is no reason to package media elements for the three modules if they are all the same and they depend upon the component anyway.  The best and most logical way to do things is to put them all in a central place that is namespaced appropriately.  
+
Finally, if you want to manage log files you are advised to use the JLog class instead of rolling your own solution.
  
Doing it this way gives us the ability to start taking all of the media assets out of our code folders and get us to a point where we could really move all the PHP files underneath the document root. It is a first step toward that end.
+
== Considerations for Javascript ==
 +
When you are using addScriptDeclaration to add inline Javascript in a Joomla! page you have to be very considerate about your code's interaction with other Javascript from other extensions running on the same page. Good practices include:
 +
* Do terminate your Javascript with a semicolon and a newline. If both are missing, your code is the source of Javascript errors as soon as another developer's code uses addScriptDeclaration after your code.
 +
* Do make sure your Javascript code is valid and doesn't throw errors. Errors in your code will render any code after it inoperable.
 +
* Do use try/catch blocks for risky code. If you are unsure if some code is risky just surround it with a try/catch block anyway.
 +
* Do load your inline Javascript in the view template, not the view class (view.html.php file). Most likely it depends on the DOM which will be different when a site integrator uses a template override.
  
For the original discussion, see [http://groups.google.com/group/joomla-devel/browse_thread/thread/49c457b9305e1379 Joomla! Developer Discussion List].
+
Other good practices concerning Javascript code in your extensions includes:
 +
* Don't modify core Javascript objects including jQuery, mooTools and everything in the Joomla Javascript object. If you want to modify a core object, subclass. If you are not sure, subclass.
 +
* Do not meddle with other developers' code. This includes moving script tags to the bottom of the page or forcibly removing script tags (e.g. removing any script tag whose source URL includes the strong "jq" – you know for whom the bell tolls).
  
 
[[Category:Development]]
 
[[Category:Development]]
 +
[[Category:JavaScript]]

Latest revision as of 07:26, 12 October 2014

Here are a collection of the Joomla! Development practices you should observe when developing a component, plugin or module for Joomla.

Contents

General Development Guidelines

  • Don't use the DS or DIRECTORY_SEPARATOR constant when including files. It is no longer needed, as pointed out by Christian on php.net
  • Don't depend on register_globals. This is a HIGH security risk, and the feature has been deprecated in PHP 5.3 and removed in 5.4.
  • Don't access the $_GET, $_POST, $_REQUEST, $_FILES and $_SERVER superglobals directly. Use JInput (typically: JFactory::getApplication()->input) instead. JInput filters the input, helping you to easily write more secure software.
  • Don't hardcode your SQL queries and do not include unescaped raw data into them. Always use JDatabase / JDatabaseQuery. It's as simple as JFactory::getDbo()->getQuery(true).
  • Don't use arbitrary entry points, i.e. .php files which must be accessible outside Joomla!, directly from the web. Typically used to accommodate for payment processors and image resizers, this practice is extremely insecure and strongly discouraged. Use a Joomla! component or a system plugin instead.
  • Don't reinvent the wheel. If there's a Joomla! class to do that try using it before you roll your own. Chances are the core class is already good enough and much better tested.
  • Do use sensible prefixes for your table names. If your component is called com_foobar it stands to reason that its tables follow the naming pattern:
 // Good
 #__foobar_something
 
 // Bad
 #__fbr_something 
 
 //Really Bad!
 #__something
  • Do test your extensions with pre-release versions of Joomla! and/or the "staging" branch of the Git repository. Making sure that users of your extension can update Joomla! safely is your responsibility.
  • Do provide documentation for your extensions. Even a short video with less than stellar English is better than nothing.
  • Do use JText to translate the output of your extension instead of hardcoding text. The vast majority of Joomla! users are not native English speakers and they will thank you for your consideration.
  • Do comment your code. Not just for the people who have to work with it, but also yourself six months from now.
  • Do test your code under real usage conditions, with real world data sets. You might be surprised at what you find.

Where should I place JavaScript, CSS, and Image files that belong to my Component?

You can see in your root a general media folder to hold all assets.

What this means in real terms is that when in your XML install manifest, if you put files inside a <media> tag instead of a <files> tag then they will be sent to the JPATH_ROOT/media folder. If you give it <media destination="com_foo"> then it will put the files in JPATH_ROOT/media/com_foo

In some cases you have a component, we'll say com_foo, and then you have a few modules that go along with com_foo... for sake of the example we'll call them mod_foo_1, mod_foo_2 and mod_foo_3. There is no reason to package media elements for the three modules if they are all the same and they depend upon the component anyway. The best and most logical way to do things is to put them all in a central place that is namespaced appropriately.

By storing media in the media folder, this enables templates to override it with template overrides versus being required to modify the files shipped with your extension, causing those customizations to be lost during updates. By loading your media using the image, script, and stylesheet methods in the JHtml class instead of loading the media directly with JDocument or hard coded tags, this enables easy overrides of your extension's media so that its output can be customized to the site it is used on. See this blog post for more details.

Where should I place files generated by my Component?

It depends on the nature of these files. There are two decisive factors:

  • The permanence of the file: temporary, cache or permanent. Temporary files are files which are supposed to be removed immediately after use, before the page load completes. Cache files will be stored on the server for a while, at most until their expiration date. Both temporary and cache files can be deleted without prior warning and your code must anticipate that. Permanent files, on the other hand, are not meant to be removed automatically.
  • The disposition of the file: web accessible or web inaccessible. The web accessible files are those which MUST be able to be accessed over the web, e.g. when you type their URL in a web browser. The web inaccessible files are those which NEEDN'T be able to be accessed over the web.

This gives us the following possibilities:

  • Temporary, web inaccessible. Use Joomla!'s temp-directory. You can get it by doing JFactory::getConfig()->get('tmp_path'). Hardcoding the path as JPATH_ROOT . '/tmp' is a bad practice and you must not do it.
  • Temporary, web accessible. That's not acceptable! Temporary files are by definition inaccessible from the web. Maybe you really meant "cache" instead of "temporary"?
  • Cache, web inaccessible. Use the defined Joomla! cache directory. Use the JPATH_CACHE constant to find its location. Please note that the cache directory may be different in the front-end and back-end of your site.
  • Cache, web accessible. Use a subdirectory of the media folder. See the section about Javascript and CSS files, it's the same thing.
  • Permanent, web inaccessible. Use a folder under your extension's main directory. If you really want the files to be completely inaccessible from the web remember to place a .htaccess file or, better yet, give your users the option to use a directory outside the site's root.
  • Permanent, web accessible. Use a subdirectory of the media folder. See the section about Javascript and CSS files, it's the same thing.

This applies to all files handled by your Component, including files your code generates and files the users of your component upload / generate.

Finally, if you want to manage log files you are advised to use the JLog class instead of rolling your own solution.

Considerations for Javascript

When you are using addScriptDeclaration to add inline Javascript in a Joomla! page you have to be very considerate about your code's interaction with other Javascript from other extensions running on the same page. Good practices include:

  • Do terminate your Javascript with a semicolon and a newline. If both are missing, your code is the source of Javascript errors as soon as another developer's code uses addScriptDeclaration after your code.
  • Do make sure your Javascript code is valid and doesn't throw errors. Errors in your code will render any code after it inoperable.
  • Do use try/catch blocks for risky code. If you are unsure if some code is risky just surround it with a try/catch block anyway.
  • Do load your inline Javascript in the view template, not the view class (view.html.php file). Most likely it depends on the DOM which will be different when a site integrator uses a template override.

Other good practices concerning Javascript code in your extensions includes:

  • Don't modify core Javascript objects including jQuery, mooTools and everything in the Joomla Javascript object. If you want to modify a core object, subclass. If you are not sure, subclass.
  • Do not meddle with other developers' code. This includes moving script tags to the bottom of the page or forcibly removing script tags (e.g. removing any script tag whose source URL includes the strong "jq" – you know for whom the bell tolls).