Difference between revisions of "Development Best Practices"

From Joomla! Documentation

(Several markup changes. URL corrections.)
 
(7 intermediate revisions by 5 users not shown)
Line 1: Line 1:
{{page|needs improvement|It is severely outdated and needs a major revision.}}
+
<noinclude><languages /></noinclude> <translate>
 +
<!--T:1-->
 +
Here are a collection of the Joomla! Development practices you should observe when developing a component, plugin or module for Joomla.
  
== General Development Guidelines ==
+
== General Development Guidelines == <!--T:2-->
  
* Don't use the DS or DIRECTORY_SEPARATOR 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]
+
<!--T:3-->
* 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 use the ''DS'' or ''DIRECTORY_SEPARATOR'' constant when including files. It is no longer needed, as pointed out by [https://www.php.net/manual/en/ref.filesystem.php#73954 Christian on php.net]
* 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 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 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 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 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 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.
 
* 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:
 +
<syntaxhighlight lang="sql">
 +
// Good
 +
#__foobar_something
  
* 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 #__foobar_something (good) instead of #__fbr_something (bad) or even #__something (really bad).
+
<!--T:4-->
* 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.
+
// Bad
 +
#__fbr_something
 +
 
 +
<!--T:5-->
 +
// Really Bad!
 +
#__something
 +
</syntaxhighlight>
 +
* Do test your extensions with pre-release versions of Joomla! and the ''staging'' branch of the Git repository. Assuring 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 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 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 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.
 
* 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? ==
+
== Where Should I Place JavaScript, CSS, and Image Files That Belong to My Component? == <!--T:6-->
 
You can see in your root a general media folder to hold all assets.
 
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
+
<!--T:7-->
 +
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.
+
<!--T:8-->
 +
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 the 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.
+
<!--T:9-->
 +
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 [https://api.joomla.org/cms-3/classes/Joomla.CMS.HTML.HTMLHelper.html#method_image image], [https://api.joomla.org/cms-3/classes/Joomla.CMS.HTML.HTMLHelper.html#method_script script], and [https://api.joomla.org/cms-3/classes/Joomla.CMS.HTML.HTMLHelper.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.
  
== Where should I place files generated by my Component? ==
+
<!--T:10-->
 +
You can read more about this simple best practice of using the media folder for your extension media in this [https://www.babdev.com/blog/139-use-the-media-folder-allow-overridable-media blog post]
 +
 
 +
== Where Should I Place Files Generated by My Component? == <!--T:11-->
 
It depends on the nature of these files. There are two decisive factors:
 
It depends on the nature of these files. There are two decisive factors:
  
 +
<!--T:12-->
 
* 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 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.
+
* 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 '''need not''' be able to be accessed over the web.
  
 +
<!--T:13-->
 
This gives us the following possibilities:
 
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 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"?
 
* 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 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.
+
* 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 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.
+
* 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.
+
<!--T:14-->
 +
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.
+
<!--T:15-->
 +
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 ==
+
== Considerations for JavaScript == <!--T:16-->
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:
+
When you are using ''addScriptDeclaration'' to add inline JavaScript in a Joomla! page you have to be 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 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 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 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.
+
* 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:
+
<!--T:17-->
* 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.
+
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).
 
* 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).
 
+
</translate>
 
[[Category:Development]]
 
[[Category:Development]]
 
[[Category:JavaScript]]
 
[[Category:JavaScript]]

Latest revision as of 17:54, 12 October 2022

Other languages:
Deutsch • ‎English • ‎中文(台灣)‎

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

General Development Guidelines[edit]

  • 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 the staging branch of the Git repository. Assuring 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?[edit]

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 the 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.

You can read more about this simple best practice of using the media folder for your extension media in this blog post

Where Should I Place Files Generated by My Component?[edit]

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 need not 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[edit]

When you are using addScriptDeclaration to add inline JavaScript in a Joomla! page you have to be 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).