<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Creuzerm</id>
	<title>Joomla! Documentation - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://docs.sandbox.joomla.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Creuzerm"/>
	<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/Special:Contributions/Creuzerm"/>
	<updated>2026-06-18T00:48:29Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Making_single_installation_packages_for_Joomla!_1.5_and_2.5_series&amp;diff=63295</id>
		<title>Making single installation packages for Joomla! 1.5 and 2.5 series</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Making_single_installation_packages_for_Joomla!_1.5_and_2.5_series&amp;diff=63295"/>
		<updated>2011-11-29T20:25:27Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: /* Obsolte code */  Spelling correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
&lt;br /&gt;
It is possible to create a single installation package which can install a component in Joomla! 1.5, 1.6 and 1.7 with minor changes. Below you will find some of the most common tricks required to create an extension which is compatible with all current versions of the Joomla! CMS.&lt;br /&gt;
&lt;br /&gt;
== Dealing with API changes ==&lt;br /&gt;
You will regularly bump into cases where an API has changed between Joomla! 1.5, 1.6 and 1.7. In order to cater for them, you need to run slightly different code based on the Joomla! version. Right now it&#039;s possible to do that by writing conditional statements like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if(version_compare(JVERSION,&#039;1.7.0&#039;,&#039;ge&#039;)) {&lt;br /&gt;
// Joomla! 1.7 code here&lt;br /&gt;
} elseif(version_compare(JVERSION,&#039;1.6.0&#039;,&#039;ge&#039;)) {&lt;br /&gt;
// Joomla! 1.6 code here&lt;br /&gt;
} else {&lt;br /&gt;
// Joomla! 1.5 code here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you do not have Joomla! 1.7-specific code -i.e it is the same as the Joomla! 1.6-specific code- please use the following code:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if(version_compare(JVERSION,&#039;1.6.0&#039;,&#039;ge&#039;)) {&lt;br /&gt;
// Joomla! 1.6 code here&lt;br /&gt;
} else {&lt;br /&gt;
// Joomla! 1.5 code here&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While this conditional statement looks like an overkill, it has two major advantages:&lt;br /&gt;
* Compatibility with all Joomla! versions using the same package, therefore using the same codebase, ergo less maintenance overhead&lt;br /&gt;
* Once, let&#039;s say, Joomla! 1.8 is released and you decide to drop support for earlier Joomla! releases, we can just search your code for &amp;quot;if(version_compare(JVERSION,&amp;quot; and remove all of the legacy code.&lt;br /&gt;
&lt;br /&gt;
== One XML configuration file, multiple Joomla! versions ==&lt;br /&gt;
&lt;br /&gt;
Various XML files in Joomla! accept settings, or parameters. For example your extension manifest file, the config.xml file and the view XML files all accept such settings. You may have noticed that whereas in Joomla! 1.5 these were found under the &amp;lt;params&amp;gt; tags, in Joomla! 1.6 and later they are found inside &amp;lt;filedsets&amp;gt;. One hidden secret of Joomla! is that Joomla! 1.5 will ignore Joomla! 1.6 syntax, whereas Joomla! 1.6/1.7 will ignore Joomla! 1.5 syntax. This allows you to have a single XML file which caters for all Joomla! releases. For example, here&#039;s a sample config.xml file, to be placed in the component&#039;s backend directory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;config&amp;gt;&lt;br /&gt;
	&amp;lt;!-- Joomla! 1.5 uses params --&amp;gt;&lt;br /&gt;
	&amp;lt;params&amp;gt;&lt;br /&gt;
		&amp;lt;param name=&amp;quot;foobar&amp;quot; type=&amp;quot;text&amp;quot; default=&amp;quot;&amp;quot; size=&amp;quot;30&amp;quot;&lt;br /&gt;
			label=&amp;quot;COM_FOOBAR_OPTION_FOOBAR_LBL&amp;quot;&lt;br /&gt;
			description =&amp;quot;COM_FOOBAR_OPTION_FOOBAR_DESC&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/params&amp;gt;&lt;br /&gt;
&lt;br /&gt;
	&amp;lt;!-- Joomla! 1.6 uses fieldset --&amp;gt;&lt;br /&gt;
	&amp;lt;fieldset&lt;br /&gt;
		name=&amp;quot;basic&amp;quot;&lt;br /&gt;
		label=&amp;quot;COM_FOOBAR_OPTIONS_SECTION_BASIC_LBL&amp;quot;&lt;br /&gt;
		description=&amp;quot;COM_FOOBAR_OPTIONS_SECTION_BASIC_DESC&amp;quot;&lt;br /&gt;
		&amp;gt;&lt;br /&gt;
		&amp;lt;field name=&amp;quot;foobar&amp;quot; type=&amp;quot;text&amp;quot; default=&amp;quot;&amp;quot; size=&amp;quot;30&amp;quot;&lt;br /&gt;
			label=&amp;quot;COM_FOOBAR_OPTION_FOOBAR_LBL&amp;quot;&lt;br /&gt;
			description =&amp;quot;COM_FOOBAR_OPTION_FOOBAR_DESC&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/fieldset&amp;gt;&lt;br /&gt;
&amp;lt;/config&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That&#039;s how easy it is!&lt;br /&gt;
&lt;br /&gt;
== Dealing with languages ==&lt;br /&gt;
&lt;br /&gt;
=== How to load component-local translation files in Joomla! 1.5 ===&lt;br /&gt;
&lt;br /&gt;
Joomla! 1.6 introduced a new feature where a user can place language files inside the component&#039;s directory, e.g. administrator/com_foobar/language/en-GB/en-GB.com_foobar.ini, in order to provide language overrides. But Joomla! 1.5 doesn&#039;t support this feature. Or does it? Even though it can not do that automatically, you can do so in your extension&#039;s dispatcher file, e.g. administrator/com_foobar/foobar.php. Here&#039;s the magic code to do that in the backend:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$jlang =&amp;amp; JFactory::getLanguage();&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_ADMINISTRATOR, null, true);&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_COMPONENT_ADMINISTRATOR, null, true);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
and the frontend:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$jlang =&amp;amp; JFactory::getLanguage();&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_SITE, null, true);&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_COMPONENT, null, true);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tips and tricks for language strings ===&lt;br /&gt;
&lt;br /&gt;
All your translation keys should consist of uppercase characters without spaces (that is A-Z, 0-9 and underscores). All translation values should be included in double quotation marks. This allows the translation files to be parsed by Joomla! 1.5/1.6/1.7 alike. You are also suggested to prefix your translation keys with the extension&#039;s name, albeit this is not required. For example, this is a good translation string:&lt;br /&gt;
COM_FOOBAR_CPANEL_TITLE=&amp;quot;Foobar Control Panel&amp;quot;&lt;br /&gt;
whereas this is a &#039;&#039;&#039;bad&#039;&#039;&#039; translation string:&lt;br /&gt;
CONTROL PANEL=Foobar Control Panel&lt;br /&gt;
The former works with all current versions of Joomla!, the latter doesn&#039;t.&lt;br /&gt;
&lt;br /&gt;
If you have double quotation marks in your translation values, please replace them with single quotation marks. While Joomla! 1.5 allowed escaping the double quotation marks with \&amp;quot;, Joomla! 1.6 under newer versions of PHP don&#039;t and require you to escape them as &amp;quot;__QQ__&amp;quot; which throws off Joomla! 1.5&#039;s parser. The workaround is to take advantage of a little known fact about HTML, that attributes can be wrapped in single quotation marks. For instance, change this:&lt;br /&gt;
COM_FOOBAR_SOME_KEY=&amp;lt;a href=&amp;quot;http://www.example.com&amp;quot;&amp;gt;Just a test&amp;lt;/a&amp;gt;&lt;br /&gt;
to this:&lt;br /&gt;
COM_FOOBAR_SOME_KEY=&amp;quot;&amp;lt;a href=&#039;http://www.example.com&#039;&amp;gt;Just a test&amp;lt;/a&amp;gt;&amp;quot;&lt;br /&gt;
It is valid HTML, it works on Joomla! 1.5/1.6/1.7 but it will invalidates XHTML. You can&#039;t always win, sorry.&lt;br /&gt;
&lt;br /&gt;
=== Making untranslated strings look more beautiful ===&lt;br /&gt;
&lt;br /&gt;
The problem with using tight translation keys as we described is that untranslated strings now look something like COM_FOOBAR_VIEWNAME_SOMEKEY. If you have volunteer translators you can bet your head that most translations will not be in sync with your component and you will have untranslated strings. In Joomla! 1.5, using &amp;quot;natural language&amp;quot; keys, you got to show your users the default (English) text if a translation key didn&#039;t exist in their language. This is impossible in Joomla! 1.6... or maybe not?&lt;br /&gt;
&lt;br /&gt;
We can use the same little trick in our component&#039;s dispatcher as with our component-local translation loading string above. Here&#039;s how to load the English translation file in the backend of your component, then overwrite only the keys which exist with the user&#039;s selected language, essentially allowing untranslated keys to show in English:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$jlang =&amp;amp; JFactory::getLanguage();&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_ADMINISTRATOR, &#039;en-GB&#039;, true);&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_ADMINISTRATOR, null, true);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The same thing in the front-end:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$jlang =&amp;amp; JFactory::getLanguage();&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_SITE, &#039;en-GB&#039;, true);&lt;br /&gt;
$jlang-&amp;gt;load(&#039;com_foobar&#039;, JPATH_SITE, null, true);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== JElement vs JFormField ==&lt;br /&gt;
&lt;br /&gt;
Oh, the struggle! You need a custom widget in the configuration section of your component. In Joomla! 1.5 you could just create a new JElement. In Joomla! 1.6 you could just create a new JFormField. But both? In a single file? You can employ a simple trick. In the following example I am going to create a rather lame element, called SQL2, which displays a multi-selection box out of the results of a SQL statement. This is made as part of a fictitious module called mod_foobar&lt;br /&gt;
&lt;br /&gt;
First, let your configuration know where to load the custom widget files from, by putting this in your module&#039;s XML manifest file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;params addpath=&amp;quot;/modules/mod_foobar/elements&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;param name=&amp;quot;ids&amp;quot; type=&amp;quot;sql2&amp;quot; default=&amp;quot;&amp;quot;&lt;br /&gt;
			label=&amp;quot;MOD_FOOBAR_LEVELS_TITLE&amp;quot;&lt;br /&gt;
			description=&amp;quot;MOD_FOOBAR_LEVELS_DESC&amp;quot;&lt;br /&gt;
			query=&amp;quot;SELECT `foobar_level_id`, `title` FROM `#__foobar_levels`&amp;quot;&lt;br /&gt;
			key_field=&amp;quot;foobar_level_id&amp;quot;&lt;br /&gt;
			value_field=&amp;quot;title&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/params&amp;gt;&lt;br /&gt;
	&lt;br /&gt;
	&amp;lt;config addfieldpath=&amp;quot;/modules/mod_foobar/elements&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;fields name=&amp;quot;params&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;fieldset name=&amp;quot;basic&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;field name=&amp;quot;ids&amp;quot; type=&amp;quot;sql2&amp;quot; default=&amp;quot;&amp;quot;&lt;br /&gt;
					label=&amp;quot;MOD_FOOBAR_LEVELS_TITLE&amp;quot;&lt;br /&gt;
					description=&amp;quot;MOD_FOOBAR_LEVELS_DESC&amp;quot;&lt;br /&gt;
					query=&amp;quot;SELECT `foobar_level_id`, `title` FROM `#__foobar_levels`&amp;quot;&lt;br /&gt;
					key_field=&amp;quot;foobar_level_id&amp;quot;&lt;br /&gt;
					value_field=&amp;quot;title&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;/fieldset&amp;gt;&lt;br /&gt;
		&amp;lt;/fields&amp;gt;&lt;br /&gt;
	&amp;lt;/config&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As you see, we instruct both Joomla! 1.5 and 1.6/1.7 to look into the same directory, for the same-named file (sql2.php). Here are the contents of the modules/mod_foobar/elements/sql2.php file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die(&#039;Restricted Access&#039;);&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * This trick allows us to extend the correct class, based on whether it&#039;s Joomla! 1.5 or 1.6&lt;br /&gt;
 */&lt;br /&gt;
if(!class_exists(&#039;JFakeElementBase&#039;)) {&lt;br /&gt;
        if(version_compare(JVERSION,&#039;1.6.0&#039;,&#039;ge&#039;)) {&lt;br /&gt;
                class JFakeElementBase extends JFormField {&lt;br /&gt;
                        // This line is required to keep Joomla! 1.6/1.7 from complaining&lt;br /&gt;
                        public function getInput() {}&lt;br /&gt;
                }               &lt;br /&gt;
        } else {&lt;br /&gt;
                class JFakeElementBase extends JElement {}&lt;br /&gt;
        }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Our main element class, creating a multi-select list out of an SQL statement&lt;br /&gt;
 */&lt;br /&gt;
class JFakeElementSQL2 extends JFakeElementBase&lt;br /&gt;
{&lt;br /&gt;
	var	$_name = &#039;SQL2&#039;;&lt;br /&gt;
&lt;br /&gt;
	// Joomla! 1.5&lt;br /&gt;
	function fetchElement($name, $value, &amp;amp;$node, $control_name)&lt;br /&gt;
	{&lt;br /&gt;
		$db			= &amp;amp; JFactory::getDBO();&lt;br /&gt;
		$db-&amp;gt;setQuery($node-&amp;gt;attributes(&#039;query&#039;));&lt;br /&gt;
		$key = ($node-&amp;gt;attributes(&#039;key_field&#039;) ? $node-&amp;gt;attributes(&#039;key_field&#039;) : &#039;value&#039;);&lt;br /&gt;
		$val = ($node-&amp;gt;attributes(&#039;value_field&#039;) ? $node-&amp;gt;attributes(&#039;value_field&#039;) : $name);&lt;br /&gt;
		return JHTML::_(&#039;select.genericlist&#039;,  $db-&amp;gt;loadObjectList(), &#039;&#039;.$control_name.&#039;[&#039;.$name.&#039;][]&#039;, &#039;class=&amp;quot;inputbox&amp;quot; multiple=&amp;quot;multiple&amp;quot; size=&amp;quot;5&amp;quot;&#039;, $key, $val, $value, $control_name.$name);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	// Joomla! 1.6&lt;br /&gt;
	function getInput()&lt;br /&gt;
	{&lt;br /&gt;
		$db			= &amp;amp; JFactory::getDBO();&lt;br /&gt;
		$db-&amp;gt;setQuery($this-&amp;gt;element[&#039;query&#039;]);&lt;br /&gt;
		$key = ($this-&amp;gt;element[&#039;key_field&#039;] ? $this-&amp;gt;element[&#039;key_field&#039;] : &#039;value&#039;);&lt;br /&gt;
		$val = ($this-&amp;gt;element[&#039;value_field&#039;] ? $this-&amp;gt;element[&#039;value_field&#039;] : $this-&amp;gt;name);&lt;br /&gt;
		return JHTML::_(&#039;select.genericlist&#039;,  $db-&amp;gt;loadObjectList(), $this-&amp;gt;name, &#039;class=&amp;quot;inputbox&amp;quot; multiple=&amp;quot;multiple&amp;quot; size=&amp;quot;5&amp;quot;&#039;, $key, $val, $this-&amp;gt;value, $this-&amp;gt;id);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 * Part two of our trick; we define the proper element name, depending on whether it&#039;s Joomla! 1.5 or 1.6&lt;br /&gt;
 */&lt;br /&gt;
if(version_compare(JVERSION,&#039;1.6.0&#039;,&#039;ge&#039;)) {&lt;br /&gt;
        class JFormFieldSQL2 extends JFakeElementSQL2 {}&lt;br /&gt;
} else {&lt;br /&gt;
        class JElementSQL2 extends JFakeElementSQL2 {}                &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Considering that most custom widgets have a lot more code than this, you can create two different initialisation sections for Joomla! 1.5 and 1.6/1.7 (fetchElement and getInput), populate class variables, then call a big, common method to render the bulk of the widget (just like we did with JHTML&#039;s genericlist in the example above). This will eliminate the need to rewrite the same code over again just to cater for a new Joomla! version.&lt;br /&gt;
&lt;br /&gt;
== Obsolete code ==&lt;br /&gt;
&lt;br /&gt;
Joomla 1.6 / 1.7 have been left any code obsolete, we should review code for do compatible with all versions.&lt;br /&gt;
=== Global Mainframe ===&lt;br /&gt;
Bad: &amp;lt;source&amp;gt;global $mainframe;&amp;lt;/source&amp;gt;&lt;br /&gt;
Good: &amp;lt;source&amp;gt;$mainframe = &amp;amp;JFactory::getApplication();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Global Option ===&lt;br /&gt;
Bad: &amp;lt;source&amp;gt;global $option;&amp;lt;/source&amp;gt;&lt;br /&gt;
Good: &amp;lt;source&amp;gt;$option = JRequest::getCmd(&#039;option&#039;);&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I will add more changes like it.&lt;br /&gt;
&lt;br /&gt;
== Content plugins work slightly different ==&lt;br /&gt;
&lt;br /&gt;
The content plugins in Joomla! 1.5 were using the onPrepareContent method, whereas the content plugins in Joomla! 1.6/1.7 use the onContentPrepare method. The arguments have also changed. You can, however, create a single content plugin which runs on both Joomla! versions without rewriting code. Here&#039;s how:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die();&lt;br /&gt;
&lt;br /&gt;
jimport(&#039;joomla.plugin.plugin&#039;);&lt;br /&gt;
&lt;br /&gt;
class plgContentFoobar extends JPlugin&lt;br /&gt;
{&lt;br /&gt;
	public function onPrepareContent( &amp;amp;$article, &amp;amp;$params, $limitstart = 0 )&lt;br /&gt;
	{&lt;br /&gt;
		$article-&amp;gt;text = $this-&amp;gt;doSomethingWith($article-&amp;gt;text);&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	public function onContentPrepare($context, &amp;amp;$row, &amp;amp;$params, $page = 0)&lt;br /&gt;
	{&lt;br /&gt;
		// Danger, Will Robinson! $row in Joomla! 1.6/1.7 may be a string, not an article object!&lt;br /&gt;
		if(is_object($row)) {&lt;br /&gt;
			return $this-&amp;gt;onPrepareContent($row, $params, $page);&lt;br /&gt;
		} else {&lt;br /&gt;
			$row = $this-&amp;gt;doSomethingWith($row);&lt;br /&gt;
		}&lt;br /&gt;
		&lt;br /&gt;
		return true;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	private function doSomethingWith($text)&lt;br /&gt;
	{&lt;br /&gt;
		// Apparently, you have to do something here ;)&lt;br /&gt;
		return $text;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Updating doesn&#039;t work as you&#039;d expect ==&lt;br /&gt;
&lt;br /&gt;
There is a small but very disturbing bug in Joomla! 1.6. Updating a component whose manifest XML states version=&amp;quot;1.5.0&amp;quot; doesn&#039;t allow you to run the SQL statements. Namely, the SQL files you specify under the &amp;quot;&amp;lt;install&amp;gt;&amp;lt;sql&amp;gt;&amp;quot; tags won&#039;t run. You can neither use the new &amp;quot;&amp;lt;update&amp;gt;&amp;quot; tag. You are stuck with no way to run SQL commands on component update!&lt;br /&gt;
&lt;br /&gt;
The ugly workaround is to create a file named script.foobar.php with the following contents:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
define(&#039;_JEXEC&#039;) or die();&lt;br /&gt;
&lt;br /&gt;
class Com_FoobarInstallerScript {&lt;br /&gt;
	&lt;br /&gt;
	function update($parent) {&lt;br /&gt;
		$db = JFactory::getDBO();&lt;br /&gt;
		// Obviously you may have to change the path and name if your installation SQL file ;)&lt;br /&gt;
		if(method_exists($parent, &#039;extension_root&#039;)) {&lt;br /&gt;
			$sqlfile = $parent-&amp;gt;getPath(&#039;extension_root&#039;).DS.&#039;install.sql&#039;;&lt;br /&gt;
		} else {&lt;br /&gt;
			$sqlfile = $parent-&amp;gt;getParent()-&amp;gt;getPath(&#039;extension_root&#039;).DS.&#039;install.sql&#039;;&lt;br /&gt;
		}&lt;br /&gt;
		// Don&#039;t modify below this line&lt;br /&gt;
		$buffer = file_get_contents($sqlfile);&lt;br /&gt;
		if ($buffer !== false) {&lt;br /&gt;
			jimport(&#039;joomla.installer.helper&#039;);&lt;br /&gt;
			$queries = JInstallerHelper::splitSql($buffer);&lt;br /&gt;
			if (count($queries) != 0) {&lt;br /&gt;
				foreach ($queries as $query)&lt;br /&gt;
				{&lt;br /&gt;
					$query = trim($query);&lt;br /&gt;
					if ($query != &#039;&#039; &amp;amp;&amp;amp; $query{0} != &#039;#&#039;) {&lt;br /&gt;
						$db-&amp;gt;setQuery($query);&lt;br /&gt;
						if (!$db-&amp;gt;query()) {&lt;br /&gt;
							JError::raiseWarning(1, JText::sprintf(&#039;JLIB_INSTALLER_ERROR_SQL_ERROR&#039;, $db-&amp;gt;stderr(true)));&lt;br /&gt;
							return false;&lt;br /&gt;
						}&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Reference that file in the end of your manifest XML file, just above the closing install tag, with:&lt;br /&gt;
&amp;lt;source type=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;scriptfile&amp;gt;script.foobar.php&amp;lt;/scriptfile&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will force Joomla! 1.6 to run your extension&#039;s installation SQL file during the component update, just like Joomla! 1.5 used to do. Enjoy!&lt;br /&gt;
&lt;br /&gt;
== Menu item creation tricks ==&lt;br /&gt;
&lt;br /&gt;
===For Joomla! 1.5===&lt;br /&gt;
&lt;br /&gt;
You have to add a line similar to the following in your component&#039;s manifest XML file, inside the &amp;lt;code&amp;gt;&amp;lt;administration&amp;gt;&amp;lt;code&amp;gt; tag.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;menu view=&amp;quot;yourview&amp;quot; img=&amp;quot;../media/com_example/logo-16.png&amp;quot;&amp;gt;COM_EXAMPLE&amp;lt;/menu&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;menu view=&amp;quot;yourview&amp;quot; img=&amp;quot;../media/com_example/logo-16.png&amp;quot;&amp;gt;Example Component&amp;lt;/menu&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In both cases, you need to create a file named en-GB.com_example.menu.ini in administrator/languages/en-GB (you can use the manifest&#039;s &amp;lt;code&amp;gt;&amp;lt;languages&amp;gt;&amp;lt;/code&amp;gt; tag to copy it during installation). In the first case (using a translation key), its contents should be:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
COM_EXAMPLE=Example Component&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
In the second case (using natural language strings) its contents should be&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
Example Component=Example Component&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
NB: Joomla! 1.5 sorts the Component menu items based on the key you supply in your XML manifest. If you use the COM_EXAMPLE approach, your component will be sorted with all the components beginning with &amp;quot;C&amp;quot;, e.g. just before Contacts on a fresh Joomla! 1.5 installation, no matter what the translation is! This leads to funny results, especially with non-English languages where the translated component names do not follow the same sorting order as their English names. If you are bilingual or multilingual, I think you know what I mean…&lt;br /&gt;
&lt;br /&gt;
===For Joomla! 1.6 and later versions===&lt;br /&gt;
&lt;br /&gt;
You have to add a line similar to the following in your component&#039;s manifest XML file, inside the &amp;lt;code&amp;gt;&amp;lt;administration&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;menu view=&amp;quot;yourview&amp;quot; img=&amp;quot;../media/com_example/logo-16.png&amp;quot;&amp;gt;COM_EXAMPLE&amp;lt;/menu&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can not use a natural language string. Doing so will result in your component name appearing as example-component in the menu and you will be unable to provide a translation.&lt;br /&gt;
&lt;br /&gt;
You need to create a file named en-GB.com_example.sys.ini in administrator/languages/en-GB (you can use the manifest&#039;s &amp;lt;code&amp;gt;&amp;lt;languages&amp;gt;&amp;lt;/code&amp;gt; tag to copy it during installation) or in administrator/components/com_example/language/en-GB. In the latter case, you must not include the translation file in the &amp;lt;code&amp;gt;&amp;lt;languages&amp;gt;&amp;lt;/code&amp;gt; tag. As long as you have placed the language directory in your &amp;lt;code&amp;gt;&amp;lt;files&amp;gt;&amp;lt;/code&amp;gt; tag, it will be copied along when the component is being installed.&lt;br /&gt;
&lt;br /&gt;
The contents of that file should be:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
COM_EXAMPLE=&amp;quot;Example Component&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Please note that the language string must be enclosed in double quotes, as per Joomla!&#039;s translation standards.&lt;br /&gt;
&lt;br /&gt;
NB: Joomla! 1.6 and later sorts the Component menu items based on the actual translation of the key you supply in your XML manifest. This means that the sorting order is correct no matter what you call your translation key and no matter which language the site is being displayed in. Essentially, Joomla! 1.6 fixed the wrong sorting of the Components menu for the majority (non-English speaking!) of Joomla! users.&lt;br /&gt;
&lt;br /&gt;
===How to have a cross-version (Joomla! 1.5, 1.6 and later) component===&lt;br /&gt;
&lt;br /&gt;
If your component is supposed to be installed under both Joomla! 1.5 and Joomla! 1.6/1.7/2.5, you can do a little trick. You have to add a line similar to the following in your component&#039;s manifest XML file, inside the &amp;lt;code&amp;gt;&amp;lt;administration&amp;gt;&amp;lt;/code&amp;gt; tag.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;menu view=&amp;quot;yourview&amp;quot; img=&amp;quot;../media/com_example/logo-16.png&amp;quot;&amp;gt;COM_EXAMPLE&amp;lt;/menu&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, you need to create two files, one for Joomla! 1.5 and one for Joomla! 1.6. For Joomla! 1.5  you need to create a file named en-GB.com_example.menu.ini in administrator/languages/en-GB (you can use the manifest&#039;s &amp;lt;code&amp;gt;&amp;lt;languages&amp;gt;&amp;lt;/code&amp;gt; tag to copy it during installation). Its contents should be:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
COM_EXAMPLE=Example Component&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
For Joomla! 1.6 you need to create a file named en-GB.com_example.sys.ini in administrator/languages/en-GB (you can use the manifest&#039;s &amp;lt;code&amp;gt;&amp;lt;languages&amp;gt;&amp;lt;/code&amp;gt; tag to copy it during installation) or in administrator/components/com_example/language/en-GB. In the latter case, you must not include the translation file in the &amp;lt;code&amp;gt;&amp;lt;languages&amp;gt;&amp;lt;/code&amp;gt; tag. As long as you have placed the language directory in your &amp;lt;code&amp;gt;&amp;lt;files&amp;gt;&amp;lt;/code&amp;gt; tag, it will be copied along when the component is being installed.&lt;br /&gt;
&lt;br /&gt;
The contents of that file should be:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
COM_EXAMPLE=&amp;quot;Example Component&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The only drawback is that your component will appear as weirdly sorted in the Components menu of Joomla! 1.5. Given the very near expiration date of Joomla! 1.5 (April 2012) this is not a major drawback and experience shows that users don&#039;t really care that much. &lt;br /&gt;
&lt;br /&gt;
===What if you do that and nothing happens?===&lt;br /&gt;
&lt;br /&gt;
Joomla! is supposed to create the components menu entries afresh every time you re-install the component. If this doesn&#039;t happen in your case, try uninstalling and re-installing your component. If you&#039;re not sure if Joomla! has the correct Components menu item translation key, you can always check the menu items database table. This will prevent you from unnecessary frustration when your translation files don&#039;t work simply because Joomla! has the wrong translation key in the table.&lt;br /&gt;
&lt;br /&gt;
== More tricks? ==&lt;br /&gt;
&lt;br /&gt;
I am sure that by writing this page I have left out a number of tricks which I am already using in my software. If you get stuck somewhere, feel free to take a look at how I&#039;ve implemented things in Admin Tools Core, Akeeba Backup Core and Akeeba Release System, my Joomla! 1.5/1.6/1.7 compatible extensions. If you find a better way to implement something, or found a trick not listed here, feel free to edit this wiki page. Sharing the knowledge is caring!&lt;br /&gt;
&lt;br /&gt;
Peace, love and friendship,&lt;br /&gt;
&lt;br /&gt;
Nicholas K. Dionysopoulos, AkeebaBackup.com Lead Developer&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Accessing_the_database_using_JDatabase&amp;diff=21346</id>
		<title>Accessing the database using JDatabase</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Accessing_the_database_using_JDatabase&amp;diff=21346"/>
		<updated>2010-01-22T16:23:11Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: /* Insert Query Execution */  Add link to more documentation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{ambox|type=merge|image=merge|text=It has been suggested that this page or section be merged with [[Tutorial:How to use the database classes in your script]]. ([[Talk:How to use the database classes in your script|Discuss here]])}}&lt;br /&gt;
Joomla provides a sophisticated database abstraction layer to simplify the usage for 3PD. This guide should help you using this layer.&lt;br /&gt;
&lt;br /&gt;
==Why should I use the Joomla database class?==&lt;br /&gt;
Joomla has been built with the ability to use several different kinds of SQL-database-systems and to run in a variety of environments with different table-prefixes. In addition to these functions, the class automatically creates the database connection. Besides instantiating the object, at a minimum, you only need 2 lines of code to get a result from the database in a variety of formats. Using the Joomla database layer ensures a maximum of compatibility and flexibility for your extension.&lt;br /&gt;
&lt;br /&gt;
==Preparing the query==&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Get a database object&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example_table WHERE id = 999999;&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
First we instantiate the database object, then we prepare the query. You can use the normal SQL-syntax, the only thing you have to change is the table-prefix. To make this as flexible as possible, Joomla uses a placeholder for the prefix, the &amp;amp;ldquo;#__&amp;amp;rdquo;. In the next step, the $db-&amp;gt;setQuery(), this string is replaced with the correct prefix.&lt;br /&gt;
&lt;br /&gt;
Now, if we don&#039;t want to get information from the database, but insert a row into it, we need one more function. Every string-value in the SQL-syntax should be quoted. For example, MySQL uses backticks &amp;amp;#096;&amp;amp;#096; for names and single quotes &amp;amp;lsquo;&amp;amp;lsquo; for values. Joomla has some functions to do this for us and to ensure code compatibility between different databases. We can pass the names to the function $db-&amp;gt;nameQuote($name) and the values to the function $db-&amp;gt;Quote($value). &lt;br /&gt;
&lt;br /&gt;
A fully quoted query example is:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT * &lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__example_table&#039;).&amp;quot;  &lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;id&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote(&#039;999999&#039;).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Whatever we want to do, we have to set the query with the $db-&amp;gt;setQuery() function. Although you could write the query directly as a parameter for $db-&amp;gt;setQuery(), it&#039;s commonly done by first saving it in a variable, normally $query, and then handing this variable over. This helps writing clean, readable code.&lt;br /&gt;
&lt;br /&gt;
==== setQuery($query) ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;setQuery($query)&#039;&#039; method sets up a database query for later execution either by the query() method or one of the Load result methods.  &amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;/* some valid sql string */&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
The parameter $query must be a valid sql string, it can either be added as a string parameter or as a variable; generally a variable is preferred as it leads to more legible code and can help in debugging.&lt;br /&gt;
&lt;br /&gt;
setQuery() also takes three other parameters: $offset, $limit - both used in list pagination; and $prefix - an alternative table prefix. All three of these variables have default values set and can usually be ignored.&lt;br /&gt;
&lt;br /&gt;
==Executing the Query==&lt;br /&gt;
To execute the query, Joomla provides several functions, which differ in their return value.&lt;br /&gt;
&lt;br /&gt;
=== Basic Query Execution ===&lt;br /&gt;
&lt;br /&gt;
==== query() ====&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;query()&#039;&#039; method is the the basic tool for executing sql queries on a database. In Joomla it is most often used for updating or administering the database simple because the various load methods detail on this page have the query step built in to them.&lt;br /&gt;
&lt;br /&gt;
The syntax is very straightforward:&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;/* some valid sql string */&amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;query();&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: $query() returns an appropriate database resource if successful, or FALSE if not&lt;br /&gt;
&lt;br /&gt;
=== Query Execution Information ===&lt;br /&gt;
* getAffectedRows()&lt;br /&gt;
* explain()&lt;br /&gt;
* insertid()&lt;br /&gt;
&lt;br /&gt;
=== Insert Query Execution ===&lt;br /&gt;
* insertObject()  [http://help.joomla.org/content/view/712/125/]&lt;br /&gt;
&lt;br /&gt;
==Query Results ==&lt;br /&gt;
The database class contains many methods for working with a query&#039;s result set.&lt;br /&gt;
&lt;br /&gt;
=== Single Value Result ===&lt;br /&gt;
&lt;br /&gt;
==== loadResult() ====&lt;br /&gt;
&lt;br /&gt;
Use &#039;&#039;&#039;loadResult()&#039;&#039;&#039; when you expect just a single value back from your database query. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- &lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
This is often the result of a &#039;count&#039; query to get a number of records:&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT COUNT(*)&lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__my_table&#039;).&amp;quot;&lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;name&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote($value).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$count = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
or where you are just looking for a single field from a single row of the table (or possibly a single field from the first row returned).&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT &amp;quot;.$db-&amp;gt;nameQuote(&#039;field_name&#039;).&amp;quot;&lt;br /&gt;
    FROM &amp;quot;.$db-&amp;gt;nameQuote(&#039;#__my_table&#039;).&amp;quot;&lt;br /&gt;
    WHERE &amp;quot;.$db-&amp;gt;nameQuote(&#039;some_name&#039;).&amp;quot; = &amp;quot;.$db-&amp;gt;quote($some_value).&amp;quot;;&lt;br /&gt;
  &amp;quot;;&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Single Row Results ===&lt;br /&gt;
&lt;br /&gt;
Each of these results functions will return a single record from the database even though there may be several records that meet the criteria that you have set. To get more records you need to call the function again.&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadRow() ====&lt;br /&gt;
&lt;br /&gt;
loadRow() returns an indexed array from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRow();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; 1 [1] =&amp;gt; John Smith [2] =&amp;gt; johnsmith@example.com [3] =&amp;gt; johnsmith ) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful&lt;br /&gt;
&lt;br /&gt;
==== loadAssoc() ====&lt;br /&gt;
&lt;br /&gt;
loadAssoc() returns an associated array from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssoc();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;name&#039;] // e.g. $row[&#039;name&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful&lt;br /&gt;
&lt;br /&gt;
==== loadObject() ====&lt;br /&gt;
&lt;br /&gt;
loadObject returns a PHP object from a single record in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadObject();&lt;br /&gt;
print_r($result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$row-&amp;gt;index // e.g. $row-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# Whilst you can repeat the call to get further rows, one of the functions that returns multiple rows might be more useful&lt;br /&gt;
&lt;br /&gt;
===Single Column Results ===&lt;br /&gt;
&lt;br /&gt;
Each of these results functions will return a single column from the database. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- &lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || style=&amp;quot;background:yellow&amp;quot; | Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || style=&amp;quot;background:yellow&amp;quot; | Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadResultArray() ====&lt;br /&gt;
&lt;br /&gt;
loadResultArray() returns an indexed array from a single column in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT name, email, username&lt;br /&gt;
    FROM . . . &amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadResultArray();&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; John Smith [1] =&amp;gt; Magda Hellman [2] =&amp;gt; Yvonne de Gaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$column[&#039;index&#039;] // e.g. $column[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# loadResultArray() is equivalent to loadResultArray(0)&lt;br /&gt;
&lt;br /&gt;
==== loadResultArray($index) ====&lt;br /&gt;
&lt;br /&gt;
loadResultArray($index) returns an indexed array from a single column in the table: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query = &amp;quot;&lt;br /&gt;
  SELECT name, email, username&lt;br /&gt;
    FROM . . . &amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadResultArray(1);&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; johnsmith@example.com [1] =&amp;gt; magda_h@example.com [2] =&amp;gt; ydg@example.com )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual values by using:&amp;lt;pre&amp;gt;$column[&#039;index&#039;] // e.g. $column[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
loadResultArray($index) allows you to iterate through a series of columns in the results&lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
for ( $i = 0; $i &amp;lt;= 2; $i++ ) {&lt;br /&gt;
  $column= $db-&amp;gt;loadResultArray($i);&lt;br /&gt;
  print_r($column);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; John Smith [1] =&amp;gt; Magda Hellman [2] =&amp;gt; Yvonne de Gaulle )&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith@example.com [1] =&amp;gt; magda_h@example.com [2] =&amp;gt; ydg@example.com )&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith [1] =&amp;gt; magdah [2] =&amp;gt; ydegaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
&lt;br /&gt;
=== Multi-Row Results ===&lt;br /&gt;
&lt;br /&gt;
Each of these results functions will return multiple records from the database. &lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! id !! name !! email !! username&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@example.com || johnsmith&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 2 || Magda Hellman || magda_h@example.com || magdah&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@example.com || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== loadRowList() ====&lt;br /&gt;
&lt;br /&gt;
loadRowList() returns an indexed array of indexed arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadRowList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; Array ( [0] =&amp;gt; 1 [1] =&amp;gt; John Smith [2] =&amp;gt; johnsmith@example.com [3] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; Array ( [0] =&amp;gt; 2 [1] =&amp;gt; Magda Hellman [2] =&amp;gt; magda_h@example.com [3] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; Array ( [0] =&amp;gt; 3 [1] =&amp;gt; Yvonne de Gaulle [2] =&amp;gt; ydg@example.com [3] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;][&#039;index&#039;] // e.g. $row[&#039;2&#039;][&#039;3&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
&lt;br /&gt;
==== loadAssocList() ====&lt;br /&gt;
&lt;br /&gt;
loadAssocList() returns an indexed array of associated arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssocList();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; Array ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; Array ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;][&#039;column_name&#039;] // e.g. $row[&#039;2&#039;][&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadAssocList($key) ====&lt;br /&gt;
&lt;br /&gt;
loadAssocList(&#039;key&#039;) returns an associated array - indexed on &#039;key&#039; - of associated arrays from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadAssocList(&#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[johnsmith] =&amp;gt; Array ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[magdah] =&amp;gt; Array ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[ydegaulle] =&amp;gt; Array ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;][&#039;column_name&#039;] // e.g. $row[&#039;johnsmith&#039;][&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.&lt;br /&gt;
&lt;br /&gt;
==== loadObjectList() ====&lt;br /&gt;
&lt;br /&gt;
loadObjectList() returns an indexed array of PHP objects from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadObjectList();&lt;br /&gt;
print_r($result);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[0] =&amp;gt; stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith &lt;br /&gt;
    [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[1] =&amp;gt; stdClass Object ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman &lt;br /&gt;
    [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[2] =&amp;gt; stdClass Object ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle &lt;br /&gt;
    [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;index&#039;]-&amp;gt;name // e.g. $row[&#039;2&#039;]-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== loadObjectList(&#039;key&#039;) ====&lt;br /&gt;
&lt;br /&gt;
loadObjectList($key) returns an associated array - indexed on &#039;key&#039; - of objects from the table records returned by the query: &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$row = $db-&amp;gt;loadObjectList(&#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( &lt;br /&gt;
[johnsmith] =&amp;gt; stdClass Object ( [id] =&amp;gt; 1 [name] =&amp;gt; John Smith &lt;br /&gt;
    [email] =&amp;gt; johnsmith@example.com [username] =&amp;gt; johnsmith ) &lt;br /&gt;
[magdah] =&amp;gt; stdClass Object ( [id] =&amp;gt; 2 [name] =&amp;gt; Magda Hellman &lt;br /&gt;
    [email] =&amp;gt; magda_h@example.com [username] =&amp;gt; magdah ) &lt;br /&gt;
[ydegaulle] =&amp;gt; stdClass Object ( [id] =&amp;gt; 3 [name] =&amp;gt; Yvonne de Gaulle &lt;br /&gt;
    [email] =&amp;gt; ydg@example.com [username] =&amp;gt; ydegaulle ) &lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can access the individual rows by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;]-&amp;gt;column_name // e.g. $row[&#039;johnsmith&#039;]-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: Key must be a valid column name from the table; it does not have to be an Index or a Primary Key. But if it does not have a unique value you may not be able to retrieve results reliably.&lt;br /&gt;
&lt;br /&gt;
=== Misc Result Set Methods ===&lt;br /&gt;
&lt;br /&gt;
==== getNumRows() ====&lt;br /&gt;
&lt;br /&gt;
getNumRows() will return the number of result rows found by the last query and waiting to be read. To get a result from getNumRows() you have to run it &#039;&#039;&#039;after&#039;&#039;&#039; the query and &#039;&#039;&#039;before&#039;&#039;&#039; you have retrieved any results.  &lt;br /&gt;
&amp;lt;source lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$db-&amp;gt;query();&lt;br /&gt;
$num_rows = $db-&amp;gt;getNumRows();&lt;br /&gt;
print_r($num_rows);&lt;br /&gt;
$result = $db-&amp;gt;loadRowList();&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will return &amp;lt;pre&amp;gt;3&amp;lt;/pre&amp;gt;&lt;br /&gt;
Note: if you run getNumRows() after loadRowList() - or any other retrieval method - you may get a PHP Warning:&lt;br /&gt;
&amp;lt;pre&amp;gt;Warning: mysql_num_rows(): 80 is not a valid MySQL result resource &lt;br /&gt;
in D:\xampp\htdocs\joomla1.5a\libraries\joomla\database\database\mysql.php on line 344&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Tips, Tricks &amp;amp; FAQ==&lt;br /&gt;
===Subqueries===&lt;br /&gt;
We had a few people lately using sub-queries like these:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;SQL&amp;quot;&amp;gt;&lt;br /&gt;
SELECT * FROM #__example WHERE id IN (SELECT id FROM #__example2);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
These kind of queries are only possible in MySQL 4.1 and above. Another way to achieve this, is splitting the query into two:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = &amp;quot;SELECT id FROM #__example2&amp;quot;;&lt;br /&gt;
$database-&amp;gt;setQuery($query);&lt;br /&gt;
$query = &amp;quot;SELECT * FROM #__example WHERE id IN (&amp;quot;. implode(&amp;quot;,&amp;quot;, $database-&amp;gt;loadResultArray()) .&amp;quot;)&amp;quot;;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
===Developer-friendly tip===&lt;br /&gt;
Here is a quick way to do 4 developer-friendly things at once:&lt;br /&gt;
* Use a simple constant as SQL-seperator (which can probably be used in many queries)&lt;br /&gt;
* Make your SQL-in-php code easy to read (for yourself and possibly other developers later on)&lt;br /&gt;
* Give an error inside your (component-) content without really setting debugging on&lt;br /&gt;
* Have a visibly nice SQL with splitting SQL-groups with linebreaks in your error&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$db =&amp;amp; JFactory::getDBO();&lt;br /&gt;
$jAp=&amp;amp; JFactory::getApplication();&lt;br /&gt;
    //We define a linebreak constant&lt;br /&gt;
define(&#039;L&#039;, chr(10));&lt;br /&gt;
    //Here is the most magic&lt;br /&gt;
$db-&amp;gt;setQuery(&lt;br /&gt;
	&#039;SELECT * FROM #__table&#039;.L.&lt;br /&gt;
	&#039;WHERE something=&amp;quot;something else&amp;quot;)&#039;.L.&lt;br /&gt;
	&#039;ORDER BY date desc&#039;&lt;br /&gt;
); &lt;br /&gt;
$db-&amp;gt;query();&lt;br /&gt;
    //display and convert to HTML when SQL error&lt;br /&gt;
if (is_null($posts=$db-&amp;gt;loadRowList())) {$jAp-&amp;gt;enqueueMessage(nl2br($db-&amp;gt;getErrorMsg()),&#039;error&#039;); return;} &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Development]][[Category:Database]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:Using_the_JToolBar_class_in_the_frontend&amp;diff=21313</id>
		<title>J1.5:Using the JToolBar class in the frontend</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:Using_the_JToolBar_class_in_the_frontend&amp;diff=21313"/>
		<updated>2010-01-19T17:25:16Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: Spelling Correction&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Anyone whom has used the very useful JToolbarHelper class in an administration component has probably already realised that there is nothing quite so useful for the frontend. The good news is that we can create our own very simply using the JToolbar class.&lt;br /&gt;
&lt;br /&gt;
First lets create the helper class. I tend to make a different helper class for each component as they will each have a different toolbar. I like to keep all my helpers in the administration end as they can often be used for both sides of the component. So firstly create a helpers directory in your component.&lt;br /&gt;
&lt;br /&gt;
/administrator/components/com_yourcom/helpers&lt;br /&gt;
&lt;br /&gt;
and create a file called toolbar.php&lt;br /&gt;
&lt;br /&gt;
The following is an example of a very simple toolbar helper class. Copy and paste this into your toolbar.php file. Don&#039;t forget to change &#039;yourcom&#039; to the name of your component. Notice also that we&#039;ve included the Jtoolbar class at the top of the file.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 // no direct access&lt;br /&gt;
 defined(&#039;_JEXEC&#039;) or die(&#039;Restricted access&#039;);&lt;br /&gt;
 jimport(&#039;joomla.html.toolbar&#039;);&lt;br /&gt;
 &lt;br /&gt;
 class YourcomHelperToolbar extends JObject&lt;br /&gt;
 {	&lt;br /&gt;
 	function getToolbar() {&lt;br /&gt;
 		&lt;br /&gt;
 		&lt;br /&gt;
 		$bar =&amp;amp; new JToolBar( &#039;My Toolbar&#039; );&lt;br /&gt;
 		$bar-&amp;gt;appendButton( &#039;Standard&#039;, &#039;new&#039;, &#039;New Record&#039;, &#039;new&#039;, false );&lt;br /&gt;
 		$bar-&amp;gt;appendButton( &#039;Separator&#039; );&lt;br /&gt;
 		$bar-&amp;gt;appendButton( &#039;Standard&#039;, &#039;delete&#039;, &#039;Delete Record&#039;, &#039;delete&#039;, false );&lt;br /&gt;
 		&lt;br /&gt;
 		&lt;br /&gt;
 		return $bar-&amp;gt;render();&lt;br /&gt;
 	&lt;br /&gt;
 	}&lt;br /&gt;
 	&lt;br /&gt;
 } &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Lets look at this code. When the &#039;getToolbar&#039; function is called it creates a new instance of the JToolbar class.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $bar =&amp;amp; new JToolBar( &#039;Associations Toolbar&#039; );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
We can then add buttons to this object.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $bar-&amp;gt;appendButton( &#039;Standard&#039;, &#039;new&#039;, &#039;New Record&#039;, &#039;new&#039;, false );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The first parameter is the button type. have a look a the JToolbar or JButton docs for a full list of these.&lt;br /&gt;
&lt;br /&gt;
The second parameter is the class to apply to the button ( this will help us to apply an image to it as in the backend )&lt;br /&gt;
&lt;br /&gt;
The third parameter is the text to display on the button.&lt;br /&gt;
&lt;br /&gt;
The fourth is the task to set. When the button is pressed the javascript submitButton function is called and the hidden field &#039;task&#039; is set to this value. We will see this later in our template file.&lt;br /&gt;
&lt;br /&gt;
The fifth states whether a selection must be made from an admin list before continuing.&lt;br /&gt;
&lt;br /&gt;
we then simply return our bar object.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We now have a choice of where to render this bar object. You can create it in a view and apply it to a template if you wish. I personally prefer to render it in the entry point file. In this example this would be yourcom.php and would look something like this. Notice that we have also included our helper file here.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 // no direct access&lt;br /&gt;
 defined(&#039;_JEXEC&#039;) or die(&#039;Restricted access&#039;);&lt;br /&gt;
 &lt;br /&gt;
 // Require the base controller&lt;br /&gt;
 require_once (JPATH_COMPONENT.DS.&#039;controller.php&#039;);&lt;br /&gt;
 &lt;br /&gt;
 // Require specific controller if requested&lt;br /&gt;
 if($controller = JRequest::getVar(&#039;controller&#039;)) {&lt;br /&gt;
 	require_once (JPATH_COMPONENT.DS.&#039;controllers&#039;.DS.$controller.&#039;.php&#039;);&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 // Component Helper&lt;br /&gt;
 jimport(&#039;joomla.application.component.helper&#039;);&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 // Load the toolbar helper&lt;br /&gt;
 require_once( JPATH_COMPONENT_ADMINISTRATOR.DS.&#039;helpers&#039;.DS.&#039;toolbar.php&#039; );&lt;br /&gt;
 &lt;br /&gt;
 // render the toolbar on the page. rendering it here means that it is displayed on every view of your component.&lt;br /&gt;
 echo YourcomHelperToolbar::getToolbar();&lt;br /&gt;
 &lt;br /&gt;
 // Create the controller&lt;br /&gt;
 $classname	= &#039;YourcomController&#039;.$controller;&lt;br /&gt;
 $controller = new $classname( );&lt;br /&gt;
 &lt;br /&gt;
 // Perform the Request task&lt;br /&gt;
 $controller-&amp;gt;execute( JRequest::getVar(&#039;task&#039;));&lt;br /&gt;
 &lt;br /&gt;
 // Redirect if set by the controller&lt;br /&gt;
 $controller-&amp;gt;redirect();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Having created this the toolbar you created should render on the page but there are a few more things we need to do to make it work. We need to ensure that every view template page has an admin form for the submitButton function to work.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;form action = &amp;quot;index.php&amp;quot; method =  &amp;quot;post&amp;quot; id = &amp;quot;adminForm&amp;quot; name = &amp;quot;adminForm&amp;quot; /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &amp;lt;input type = &amp;quot;hidden&amp;quot; name = &amp;quot;task&amp;quot; value = &amp;quot;&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;input type = &amp;quot;hidden&amp;quot; name = &amp;quot;option&amp;quot; value = &amp;quot;com_yourcom&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/form&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Now when one of the buttons is clicked the submitbutton function will set the hidden field &#039;task&#039; to the task identifier you specified in the toolbar class.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 $bar-&amp;gt;appendButton( &#039;Standard&#039;, &#039;delete&#039;, &#039;Delete Record&#039;, &#039;new&#039;, false );&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
In the above button the task would be &#039;new&#039; ( the fourth parameter );&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If this task is going to be run we had better make sure that it&#039;s available in our controller. Open up your controller.php and add the following.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 function new() &lt;br /&gt;
 	{&lt;br /&gt;
 		JRequest::setVar(&#039;view&#039; , &#039;new&#039;);&lt;br /&gt;
 		&lt;br /&gt;
 		parent::display();&lt;br /&gt;
 	}&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This will display your &#039;new&#039; view assuming you&#039;ve already created one. You could put any code in here you like.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
There we go that should create a nice easy to use toolbar class. There is one last thing though. You may have noticed that the icons are not displaying as they do in the backend. To make this work we have to &#039;steal&#039; some images and some CSS from the backend.&lt;br /&gt;
&lt;br /&gt;
open up the folder &lt;br /&gt;
&lt;br /&gt;
 administrator/templates/khepri/images &lt;br /&gt;
&lt;br /&gt;
and copy the directory &#039;toolbar&#039; directory to your frontend templates/rhuk_milkyway/images folder&lt;br /&gt;
&lt;br /&gt;
It should now look like this&lt;br /&gt;
&lt;br /&gt;
 templates/rhuk_milkyway/images/toolbar&lt;br /&gt;
&lt;br /&gt;
and be filled with png images&lt;br /&gt;
&lt;br /&gt;
Now you could hunt around through the backend css to find the correct code to display the buttons but I&#039;ve saved you the trouble. In your templates/css folder create a file called icon.css and paste in the following code.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 /* toolbar */&lt;br /&gt;
 div.toolbar { float: right; text-align: right; padding: 0; }&lt;br /&gt;
 &lt;br /&gt;
 table.toolbar    			 { border-collapse: collapse; padding: 0; margin: 0;	 }&lt;br /&gt;
 table.toolbar td 			 { padding: 1px 1px 1px 4px; text-align: center; color: #666; height: 48px; }&lt;br /&gt;
 table.toolbar td.spacer  { width: 10px; }&lt;br /&gt;
 table.toolbar td.divider { border-right: 1px solid #eee; width: 5px; } &lt;br /&gt;
 &lt;br /&gt;
 table.toolbar span { float: none; width: 32px; height: 32px; margin: 0 auto; display: block; }&lt;br /&gt;
 &lt;br /&gt;
 table.toolbar a {&lt;br /&gt;
    display: block; float: left;&lt;br /&gt;
 	white-space: nowrap;&lt;br /&gt;
 	border: 1px solid #fbfbfb;&lt;br /&gt;
 	padding: 1px 5px;&lt;br /&gt;
 	cursor: pointer;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 table.toolbar a:hover {&lt;br /&gt;
 	border-left: 1px solid #eee;&lt;br /&gt;
 	border-top: 1px solid #eee;&lt;br /&gt;
 	border-right: 1px solid #ccc;&lt;br /&gt;
 	border-bottom: 1px solid #ccc;&lt;br /&gt;
 	text-decoration: none;&lt;br /&gt;
 	color: #0B55C4;&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 /** toolbar icons **/&lt;br /&gt;
 .icon-32-send 			{ background-image: url(../images/toolbar/icon-32-send.png); }&lt;br /&gt;
 .icon-32-delete 		{ background-image: url(../images/toolbar/icon-32-delete.png); }&lt;br /&gt;
 .icon-32-help 			{ background-image: url(../images/toolbar/icon-32-help.png); }&lt;br /&gt;
 .icon-32-cancel 		{ background-image: url(../images/toolbar/icon-32-cancel.png); }&lt;br /&gt;
 .icon-32-config 		{ background-image: url(../images/toolbar/icon-32-config.png); }&lt;br /&gt;
 .icon-32-apply 		{ background-image: url(../images/toolbar/icon-32-apply.png); }&lt;br /&gt;
 .icon-32-back			{ background-image: url(../images/toolbar/icon-32-back.png); }&lt;br /&gt;
 .icon-32-forward		{ background-image: url(../images/toolbar/icon-32-forward.png); }&lt;br /&gt;
 .icon-32-save 			{ background-image: url(../images/toolbar/icon-32-save.png); }&lt;br /&gt;
 .icon-32-edit 			{ background-image: url(../images/toolbar/icon-32-edit.png); }&lt;br /&gt;
 .icon-32-copy 			{ background-image: url(../images/toolbar/icon-32-copy.png); }&lt;br /&gt;
 .icon-32-move 			{ background-image: url(../images/toolbar/icon-32-move.png); }&lt;br /&gt;
 .icon-32-new 			{ background-image: url(../images/toolbar/icon-32-new.png); }&lt;br /&gt;
 .icon-32-upload 		{ background-image: url(../images/toolbar/icon-32-upload.png); }&lt;br /&gt;
 .icon-32-assign 		{ background-image: url(../images/toolbar/icon-32-publish.png); }&lt;br /&gt;
 .icon-32-html 			{ background-image: url(../images/toolbar/icon-32-html.png); }&lt;br /&gt;
 .icon-32-css 			{ background-image: url(../images/toolbar/icon-32-css.png); }&lt;br /&gt;
 .icon-32-menus 			{ background-image: url(../images/toolbar/icon-32-menu.png); }&lt;br /&gt;
 .icon-32-publish 		{ background-image: url(../images/toolbar/icon-32-publish.png); }&lt;br /&gt;
 .icon-32-unpublish 	{ background-image: url(../images/toolbar/icon-32-unpublish.png);}&lt;br /&gt;
 .icon-32-restore		{ background-image: url(../images/toolbar/icon-32-revert.png); }&lt;br /&gt;
 .icon-32-trash 		{ background-image: url(../images/toolbar/icon-32-trash.png); }&lt;br /&gt;
 .icon-32-archive 		{ background-image: url(../images/toolbar/icon-32-archive.png); }&lt;br /&gt;
 .icon-32-unarchive 	{ background-image: url(../images/toolbar/icon-32-unarchive.png); }&lt;br /&gt;
 .icon-32-preview 		{ background-image: url(../images/toolbar/icon-32-preview.png); }&lt;br /&gt;
 .icon-32-default 		{ background-image: url(../images/toolbar/icon-32-default.png); }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
We now have to include this css in to your template so add the following line to the top of your template index.php&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;&amp;lt;?php echo $this-&amp;gt;baseurl ?&amp;gt;/templates/rhuk_milkyway/css/icon.css&amp;quot; type=&amp;quot;text/css&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
(if you are using the toolbar on a component that other people will be installing it would be better to use: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$mainframe-&amp;gt;addCustomHeadTag (&#039;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;&#039;.$this-&amp;gt;baseurl.&#039;/components/com_**yourcomponent**/filename.css&amp;quot; type=&amp;quot;text/css&amp;quot; media=&amp;quot;screen&amp;quot; /&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
And finally - you will require the javascript file used in the backend to enable the buttons to work ;-)&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$mainframe-&amp;gt;addCustomHeadTag (&#039;&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;/includes/js/joomla.javascript.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&#039;);&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
And that&#039;s it. your toolbar should now render exactly as it does in the backend. This is a very simple toolbar helper. You could equally copy the JToolbarHelper class exactly in to your toolbar helper and use the functions in the same way as the backend. This would allow you to reuse your jtoolbar helper in multiple components.&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Development]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_add_tooltips_to_your_Joomla!_website&amp;diff=20661</id>
		<title>J1.5:How to add tooltips to your Joomla! website</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_add_tooltips_to_your_Joomla!_website&amp;diff=20661"/>
		<updated>2009-12-09T21:48:58Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: /* Customizing Your Yooltips */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
===Tooltips Overview===&lt;br /&gt;
A tooltips is a piece of text that pops up when you hover the mouse over a region on a website. If you use the Joomla! back end, for example, tooltips are used to help explain the action of different parameters, as shown in the screenshot below: &lt;br /&gt;
&lt;br /&gt;
[[Image:Screen_tooltip_example_20090208.png]]&lt;br /&gt;
&lt;br /&gt;
Tooltips are a great way to give the user access to information without using up space on the screen. You can use basic tooltips just by adding a &amp;quot;title&amp;quot; attribute to a tag. However, this doesn&#039;t give you the option to style the tooltips. With Joomla! version 1.5, it is very easy to add styled tooltips to your site. This tutorial will show you how. &amp;lt;blockquote&amp;gt;&#039;&#039;Note: If you are converting old code, make sure it doesn&#039;t use the prototype.js file.  That file will keep the tooltips from working.&#039;&#039;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Activate Tooltip Behavior===&lt;br /&gt;
To start, you must activate the tooltip behavior.  This is done with the following line of code:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JHTML::_(&#039;behavior.tooltip&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Note that you only put this line in once per file. A good place is right after the &amp;lt;code&amp;gt;defined(&#039;_JEXEC&#039;) or die(&#039;Restricted access&#039;);&amp;lt;/code&amp;gt; line. If you are curious about what this line does, it inserts the following JavaScript code in the heading of the HTML page:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;text/javascript&amp;quot;&amp;gt;&lt;br /&gt;
    window.addEvent(&#039;domready&#039;, function(){ &lt;br /&gt;
       var JTooltips = new Tips($$(&#039;.hasTip&#039;), &lt;br /&gt;
       { maxTitleChars: 50, fixed: false}); &lt;br /&gt;
    });&lt;br /&gt;
&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This allows tooltips to function, as outlined below.&lt;br /&gt;
&lt;br /&gt;
===Create a Tooltip with the JHTML::tooltip Method===&lt;br /&gt;
One way to create a tooltip is using the JHTML::tooltip method. The API documentation is available at [http://api.joomla.org/Joomla-Framework/HTML/JHTML.html#tooltip http://api.joomla.org/Joomla-Framework/HTML/JHTML.html#tooltip]. The method definition is shown below.  &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
void tooltip (string $tooltip, [string $title = &#039;&#039;], [string $image = &#039;tooltip.png&#039;], &lt;br /&gt;
              [string $text = &#039;&#039;], [string $href = &#039;&#039;], [boolean $link = 1])&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The brackets mean the parameter is optional. The first parameter, &amp;quot;$tooltip&amp;quot;, is the only required parameter. The equals specifies the default if you do not pass that parameter. For example, the image file &#039;tooltip.png&#039; is the default image.&lt;br /&gt;
&lt;br /&gt;
The following is a basic tooltip.  Keep in mind that the image variable must be in reference to &#039;includes/js/ThemeOffice&#039;.  Use the prefix &#039;../../../&#039; to reference from the root of the Joomla installation.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JHTML::tooltip(&#039;This is the tooltip text&#039;, &#039;Tooltip title&#039;, &#039;tooltip.png&#039;, &#039;&#039;, &lt;br /&gt;
               &#039;http://www.joomla.org&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The above will make a tooltip using the default &amp;quot;tooltip.png&amp;quot; image, as shown below.[[Image:Tooltip_tutorial_example_screenshot_20090208.png|center|frame]]Clicking the image will take you to &amp;lt;tt&amp;gt;http://www.joola.org&amp;lt;/tt&amp;gt;, since that is the &amp;quot;$href&amp;quot; argument. The HTML source for this tooltip is as follows:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;editlinktip hasTip&amp;quot; title=&amp;quot;Tooltip title::This is the tooltip text&amp;quot; &amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;http://www.joomla.org&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;img src=&amp;quot;/my_joomla_path/includes/js/ThemeOffice/tooltip.png&amp;quot; border=&amp;quot;0&amp;quot; alt=&amp;quot;Tooltip&amp;quot;/&amp;gt;&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;Internet Explorer Bug: As shown above, when you use the JHTML::tooltip method to create an image tooltip, it creates an &amp;quot;alt&amp;quot; attribute with the value &amp;quot;Tooltip&amp;quot;. The &amp;quot;alt&amp;quot; attribute is used in cases where the image file cannot be found or for accessibility (for example, for blind users). Internet Explorer automatically -- and incorrectly -- displays the &amp;quot;alt&amp;quot; attribute as a tooltip. This means that image tooltips created by JHTML::tooltip (like the example above) will display with two tooltips when viewed with Internet Explorer, as shown below.&#039;&#039;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
[[Image:Tooltip_tutorial_ie7bug_20090301.png|center|frame]]&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;You can avoid this problem either by using text tooltips or by not using this method for image tooltips. Instead, just enter the HTML manually and set the &amp;quot;alt&amp;quot; attribute to an empty string (alt=&amp;quot;&amp;quot;).&#039;&#039;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This code is almost the same as above except the image will not be a link (because the &amp;quot;$href&amp;quot; argument is omitted).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JHTML::tooltip(&#039;This is the tooltip text&#039;, &#039;Tooltip title&#039;, &lt;br /&gt;
               &#039;tooltip.png&#039;, &#039;&#039;, &#039;&#039;, false);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A tooltip can be attached to an image or to text. For example, this code &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
echo JHTML::tooltip(&#039;This is a tooltip attached to text&#039;, &#039;Text Tooltip Title&#039;, &lt;br /&gt;
	            &#039;&#039;, &#039;Hover on this text to see the tooltip&#039;);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will show a tooltip attached to text, as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:Tooltip_tutorial_example_screenshot2_20090208.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
Note that specifying the &amp;quot;$text&amp;quot; parameter will override any image you have passed to tooltip.&lt;br /&gt;
&lt;br /&gt;
===Create a Tooltip Using a CSS Class Name===&lt;br /&gt;
If we look at the HTML page source generated by the &amp;lt;code&amp;gt;JHTML::tooltip&amp;lt;/code&amp;gt; function above, here is what we see:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;editlinktip hasTip&amp;quot; &lt;br /&gt;
      title=&amp;quot;Text Tooltip Title::This is a tooltip attached to text&amp;quot; &lt;br /&gt;
      style=&amp;quot;text-decoration: none; color: #333;&amp;quot;&amp;gt;&lt;br /&gt;
      Hover on this text to see the tooltip&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This function generates an HTML &amp;quot;span&amp;quot; tag with the classes &amp;quot;editlinktip&amp;quot; and &amp;quot;hasTip&amp;quot; and an attribute called &amp;quot;title&amp;quot;. Notice that the the &amp;quot;title&amp;quot; attribute has two parts, &amp;lt;code&amp;gt;&amp;lt;tooltip title&amp;gt;::&amp;lt;tooltip text&amp;gt;&amp;lt;/code&amp;gt; (for example, &amp;quot;Tooltip Title::This is the tooltip text&amp;quot;). You can create a tooltip with only text or with only a title. The title has implications for styling, as we&#039;ll see below.&lt;br /&gt;
&lt;br /&gt;
The Javascript inserted by the &amp;lt;code&amp;gt;JHTML::(&#039;behavior_tooltip&#039;)&amp;lt;/code&amp;gt; command we entered earlier picks up this tag based on the class called &amp;quot;hasTip&amp;quot;. So, a second way of creating a tooltip is to simply create a tag with a class called &amp;quot;hasTip&amp;quot; and an attribute of &amp;quot;title&amp;quot;. For example, this code&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;hasTip&amp;quot; &lt;br /&gt;
   title=&amp;quot;Text Tooltip Title::This is a tooltip attached to text&amp;quot;&amp;gt;&lt;br /&gt;
   Hover on this text to see the tooltip&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
will produce exactly the same effect as the &amp;lt;code&amp;gt;JHTML::tooltip()&amp;lt;/code&amp;gt; example above.&lt;br /&gt;
&lt;br /&gt;
===Adding CSS Styling to the Tooltip===&lt;br /&gt;
The default tooltips, whether using the JHTML::tooltip method or class method, use the following three CSS classes: &amp;lt;tt&amp;gt;.tool-tip&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;.tool-title&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;.tool-text&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Here are the default styles.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
/* Tooltips */&lt;br /&gt;
.tool-tip {&lt;br /&gt;
   float: left;&lt;br /&gt;
   background: #ffc;&lt;br /&gt;
   border: 1px solid #D4D5AA;&lt;br /&gt;
   padding: 5px;&lt;br /&gt;
   max-width: 200px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tool-title {&lt;br /&gt;
   padding: 0;&lt;br /&gt;
   margin: 0;&lt;br /&gt;
   font-size: 100%;&lt;br /&gt;
   font-weight: bold;&lt;br /&gt;
   margin-top: -15px;&lt;br /&gt;
   padding-top: 15px;&lt;br /&gt;
   padding-bottom: 5px;&lt;br /&gt;
   background: url(../images/selector-arrow.png) no-repeat;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.tool-text {&lt;br /&gt;
   font-size: 100%;&lt;br /&gt;
   margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a custom CSS file, copy this code and alter it to your liking. Note that the &amp;lt;tt&amp;gt;.tool-title&amp;lt;/tt&amp;gt; class uses by default the &amp;quot;selector-arrow.png&amp;quot; image. This is what gives the outline of the tooltip the little pointer in the upper left of the tooltip box. If you leave out a title in your tooltip, you will just get a rectangle, without the pointer.&lt;br /&gt;
&lt;br /&gt;
===Customizing Your Tooltips===&lt;br /&gt;
Ok, now it&#039;s time to have some fun. The &amp;lt;code&amp;gt;JHTML::_(&#039;behavior.tooltip&#039;)&amp;lt;/code&amp;gt; can take two optional parameters. The first parameter is the name of the CSS class that will be used to identify the tooltip. As we saw earlier, this defaults to &amp;quot;hasTip&amp;quot;. The second optional parameter is an array of parameters that you can use to fine-tune the tooltip functionality. These are explained below. &lt;br /&gt;
* &#039;&#039;&#039;maxTitleChars:&#039;&#039;&#039; The maximum length of the title (the part of the &amp;quot;title&amp;quot; attribute before the &amp;quot;::&amp;quot;)&lt;br /&gt;
* &#039;&#039;&#039;showDelay, hideDelay:&#039;&#039;&#039; The time to delay showing or hiding the tooltip, in milliseconds. Default is 100.&lt;br /&gt;
* &#039;&#039;&#039;className:&#039;&#039;&#039; The first part of the class name used to style the actual tooltip. The default, as we saw, is &amp;quot;tool&amp;quot;, and the full class names by default are &amp;quot;tool-tip&amp;quot;, &amp;quot;tool-title&#039;, and &amp;quot;tool-text&amp;quot;. So, for example, if we set this to &amp;quot;custom&amp;quot;, we would style the classes &amp;quot;custom-tip&amp;quot;, &amp;quot;custom-title&amp;quot;, and &amp;quot;custom-text&amp;quot;.&lt;br /&gt;
* &#039;&#039;&#039;fixed:&#039;&#039;&#039; Whether or not to have the tooltip move with the mouse. If set to &amp;quot;true&amp;quot;, the tooltip will be centered below the text or image. If set to &amp;quot;false&amp;quot;, the tooltip will move with the mouse. Default is &amp;quot;false&amp;quot;. &lt;br /&gt;
* &#039;&#039;&#039;onShow, onHide:&#039;&#039;&#039; Functions to call for the onShow and onHide events. We&#039;ll see an example below where we can use these to create a fade-in and fade-out for the tooltip.&lt;br /&gt;
&lt;br /&gt;
In the next section, we&#039;ll show how to use these parameters with some examples.&lt;br /&gt;
&lt;br /&gt;
===Tooltip With Different Classes===&lt;br /&gt;
In this example, we will create a tooltip using different selector and tooltip styling classes. Why might we want to do this? One reason would be if we had different types of tooltips and we wanted to style them differently.&lt;br /&gt;
&lt;br /&gt;
Here is the code to create the tooltip Javascript function:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$toolTipArray = array(&#039;className&#039;=&amp;gt;&#039;custom2&#039;);&lt;br /&gt;
JHTML::_(&#039;behavior.tooltip&#039;, &#039;.hasTip2&#039;, $toolTipArray);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
In this code, we are creating an array with just one element -- to set the &amp;quot;className&amp;quot; parameter to &amp;quot;custom2&amp;quot;. This means that, to style these tooltips, we would use the classes &amp;lt;tt&amp;gt;custom2-tip&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;custom2-title&amp;lt;/tt&amp;gt;, and &amp;lt;tt&amp;gt;custom2-text&amp;lt;/tt&amp;gt;. Then we call the method with the arguments &amp;quot;.hasTip2&amp;quot; and the array &amp;quot;$toolTipArray&amp;quot;. It can be a little confusing, because we have two CSS classes at work here. The class &amp;quot;.hasTip2&amp;quot; is used in the HTML tag. That is how the Javascript program identifies the tooltips to operate on. The class &amp;quot;custom2&amp;quot; is used as the first part of the three CSS classes to use to style the actual tooltip itself.&lt;br /&gt;
&lt;br /&gt;
To use this new tooltip, we could use the following code:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;hasTip2&amp;quot; &lt;br /&gt;
	title=&amp;quot;My Tooltip Title :: Tooltip text for hasTip2 class with custom2 style classes.&amp;quot;&amp;gt;&lt;br /&gt;
	hasTip2 and custom2 example&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Since we set the class to &amp;quot;hasTip2&amp;quot;, this tag will be processed by the new version of the tooltip program. So, if we use both the default tooltip (&amp;quot;hasTip&amp;quot; class) and the new tooltip (&amp;quot;hasTip2&amp;quot; class) in the same page, we can style them differently using &amp;quot;tool-&amp;quot; styles for the default and &amp;quot;custom2-&amp;quot; styles for the &amp;quot;hasTip2&amp;quot; tooltips.&lt;br /&gt;
&lt;br /&gt;
Next, let&#039;s look at a more complex example, shown below.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$toolTipArray = array(&#039;className&#039; =&amp;gt; &#039;custom2&#039;, &#039;showDelay&#039;=&amp;gt;&#039;500&#039;, &lt;br /&gt;
   &#039;hideDelay&#039;=&amp;gt;&#039;500&#039;, &#039;fixed&#039;=&amp;gt;true,&lt;br /&gt;
   &#039;onShow&#039;=&amp;gt;&amp;quot;function(tip) {tip.effect(&#039;opacity&#039;, &lt;br /&gt;
      {duration: 500, wait: false}).start(0,1)}&amp;quot;, &lt;br /&gt;
   &#039;onHide&#039;=&amp;gt;&amp;quot;function(tip) {tip.effect(&#039;opacity&#039;, &lt;br /&gt;
      {duration: 500, wait: false}).start(1,0)}&amp;quot;);&lt;br /&gt;
JHTML::_(&#039;behavior.tooltip&#039;, &#039;.hasTip2&#039;, $toolTipArray); ?&amp;gt; &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Again, we are building an array to pass to the &amp;lt;code&amp;gt;JHTML::_(&#039;behavior.tooltip&#039;)&amp;lt;/code&amp;gt; function. Again, we are setting the &amp;quot;className&amp;quot; parameter to &amp;quot;custom2&amp;quot;. We are also setting the &amp;quot;showDelay&amp;quot; and &amp;quot;hideDelay&amp;quot; parameters to 500 milliseconds (.5 seconds). So the tooltip will show only after the mouse has hovered for this amount of time. &lt;br /&gt;
&lt;br /&gt;
Notice that we are setting the parameter &amp;quot;fixed&amp;quot; to &amp;quot;true&amp;quot; (without the quotes). This means that the tooltip will not move with the mouse. Instead, it will always show centered below the tooltip text or image.&lt;br /&gt;
&lt;br /&gt;
Finally, the tricky part. We are creating functions to pass in to the &amp;quot;onShow&amp;quot; and &amp;quot;onHide&amp;quot; events. These functions cause the tooltip to fade in and fade out over the space of 500 milliseconds. This is done by gradually varying the tooltip&#039;s CSS &amp;quot;opacity&amp;quot; style from &amp;quot;0&amp;quot; (completely transparent) to &amp;quot;1&amp;quot; (completely opaque). If we wanted the tooltip to be partially transparent, we could change these to &amp;lt;code&amp;gt;start(0,.8)&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;start(.8,0)&amp;lt;/code&amp;gt;. &lt;br /&gt;
&lt;br /&gt;
These functions are similar to the sample code in the [http://demos111.mootools.net/Tips MooTools demo tutorial]. Click on the link called &amp;quot;js code&amp;quot; and look at the code for the &amp;quot;Tips2&amp;quot; demo. We have just taken the code from the initialize function and incorporated it into the &amp;quot;onShow&amp;quot; and &amp;quot;onHide&amp;quot; functions.&lt;br /&gt;
&lt;br /&gt;
The last line of code above creates the actual Javascript code in our Joomla! document. If we show the page and view source, we see the following:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEvent(&#039;domready&#039;, function(){ &lt;br /&gt;
   var JTooltips = new Tips($$(&#039;.hasTip2&#039;), {&lt;br /&gt;
      maxTitleChars: 50, showDelay: 500, hideDelay: 500, className: &#039;custom2&#039;, &lt;br /&gt;
         fixed: true, &lt;br /&gt;
      onShow: function(tip) {tip.effect(&#039;opacity&#039;, {duration: 500, wait: false}).start(0,1)}, &lt;br /&gt;
      onHide: function(tip) {tip.effect(&#039;opacity&#039;, {duration: 500, wait: false}).start(1,0)}&lt;br /&gt;
   }); &lt;br /&gt;
});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
So we can see the effect of the parameters that we passed to the &amp;lt;code&amp;gt;JHTML::_(&#039;behavior.tooltip&#039;)&amp;lt;/code&amp;gt; method.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;offsets Parameter&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&#039;&#039;Note: The &amp;quot;offsets&amp;quot; parameter doesn&#039;t work in version 1.5.9 and earlier because of a bug. As of version 1.5.10 it should work as outlined below.&#039;&#039;&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
You can control the x and y distance, in pixels, from the cursor to the tooltip using the &amp;quot;offsets&amp;quot; parameter. This parameter must be an array as shown in the example code below:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// set x (horizontal) distance to 20 pixels, y (vertical) distance to 30 pixels&lt;br /&gt;
$toolTipArray = array(&#039;offsets&#039;=&amp;gt;array(&#039;x&#039;=&amp;gt;20, &#039;y&#039;=&amp;gt;30), &#039;maxtitlechars&#039;=&amp;gt;40);&lt;br /&gt;
JHTML::_(&#039;behavior.tooltip&#039;, &#039;.customOffset&#039;, $toolTipArray);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using an External Javascript File===&lt;br /&gt;
There are times when you might prefer to work with a separate Javascript file. This gives you complete flexibility to use all of the mootools capabilities. To do this:&lt;br /&gt;
# Create the separate Javascript file and save it somewhere in your Joomla! site (for example, &amp;quot;templates/&amp;lt;your template&amp;gt;/js/yourjsfile.js&amp;quot;.&lt;br /&gt;
# Use the &amp;lt;code&amp;gt;JHTML::script&amp;lt;/code&amp;gt; function to add this script to your document. For example: &lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
   $filename = &#039;testtooltip.js&#039;; // this file is used for class=&amp;quot;hasTip3&amp;quot; titles&lt;br /&gt;
   $path = &#039;templates/rhuk_milkyway/js/&#039;; // path to the file&lt;br /&gt;
   // true means MooTools will load if it is not already loaded&lt;br /&gt;
   JHTML::script($filename, $path, true); &lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This will load your script into the document and make sure that the MooTools library is available.&lt;br /&gt;
&lt;br /&gt;
===Complete Code Example===&lt;br /&gt;
Here is an example that incorporates all of the elements discussed in this tutorial. So you can see the code in action, we will create an override of the &amp;quot;mod_stats&amp;quot; Module and add our test code there. We will use the rhuk_milkyway template.&lt;br /&gt;
&lt;br /&gt;
To set up the template override, create a folder called &amp;quot;templates/rhuk_milkyway/html/mod_stats&amp;quot; and copy the file &amp;quot;modules/mod_stats/tmpl/default.php&amp;quot; to this new folder.&lt;br /&gt;
&lt;br /&gt;
After line 2 of this file (&amp;lt;code&amp;gt;defined(&#039;_JEXEC&#039;) or die(&#039;Restricted access&#039;);&amp;lt;/code&amp;gt;), insert the following:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JHTML::_(&#039;behavior.tooltip&#039;);&lt;br /&gt;
$toolTipArray = array(&#039;className&#039; =&amp;gt; &#039;custom2&#039;, &#039;showDelay&#039;=&amp;gt;&#039;500&#039;, &#039;hideDelay&#039;=&amp;gt;&#039;500&#039;, &lt;br /&gt;
   &#039;fixed&#039;=&amp;gt;&#039;true&#039; &lt;br /&gt;
   , &#039;onShow&#039;=&amp;gt;&amp;quot;function(tip) {tip.effect(&#039;opacity&#039;, &lt;br /&gt;
        {duration: 500, wait: false}).start(0,1)}&amp;quot;&lt;br /&gt;
   , &#039;onHide&#039;=&amp;gt;&amp;quot;function(tip) {tip.effect(&#039;opacity&#039;, &lt;br /&gt;
        {duration: 500, wait: false}).start(1,0)}&amp;quot;);&lt;br /&gt;
JHTML::_(&#039;behavior.tooltip&#039;, &#039;.hasTip2&#039;, $toolTipArray);  // class=&amp;quot;hasTip2&amp;quot; titles&lt;br /&gt;
$filename = &#039;testtooltip.js&#039;; // used for class=&amp;quot;hasTip3&amp;quot; titles&lt;br /&gt;
$path = &#039;templates/rhuk_milkyway/js/&#039;;&lt;br /&gt;
JHTML::script($filename, $path, true); // MooTools will load if it is not already loaded&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Here we are creating the Javascript functions we will need later. The first line is the simple default declaration that will use the &amp;quot;.hasTip&amp;quot; and &amp;quot;tool-&amp;quot; CSS classes. &lt;br /&gt;
&lt;br /&gt;
The next 5 lines create the more customized function that includes the fade-in and fade-out. It uses the &amp;quot;.hasTip2&amp;quot; to create the tip and the classes starting with &amp;quot;custom2-&amp;quot; to style the tooltip.&lt;br /&gt;
&lt;br /&gt;
The last 3 lines reference the external Javascript file, which will be created below. The class information will be contained in that file.&lt;br /&gt;
&lt;br /&gt;
Now, time for some more coding. At the end of the &amp;quot;modules/mod_stats/tmpl/default.php&amp;quot; file, add the code shown below:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;Tooltip Examples&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;?php echo JHTML::tooltip(&#039;This is the tooltip text&#039;, &#039;Tooltip title&#039;, &lt;br /&gt;
	&#039;tooltip.png&#039;, &#039;&#039;, &#039;http://www.joomla.org&#039;);?&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;?php echo JHTML::tooltip(&#039;This is a tooltip attached to text&#039;, &#039;Text Tooltip Title&#039;, &lt;br /&gt;
	&#039;&#039;, &#039;Hover on this text to see the tooltip&#039;);?&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;							&lt;br /&gt;
&amp;lt;a class=&amp;quot;hasTip&amp;quot; title=&amp;quot;My Title::Tooltip on &#039;a&#039; tag text using default &#039;hasTip&#039; class&amp;quot; &lt;br /&gt;
	href=&amp;quot;http://www.joomla.org&amp;quot;&amp;gt;Tooltip on a link example&amp;lt;/a&amp;gt; &lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;hasTip2&amp;quot; &lt;br /&gt;
	title=&amp;quot;My Tooltip Title :: Tooltip text for hasTip2 class with custom2 style classes.&amp;quot;&amp;gt;&lt;br /&gt;
	hasTip2 and custom2 example&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;span class=&amp;quot;hasTip3&amp;quot; &lt;br /&gt;
	title=&amp;quot;hasTip3 Title::This is using class &#039;hasTip3&#039; using external JS script.&amp;quot;&amp;gt;&lt;br /&gt;
           hasTip3 hover text&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The first two examples using the &amp;lt;code&amp;gt;JHTML::tooltip&amp;lt;/code&amp;gt; function to create the tooltip HTML code. &lt;br /&gt;
&lt;br /&gt;
The third example shows an &amp;quot;a&amp;quot; tag with a tooltip. This illustrates that you can put tooltips on most HTML tags, not just &amp;quot;span&amp;quot; tags. Again, it is using the &amp;quot;hasTip&amp;quot; class, so it will be controlled by the Javascript above called with the &amp;quot;.hasTip&amp;quot; argument and will be styled with the default &amp;quot;tool-&amp;quot; styles.&lt;br /&gt;
&lt;br /&gt;
The fourth example shows a &amp;quot;span&amp;quot; tag using the &amp;quot;hasTip2&amp;quot; class. So it will be styled using the &amp;quot;custom2-&amp;quot; classes and will have the &amp;quot;showDelay&amp;quot; and &amp;quot;hideDelay&amp;quot; of 500 milliseconds and have &amp;quot;fixed&amp;quot; equal to &amp;quot;true&amp;quot; (so the tip will not move with the mouse). Also, it uses the special fade-in and fade-out effects. &lt;br /&gt;
&lt;br /&gt;
The last example will use the Javascript code from the external file, shown below.&lt;br /&gt;
&lt;br /&gt;
Now, some more coding. Create a JavaScript file called &amp;quot;testtooltip.js&amp;quot; and save it into the folder &amp;quot;templates/rhuk_milkyway/js&amp;quot;:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
window.addEvent(&#039;domready&#039;, function(){&lt;br /&gt;
	   //do your tips stuff in here...&lt;br /&gt;
	   var zoomTip = new Tips($$(&#039;.hasTip3&#039;), {&lt;br /&gt;
	      className: &#039;custom3&#039;, //this is the prefix for the CSS class&lt;br /&gt;
	      offsets: {&lt;br /&gt;
	  		&#039;x&#039;: 20,       //default is 16&lt;br /&gt;
	  		&#039;y&#039;: 30        //default is 16&lt;br /&gt;
              },&lt;br /&gt;
	      initialize:function(){&lt;br /&gt;
	         this.fx = new Fx.Style(this.toolTip, &#039;opacity&#039;, &lt;br /&gt;
	        		 {duration: 1000, wait: false}).set(0);&lt;br /&gt;
	      },&lt;br /&gt;
	      onShow: function(toolTip) {&lt;br /&gt;
	         this.fx.start(0,.8);&lt;br /&gt;
	      },&lt;br /&gt;
	      onHide: function(toolTip) {&lt;br /&gt;
	         this.fx.start(.8,0);&lt;br /&gt;
	      }&lt;br /&gt;
	   });&lt;br /&gt;
	});&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This code will operate on the &amp;quot;hasTip3&amp;quot; class and will use style classes starting with &amp;quot;custom3-&amp;quot;. We are setting the x distance (from the cursor to the tooltip) to 20 pixels and the y distance to 30 pixels. This also has the fade-in and fade-out functionality, but the final &amp;quot;opacity&amp;quot; value is set to .8, meaning that the tooltip will be slightly transparent.&lt;br /&gt;
&lt;br /&gt;
Finally, add this to the end of your &amp;quot;templates/rhuk_milkyway/css/template.css&amp;quot; file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;css&amp;quot;&amp;gt;&lt;br /&gt;
.custom2-tip {&lt;br /&gt;
	color: #000;&lt;br /&gt;
	width: 130px;&lt;br /&gt;
	z-index: 13000;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
.custom2-title {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 11px;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	color: #024A68;&lt;br /&gt;
	padding: 8px 8px 4px;&lt;br /&gt;
	background: #3CA0D0;&lt;br /&gt;
	border-bottom: 1px solid #024A68;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
.custom2-text {&lt;br /&gt;
	font-size: 11px;&lt;br /&gt;
	padding: 4px 8px 8px;&lt;br /&gt;
	background: #63ADD0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.custom3-tip {&lt;br /&gt;
	color: #000;&lt;br /&gt;
	width: 130px;&lt;br /&gt;
	z-index: 13000;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
.custom3-title {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 11px;&lt;br /&gt;
	margin: 0;&lt;br /&gt;
	color: #3E4F14;&lt;br /&gt;
	padding: 8px 8px 4px;&lt;br /&gt;
	background: #C3DF7D;&lt;br /&gt;
	border-bottom: 1px solid #B5CF74;&lt;br /&gt;
}&lt;br /&gt;
 &lt;br /&gt;
.custom3-text {&lt;br /&gt;
	font-size: 11px;&lt;br /&gt;
	padding: 4px 8px 8px;&lt;br /&gt;
	background: #CFDFA7;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Here we are just adding different colors for the &amp;quot;custom2-&amp;quot; and &amp;quot;custom3-&amp;quot; styles so you can see the effect of the different tooltip code.&lt;br /&gt;
&lt;br /&gt;
Notice that &amp;lt;tt&amp;gt;.custom2-title&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;.custom3-title&amp;lt;/tt&amp;gt; classes do not have a background property. So these tooltips will be a box without the neat little arrow pointing at the mouse. If you wanted, you could create an image similar to &amp;quot;templates/system/images/selector-arrow.png&amp;quot; of the right color and add that as a background to these classes.&lt;br /&gt;
&lt;br /&gt;
===Example Code Screenshots===&lt;br /&gt;
Here are some screenshots taken from the sample code above. The first screenshot shows the modified &amp;quot;mod_stats&amp;quot; modules with our sample code.&lt;br /&gt;
[[Image:Screen_tooltip_example2_20090210.png|center|frame]]&lt;br /&gt;
The screenshot below shows the fade-in effect for the &amp;quot;.hasTip2&amp;quot; tooltip. Notice also that the tooltip is centered below the text. This is the effect of setting &amp;quot;fixed&amp;quot; equal to &amp;quot;true&amp;quot;.&lt;br /&gt;
[[Image:Screen_tooltip_example1_20090209.png|center|frame]]&lt;br /&gt;
The last screenshot shows the different styling for the &amp;quot;.hasTip3&amp;quot; tooltip, based on the &amp;quot;custom3-&amp;quot; CSS class styles. &lt;br /&gt;
[[Image:Screen_tooltip_example3_20090210.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
===More Information===&lt;br /&gt;
More information about the topics covered in this tutorial is available at the links below. Note that Joomla! version 1.5 uses MooTools version 1.11. The current version of MooTools is 1.2.&lt;br /&gt;
* Joomla API - [http://api.joomla.org http://api.joomla.org]&lt;br /&gt;
* Documentation for 1.11 MooTools Tips: [http://docs111.mootools.net/Plugins/Tips.js http://docs111.mootools.net/Plugins/Tips.js]&lt;br /&gt;
* Mootools demos for version 1.11 - [http://demos111.mootools.net/Tips http://demos111.mootools.net/Tips]&lt;br /&gt;
* Mootools Website - [http://www.mootools.net/ http://www.mootools.net/]&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:Creating_a_search_plugin&amp;diff=20566</id>
		<title>J1.5:Creating a search plugin</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:Creating_a_search_plugin&amp;diff=20566"/>
		<updated>2009-12-03T20:03:46Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: /* PHP file */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Plugins]]&lt;br /&gt;
==Description==&lt;br /&gt;
This document is about how to create a Search Plugin. You can use a Search Plugin to search through the database of your Joomla! site. To create a plugin, you will at least need two files; an XML file and a PHP file. For internationalization it is good to create an INI file as well. &lt;br /&gt;
&lt;br /&gt;
==XML file==&lt;br /&gt;
The XML file is named the same as the PHP file, and is one of the two required files.&lt;br /&gt;
Always start off with the XML tag and define that it is written in a UTF-8 format.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;!DOCTYPE install PUBLIC &lt;br /&gt;
  &amp;quot;-//Joomla! 1.5//DTD plugin 1.0//EN&amp;quot; &amp;quot;http://dev.joomla.org/xml/1.5/plugin-install.dtd&amp;quot;&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
To define that the plugin has to be a search plugin, add this line:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;install version=&amp;quot;1.5&amp;quot; type=&amp;quot;plugin&amp;quot; group=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
The type will define it is a plugin, the group defines the Plugin is in the group of search plugins.&lt;br /&gt;
&lt;br /&gt;
After that, add some information about yourself and the plugin, like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;name&amp;gt;Name of your search plugin&amp;lt;/name&amp;gt;&lt;br /&gt;
&amp;lt;creationDate&amp;gt;Creation date&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
&amp;lt;author&amp;gt;Your name&amp;lt;/author&amp;gt;&lt;br /&gt;
&amp;lt;authorEmail&amp;gt;Your e-mail address&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
&amp;lt;authorUrl&amp;gt;Your website&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
&amp;lt;copyright&amp;gt;Copyright information&amp;lt;/copyright&amp;gt;&lt;br /&gt;
&amp;lt;license&amp;gt;License, for example GNU/GPL&amp;lt;/license&amp;gt;&lt;br /&gt;
&amp;lt;version&amp;gt;Version of the plugin&amp;lt;/version&amp;gt;&lt;br /&gt;
&amp;lt;description&amp;gt;Description of the plugin; showed during installation and when editing &lt;br /&gt;
the plugin in the Plugin Manager&amp;lt;/description&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
And now, include your PHP file to the Search Plugin. The name of this file should be the same as the name of this XML file. Put this name also behind the plugin=&amp;quot;&amp;quot; part. &lt;br /&gt;
&lt;br /&gt;
You could also add more files for your plugin, for example an image. Just add another row between &amp;lt;files&amp;gt; and &amp;lt;/file&amp;gt;, and then place the file between &amp;lt;filename&amp;gt; tags.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;files&amp;gt;&lt;br /&gt;
   &amp;lt;filename plugin=&amp;quot;nameofplugin&amp;quot;&amp;gt;nameofplugin.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
&amp;lt;/files&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the internationalization, we will use language files. This is not required, but people from other countries will love it they can easily translate your plugin to their own language.&lt;br /&gt;
The language tags can be found here: [http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes] (use the ISO 639-1 column) and here: [http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements]&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;languages&amp;gt;&lt;br /&gt;
   &amp;lt;language tag=&amp;quot;en-GB&amp;quot;&amp;gt;language/en-GB/en-GB.plg_search_nameofplugin.ini&amp;lt;/language&amp;gt;&lt;br /&gt;
&amp;lt;/languages&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
Optionally, you could add some parameters to the plugin. These will look like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;params&amp;gt;&lt;br /&gt;
   &amp;lt;param name=&amp;quot;paramname&amp;quot; type=&amp;quot;typeofparameter&amp;quot; default=&amp;quot;defaultsetting&amp;quot; label=&amp;quot;title&amp;quot; description=&amp;quot;description&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/params&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;Param name:&#039;&#039;&#039; The name of the parameter. You will need this when creating the PHP file.&lt;br /&gt;
*&#039;&#039;&#039;Param type:&#039;&#039;&#039; You could choose between several types of parameters. Look at this document to learn something about the different types: [http://docs.joomla.org/Using_the_core_parameter_types] &lt;br /&gt;
*&#039;&#039;&#039;Param default:&#039;&#039;&#039; The default setting for this parameter.&lt;br /&gt;
*&#039;&#039;&#039;Param label:&#039;&#039;&#039; The name of this parameter displayed in the edit screen of this plugin in the Plugin Manager.&lt;br /&gt;
*&#039;&#039;&#039;Param description:&#039;&#039;&#039; The text which appears as a tool tip for this parameter. &lt;br /&gt;
&lt;br /&gt;
And do not forget to end your XML file with the following tag:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;/install&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PHP file==&lt;br /&gt;
The PHP file of your plugin is probably the most important file of the plugin. This is an example PHP file of a search plugin. The comments are included. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;PHP&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
//First start with information about the Plugin and yourself. For example:&lt;br /&gt;
/**&lt;br /&gt;
 * @version		$Id: nameofplugin.php versionnumber date author&lt;br /&gt;
 * @copyright	        Copyright&lt;br /&gt;
 * @license		License, for example GNU/GPL&lt;br /&gt;
 * All other information you would like to add&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
//To prevent accessing the document directly, enter this code:&lt;br /&gt;
// no direct access&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
//Now define the registerEvent and the language file. Replace &#039;nameofplugin&#039; with the name of your plugin.&lt;br /&gt;
$mainframe-&amp;gt;registerEvent( &#039;onSearch&#039;, &#039;plgSearchnameofplugin&#039; );&lt;br /&gt;
$mainframe-&amp;gt;registerEvent( &#039;onSearchAreas&#039;, &#039;plgSearchnameofpluginAreas&#039; );&lt;br /&gt;
&lt;br /&gt;
JPlugin::loadLanguage( &#039;plg_search_nameofplugin&#039; );&lt;br /&gt;
&lt;br /&gt;
//Then define a function to return an array of search areas. Replace &#039;nameofplugin&#039; with the name of your plugin.&lt;br /&gt;
function &amp;amp;plgSearchnameofpluginAreas()&lt;br /&gt;
{&lt;br /&gt;
	static $areas = array(&lt;br /&gt;
		&#039;nameofplugin&#039; =&amp;gt; &#039;Nameofplugin&#039;&lt;br /&gt;
	);&lt;br /&gt;
	return $areas;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Then the real function has to be created. The database connection should be made. &lt;br /&gt;
//The function will be closed with an } at the end of the file.&lt;br /&gt;
function plgSearchnameofplugin( $text, $phrase=&#039;&#039;, $ordering=&#039;&#039;, $areas=null )&lt;br /&gt;
{&lt;br /&gt;
	$db		=&amp;amp; JFactory::getDBO();&lt;br /&gt;
	$user	=&amp;amp; JFactory::getUser(); &lt;br /&gt;
&lt;br /&gt;
//If the array is not correct, return it:&lt;br /&gt;
	if (is_array( $areas )) {&lt;br /&gt;
		if (!array_intersect( $areas, array_keys( plgSearchnameofpluginAreas() ) )) {&lt;br /&gt;
			return array();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//It is time to define the parameters! First get the right plugin; &#039;search&#039; (the group), &#039;nameofplugin&#039;. &lt;br /&gt;
$plugin =&amp;amp; JPluginHelper::getPlugin(&#039;search&#039;, &#039;nameofplugin&#039;);&lt;br /&gt;
&lt;br /&gt;
//Then load the parameters of the plugin..&lt;br /&gt;
$pluginParams = new JParameter( $plugin-&amp;gt;params );&lt;br /&gt;
&lt;br /&gt;
//And define the parameters. For example like this..&lt;br /&gt;
$limit = $pluginParams-&amp;gt;def( &#039;nameofparameter&#039;, defaultsetting );&lt;br /&gt;
&lt;br /&gt;
//Use the function trim to delete spaces in front of or at the back of the searching terms&lt;br /&gt;
$text = trim( $text );&lt;br /&gt;
&lt;br /&gt;
//Return Array when nothing was filled in&lt;br /&gt;
if ($text == &#039;&#039;) {&lt;br /&gt;
		return array();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//After this, you have to add the database part. This will be the most difficult part, because this changes per situation.&lt;br /&gt;
//In the coding examples later on you will find some of the examples used by Joomla! 1.5 core Search Plugins.&lt;br /&gt;
//It will look something like this.&lt;br /&gt;
	$wheres = array();&lt;br /&gt;
	switch ($phrase) {&lt;br /&gt;
&lt;br /&gt;
//search exact&lt;br /&gt;
		case &#039;exact&#039;:&lt;br /&gt;
			$text		= $db-&amp;gt;Quote( &#039;%&#039;.$db-&amp;gt;getEscaped( $text, true ).&#039;%&#039;, false );&lt;br /&gt;
			$wheres2 	= array();&lt;br /&gt;
			$wheres2[] 	= &#039;LOWER(a.name) LIKE &#039;.$text;&lt;br /&gt;
			$where 		= &#039;(&#039; . implode( &#039;) OR (&#039;, $wheres2 ) . &#039;)&#039;;&lt;br /&gt;
			break;&lt;br /&gt;
&lt;br /&gt;
//search all or any&lt;br /&gt;
		case &#039;all&#039;:&lt;br /&gt;
		case &#039;any&#039;:&lt;br /&gt;
&lt;br /&gt;
//set default&lt;br /&gt;
		default:&lt;br /&gt;
			$words 	= explode( &#039; &#039;, $text );&lt;br /&gt;
			$wheres = array();&lt;br /&gt;
			foreach ($words as $word)&lt;br /&gt;
			{&lt;br /&gt;
				$word		= $db-&amp;gt;Quote( &#039;%&#039;.$db-&amp;gt;getEscaped( $word, true ).&#039;%&#039;, false );&lt;br /&gt;
				$wheres2 	= array();&lt;br /&gt;
				$wheres2[] 	= &#039;LOWER(a.name) LIKE &#039;.$word;&lt;br /&gt;
				$wheres[] 	= implode( &#039; OR &#039;, $wheres2 );&lt;br /&gt;
			}&lt;br /&gt;
			$where = &#039;(&#039; . implode( ($phrase == &#039;all&#039; ? &#039;) AND (&#039; : &#039;) OR (&#039;), $wheres ) . &#039;)&#039;;&lt;br /&gt;
			break;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//ordering of the results&lt;br /&gt;
	switch ( $ordering ) {&lt;br /&gt;
&lt;br /&gt;
//alphabetic, ascending&lt;br /&gt;
		case &#039;alpha&#039;:&lt;br /&gt;
			$order = &#039;a.name ASC&#039;;&lt;br /&gt;
			break;&lt;br /&gt;
&lt;br /&gt;
//oldest first&lt;br /&gt;
		case &#039;oldest&#039;:&lt;br /&gt;
&lt;br /&gt;
//popular first&lt;br /&gt;
		case &#039;popular&#039;:&lt;br /&gt;
&lt;br /&gt;
//newest first&lt;br /&gt;
		case &#039;newest&#039;:&lt;br /&gt;
&lt;br /&gt;
//default setting: alphabetic, ascending&lt;br /&gt;
		default:&lt;br /&gt;
			$order = &#039;a.name ASC&#039;;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//replace nameofplugin&lt;br /&gt;
	$searchnameofplugin = JText::_( &#039;Nameofplugin&#039; );&lt;br /&gt;
&lt;br /&gt;
//the database query; differs per situation! It will look something like this:&lt;br /&gt;
	$query = &#039;SELECT a.name AS title,&#039;&lt;br /&gt;
	. &#039; CONCAT_WS( &amp;quot; / &amp;quot;, &#039;. $db-&amp;gt;Quote($searchNameofplugin) .&#039;, b.title )AS section,&#039;&lt;br /&gt;
	. &#039; &amp;quot;1&amp;quot; AS browsernav&#039;&lt;br /&gt;
	. &#039; FROM #__nameofplugin AS a&#039;&lt;br /&gt;
	. &#039; INNER JOIN #__categories AS b ON b.id = a.catid&#039;&lt;br /&gt;
	. &#039; WHERE ( &#039;. $where .&#039; )&#039;&lt;br /&gt;
	. &#039; AND a.published = 1&#039;&lt;br /&gt;
	. &#039; AND b.access &amp;lt;= &#039;. (int) $user-&amp;gt;get( &#039;aid&#039; )&lt;br /&gt;
	. &#039; ORDER BY &#039;. $order&lt;br /&gt;
	;&lt;br /&gt;
&lt;br /&gt;
//Set query&lt;br /&gt;
	$db-&amp;gt;setQuery( $query, 0, $limit );&lt;br /&gt;
	$rows = $db-&amp;gt;loadObjectList();&lt;br /&gt;
&lt;br /&gt;
//The &#039;output&#039; of the displayed link&lt;br /&gt;
	foreach($rows as $key =&amp;gt; $row) {&lt;br /&gt;
		$rows[$key]-&amp;gt;href = &#039;index.php?option=com_newsfeeds&amp;amp;view=newsfeed&amp;amp;catid=&#039;.$row-&amp;gt;catslug.&#039;&amp;amp;id=&#039;.$row-&amp;gt;slug;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Return the search results in an array&lt;br /&gt;
return $rows;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are 4 variables that get passed in, which are evident by their names and use in the above code.&lt;br /&gt;
What&#039;s not obvious is what the function should return. An array of objects that the search tool uses to display the results. The results could alternatively have been assembled something like this.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
$rows[] = (object) array(&lt;br /&gt;
			&#039;href&#039;        =&amp;gt; &#039;index.php?option=com_newsfeeds&amp;amp;view=newsfeed&amp;amp;catid=&#039;.$row-&amp;gt;catslug.&#039;&amp;amp;id=&#039;.$row-&amp;gt;slug,&lt;br /&gt;
			&#039;title&#039;       =&amp;gt; $row[&#039;name&#039;],&lt;br /&gt;
			&#039;section&#039;     =&amp;gt; $searchnameofplugin,&lt;br /&gt;
			&#039;created&#039;     =&amp;gt; $row[&#039;date&#039;],&lt;br /&gt;
			&#039;text&#039;        =&amp;gt; $row[&#039;name&#039;],&lt;br /&gt;
			&#039;browsernav&#039;  =&amp;gt; &#039;1&#039;&lt;br /&gt;
		);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==INI file(s)==&lt;br /&gt;
For internationalization it is good to use the INI files. You can add everything to the language file that outputs text to the user, in this order:&lt;br /&gt;
*XML description tag&lt;br /&gt;
*XML label and description attributes from parameters&lt;br /&gt;
*JText::_( &#039;string&#039; ) used by the plugin&lt;br /&gt;
&lt;br /&gt;
Start your INI file with something like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;INI&amp;quot;&amp;gt;# $Id: en-GB.plg_search_nameofplugin.ini&lt;br /&gt;
# Joomla! Project&lt;br /&gt;
# Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.&lt;br /&gt;
# License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php&lt;br /&gt;
# Note : All ini files need to be saved as UTF-8 - No BOM&amp;lt;/source&amp;gt;&lt;br /&gt;
Of course, you could also add other information, like the author. &lt;br /&gt;
&lt;br /&gt;
For example, this parameter:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&amp;lt;param name=&amp;quot;search_limit&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;5&amp;quot; default=&amp;quot;50&amp;quot; label=&amp;quot;Search Limit&amp;quot; &lt;br /&gt;
description=&amp;quot;Number of Search items to return&amp;quot;/&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
Will cause the following output in the INI file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;INI&amp;quot;&amp;gt;&lt;br /&gt;
SEARCH LIMIT=Search Limit&lt;br /&gt;
NUMBER OF SEARCH ITEMS TO RETURN=Number of Search items to return&amp;lt;/source&amp;gt;&lt;br /&gt;
The file looks repetitive, but will be very useful for translaters.&lt;br /&gt;
&lt;br /&gt;
When you want to make your search plugin available in more languages, first add them to the &amp;lt;languages&amp;gt; tag in the XML file. Then create the same INI file, and change the part after the =, for example the dutch version would be:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;INI&amp;quot;&amp;gt;&lt;br /&gt;
SEARCH LIMIT=Zoek limiet&lt;br /&gt;
NUMBER OF SEARCH ITEMS TO RETURN=Aantal weer te geven zoekresultaten&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Coding examples==&lt;br /&gt;
There are six Joomla! Core Search Plugins. If you look at them you can learn a lot, especially about the query part.&lt;br /&gt;
You can see them &#039;working&#039; when you go to the back-end of your Joomla! 1.5 installation, then go to the menu &#039;Extensions&#039; and select the &#039;Plugin Manager&#039;. Click on the name of the plugin to edit it; and see it working.&lt;br /&gt;
*Plugin Search - Categories&lt;br /&gt;
**\plugins\search\categories.XML&lt;br /&gt;
**\plugins\search\categories.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_categories.INI&lt;br /&gt;
*Plugin Search - Contacts&lt;br /&gt;
**\plugins\search\contacts.XML&lt;br /&gt;
**\plugins\search\contacts.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_contacts.INI&lt;br /&gt;
*Plugin Search - Content&lt;br /&gt;
**\plugins\search\content.XML&lt;br /&gt;
**\plugins\search\content.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_content.INI&lt;br /&gt;
*Plugin Search - Newsfeeds&lt;br /&gt;
**\plugins\search\newsfeeds.XML&lt;br /&gt;
**\plugins\search\newsfeeds.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_newsfeeds.INI&lt;br /&gt;
*Plugin Search - Sections&lt;br /&gt;
**\plugins\search\sections.XML&lt;br /&gt;
**\plugins\search\sections.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_sections.INI&lt;br /&gt;
*Plugin Search - Weblinks&lt;br /&gt;
**\plugins\search\weblinks.XML&lt;br /&gt;
**\plugins\search\weblinks.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_weblinks.INI&lt;br /&gt;
&lt;br /&gt;
==Quick tips==&lt;br /&gt;
*In the PHP file, people often forget to place an semicolon (;) at the end of a row. This causes errors. Check this before you test your plugin.&lt;br /&gt;
*Make sure the parameters in the XML file are closed correctly. When you add options, for example, you need to close it with &amp;lt;/param&amp;gt;.&lt;br /&gt;
*It is easy to test on a localhost when you are still busy with editing your plugin.&lt;br /&gt;
*When making a zip-file to test it, do not forget to make the directories for the language files. A typical zip will contain the following:&lt;br /&gt;
**nameofplugin.XML&lt;br /&gt;
**nameofplugin.PHP&lt;br /&gt;
**language\en-GB\en-GB.plg_search_nameofplugin.INI&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:Creating_a_search_plugin&amp;diff=20565</id>
		<title>J1.5:Creating a search plugin</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:Creating_a_search_plugin&amp;diff=20565"/>
		<updated>2009-12-03T20:02:46Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: /* PHP file */   Added alternative example of how to format the search results as the code isn&amp;#039;t obvious as to what is needed.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{review}}&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:Plugins]]&lt;br /&gt;
==Description==&lt;br /&gt;
This document is about how to create a Search Plugin. You can use a Search Plugin to search through the database of your Joomla! site. To create a plugin, you will at least need two files; an XML file and a PHP file. For internationalization it is good to create an INI file as well. &lt;br /&gt;
&lt;br /&gt;
==XML file==&lt;br /&gt;
The XML file is named the same as the PHP file, and is one of the two required files.&lt;br /&gt;
Always start off with the XML tag and define that it is written in a UTF-8 format.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;&lt;br /&gt;
 &amp;lt;!DOCTYPE install PUBLIC &lt;br /&gt;
  &amp;quot;-//Joomla! 1.5//DTD plugin 1.0//EN&amp;quot; &amp;quot;http://dev.joomla.org/xml/1.5/plugin-install.dtd&amp;quot;&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
To define that the plugin has to be a search plugin, add this line:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;install version=&amp;quot;1.5&amp;quot; type=&amp;quot;plugin&amp;quot; group=&amp;quot;search&amp;quot;&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
The type will define it is a plugin, the group defines the Plugin is in the group of search plugins.&lt;br /&gt;
&lt;br /&gt;
After that, add some information about yourself and the plugin, like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;name&amp;gt;Name of your search plugin&amp;lt;/name&amp;gt;&lt;br /&gt;
&amp;lt;creationDate&amp;gt;Creation date&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
&amp;lt;author&amp;gt;Your name&amp;lt;/author&amp;gt;&lt;br /&gt;
&amp;lt;authorEmail&amp;gt;Your e-mail address&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
&amp;lt;authorUrl&amp;gt;Your website&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
&amp;lt;copyright&amp;gt;Copyright information&amp;lt;/copyright&amp;gt;&lt;br /&gt;
&amp;lt;license&amp;gt;License, for example GNU/GPL&amp;lt;/license&amp;gt;&lt;br /&gt;
&amp;lt;version&amp;gt;Version of the plugin&amp;lt;/version&amp;gt;&lt;br /&gt;
&amp;lt;description&amp;gt;Description of the plugin; showed during installation and when editing &lt;br /&gt;
the plugin in the Plugin Manager&amp;lt;/description&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
And now, include your PHP file to the Search Plugin. The name of this file should be the same as the name of this XML file. Put this name also behind the plugin=&amp;quot;&amp;quot; part. &lt;br /&gt;
&lt;br /&gt;
You could also add more files for your plugin, for example an image. Just add another row between &amp;lt;files&amp;gt; and &amp;lt;/file&amp;gt;, and then place the file between &amp;lt;filename&amp;gt; tags.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;files&amp;gt;&lt;br /&gt;
   &amp;lt;filename plugin=&amp;quot;nameofplugin&amp;quot;&amp;gt;nameofplugin.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
&amp;lt;/files&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the internationalization, we will use language files. This is not required, but people from other countries will love it they can easily translate your plugin to their own language.&lt;br /&gt;
The language tags can be found here: [http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes] (use the ISO 639-1 column) and here: [http://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements]&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;languages&amp;gt;&lt;br /&gt;
   &amp;lt;language tag=&amp;quot;en-GB&amp;quot;&amp;gt;language/en-GB/en-GB.plg_search_nameofplugin.ini&amp;lt;/language&amp;gt;&lt;br /&gt;
&amp;lt;/languages&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
Optionally, you could add some parameters to the plugin. These will look like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;params&amp;gt;&lt;br /&gt;
   &amp;lt;param name=&amp;quot;paramname&amp;quot; type=&amp;quot;typeofparameter&amp;quot; default=&amp;quot;defaultsetting&amp;quot; label=&amp;quot;title&amp;quot; description=&amp;quot;description&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/params&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
*&#039;&#039;&#039;Param name:&#039;&#039;&#039; The name of the parameter. You will need this when creating the PHP file.&lt;br /&gt;
*&#039;&#039;&#039;Param type:&#039;&#039;&#039; You could choose between several types of parameters. Look at this document to learn something about the different types: [http://docs.joomla.org/Using_the_core_parameter_types] &lt;br /&gt;
*&#039;&#039;&#039;Param default:&#039;&#039;&#039; The default setting for this parameter.&lt;br /&gt;
*&#039;&#039;&#039;Param label:&#039;&#039;&#039; The name of this parameter displayed in the edit screen of this plugin in the Plugin Manager.&lt;br /&gt;
*&#039;&#039;&#039;Param description:&#039;&#039;&#039; The text which appears as a tool tip for this parameter. &lt;br /&gt;
&lt;br /&gt;
And do not forget to end your XML file with the following tag:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;/install&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==PHP file==&lt;br /&gt;
The PHP file of your plugin is probably the most important file of the plugin. This is an example PHP file of a search plugin. The comments are included. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;PHP&amp;quot;&amp;gt;&amp;lt;?php&lt;br /&gt;
//First start with information about the Plugin and yourself. For example:&lt;br /&gt;
/**&lt;br /&gt;
 * @version		$Id: nameofplugin.php versionnumber date author&lt;br /&gt;
 * @copyright	        Copyright&lt;br /&gt;
 * @license		License, for example GNU/GPL&lt;br /&gt;
 * All other information you would like to add&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
//To prevent accessing the document directly, enter this code:&lt;br /&gt;
// no direct access&lt;br /&gt;
defined( &#039;_JEXEC&#039; ) or die( &#039;Restricted access&#039; );&lt;br /&gt;
&lt;br /&gt;
//Now define the registerEvent and the language file. Replace &#039;nameofplugin&#039; with the name of your plugin.&lt;br /&gt;
$mainframe-&amp;gt;registerEvent( &#039;onSearch&#039;, &#039;plgSearchnameofplugin&#039; );&lt;br /&gt;
$mainframe-&amp;gt;registerEvent( &#039;onSearchAreas&#039;, &#039;plgSearchnameofpluginAreas&#039; );&lt;br /&gt;
&lt;br /&gt;
JPlugin::loadLanguage( &#039;plg_search_nameofplugin&#039; );&lt;br /&gt;
&lt;br /&gt;
//Then define a function to return an array of search areas. Replace &#039;nameofplugin&#039; with the name of your plugin.&lt;br /&gt;
function &amp;amp;plgSearchnameofpluginAreas()&lt;br /&gt;
{&lt;br /&gt;
	static $areas = array(&lt;br /&gt;
		&#039;nameofplugin&#039; =&amp;gt; &#039;Nameofplugin&#039;&lt;br /&gt;
	);&lt;br /&gt;
	return $areas;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//Then the real function has to be created. The database connection should be made. &lt;br /&gt;
//The function will be closed with an } at the end of the file.&lt;br /&gt;
function plgSearchnameofplugin( $text, $phrase=&#039;&#039;, $ordering=&#039;&#039;, $areas=null )&lt;br /&gt;
{&lt;br /&gt;
	$db		=&amp;amp; JFactory::getDBO();&lt;br /&gt;
	$user	=&amp;amp; JFactory::getUser(); &lt;br /&gt;
&lt;br /&gt;
//If the array is not correct, return it:&lt;br /&gt;
	if (is_array( $areas )) {&lt;br /&gt;
		if (!array_intersect( $areas, array_keys( plgSearchnameofpluginAreas() ) )) {&lt;br /&gt;
			return array();&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//It is time to define the parameters! First get the right plugin; &#039;search&#039; (the group), &#039;nameofplugin&#039;. &lt;br /&gt;
$plugin =&amp;amp; JPluginHelper::getPlugin(&#039;search&#039;, &#039;nameofplugin&#039;);&lt;br /&gt;
&lt;br /&gt;
//Then load the parameters of the plugin..&lt;br /&gt;
$pluginParams = new JParameter( $plugin-&amp;gt;params );&lt;br /&gt;
&lt;br /&gt;
//And define the parameters. For example like this..&lt;br /&gt;
$limit = $pluginParams-&amp;gt;def( &#039;nameofparameter&#039;, defaultsetting );&lt;br /&gt;
&lt;br /&gt;
//Use the function trim to delete spaces in front of or at the back of the searching terms&lt;br /&gt;
$text = trim( $text );&lt;br /&gt;
&lt;br /&gt;
//Return Array when nothing was filled in&lt;br /&gt;
if ($text == &#039;&#039;) {&lt;br /&gt;
		return array();&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//After this, you have to add the database part. This will be the most difficult part, because this changes per situation.&lt;br /&gt;
//In the coding examples later on you will find some of the examples used by Joomla! 1.5 core Search Plugins.&lt;br /&gt;
//It will look something like this.&lt;br /&gt;
	$wheres = array();&lt;br /&gt;
	switch ($phrase) {&lt;br /&gt;
&lt;br /&gt;
//search exact&lt;br /&gt;
		case &#039;exact&#039;:&lt;br /&gt;
			$text		= $db-&amp;gt;Quote( &#039;%&#039;.$db-&amp;gt;getEscaped( $text, true ).&#039;%&#039;, false );&lt;br /&gt;
			$wheres2 	= array();&lt;br /&gt;
			$wheres2[] 	= &#039;LOWER(a.name) LIKE &#039;.$text;&lt;br /&gt;
			$where 		= &#039;(&#039; . implode( &#039;) OR (&#039;, $wheres2 ) . &#039;)&#039;;&lt;br /&gt;
			break;&lt;br /&gt;
&lt;br /&gt;
//search all or any&lt;br /&gt;
		case &#039;all&#039;:&lt;br /&gt;
		case &#039;any&#039;:&lt;br /&gt;
&lt;br /&gt;
//set default&lt;br /&gt;
		default:&lt;br /&gt;
			$words 	= explode( &#039; &#039;, $text );&lt;br /&gt;
			$wheres = array();&lt;br /&gt;
			foreach ($words as $word)&lt;br /&gt;
			{&lt;br /&gt;
				$word		= $db-&amp;gt;Quote( &#039;%&#039;.$db-&amp;gt;getEscaped( $word, true ).&#039;%&#039;, false );&lt;br /&gt;
				$wheres2 	= array();&lt;br /&gt;
				$wheres2[] 	= &#039;LOWER(a.name) LIKE &#039;.$word;&lt;br /&gt;
				$wheres[] 	= implode( &#039; OR &#039;, $wheres2 );&lt;br /&gt;
			}&lt;br /&gt;
			$where = &#039;(&#039; . implode( ($phrase == &#039;all&#039; ? &#039;) AND (&#039; : &#039;) OR (&#039;), $wheres ) . &#039;)&#039;;&lt;br /&gt;
			break;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//ordering of the results&lt;br /&gt;
	switch ( $ordering ) {&lt;br /&gt;
&lt;br /&gt;
//alphabetic, ascending&lt;br /&gt;
		case &#039;alpha&#039;:&lt;br /&gt;
			$order = &#039;a.name ASC&#039;;&lt;br /&gt;
			break;&lt;br /&gt;
&lt;br /&gt;
//oldest first&lt;br /&gt;
		case &#039;oldest&#039;:&lt;br /&gt;
&lt;br /&gt;
//popular first&lt;br /&gt;
		case &#039;popular&#039;:&lt;br /&gt;
&lt;br /&gt;
//newest first&lt;br /&gt;
		case &#039;newest&#039;:&lt;br /&gt;
&lt;br /&gt;
//default setting: alphabetic, ascending&lt;br /&gt;
		default:&lt;br /&gt;
			$order = &#039;a.name ASC&#039;;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//replace nameofplugin&lt;br /&gt;
	$searchnameofplugin = JText::_( &#039;Nameofplugin&#039; );&lt;br /&gt;
&lt;br /&gt;
//the database query; differs per situation! It will look something like this:&lt;br /&gt;
	$query = &#039;SELECT a.name AS title,&#039;&lt;br /&gt;
	. &#039; CONCAT_WS( &amp;quot; / &amp;quot;, &#039;. $db-&amp;gt;Quote($searchNameofplugin) .&#039;, b.title )AS section,&#039;&lt;br /&gt;
	. &#039; &amp;quot;1&amp;quot; AS browsernav&#039;&lt;br /&gt;
	. &#039; FROM #__nameofplugin AS a&#039;&lt;br /&gt;
	. &#039; INNER JOIN #__categories AS b ON b.id = a.catid&#039;&lt;br /&gt;
	. &#039; WHERE ( &#039;. $where .&#039; )&#039;&lt;br /&gt;
	. &#039; AND a.published = 1&#039;&lt;br /&gt;
	. &#039; AND b.access &amp;lt;= &#039;. (int) $user-&amp;gt;get( &#039;aid&#039; )&lt;br /&gt;
	. &#039; ORDER BY &#039;. $order&lt;br /&gt;
	;&lt;br /&gt;
&lt;br /&gt;
//Set query&lt;br /&gt;
	$db-&amp;gt;setQuery( $query, 0, $limit );&lt;br /&gt;
	$rows = $db-&amp;gt;loadObjectList();&lt;br /&gt;
&lt;br /&gt;
//The &#039;output&#039; of the displayed link&lt;br /&gt;
	foreach($rows as $key =&amp;gt; $row) {&lt;br /&gt;
		$rows[$key]-&amp;gt;href = &#039;index.php?option=com_newsfeeds&amp;amp;view=newsfeed&amp;amp;catid=&#039;.$row-&amp;gt;catslug.&#039;&amp;amp;id=&#039;.$row-&amp;gt;slug;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
//Return the search results in an array&lt;br /&gt;
return $rows;&lt;br /&gt;
}&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are 4 variables that get passed it, which are evident by their names and use in the code.&lt;br /&gt;
What&#039;s not obvious is what the function should return. An array of objects that the search tool uses to display the results. The results could alternatively have been assembled something like this.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
$rows[] = (object) array(&lt;br /&gt;
			&#039;href&#039;        =&amp;gt; &#039;index.php?option=com_newsfeeds&amp;amp;view=newsfeed&amp;amp;catid=&#039;.$row-&amp;gt;catslug.&#039;&amp;amp;id=&#039;.$row-&amp;gt;slug,&lt;br /&gt;
			&#039;title&#039;       =&amp;gt; $row[&#039;name&#039;],&lt;br /&gt;
			&#039;section&#039;     =&amp;gt; $searchnameofplugin,&lt;br /&gt;
			&#039;created&#039;     =&amp;gt; $row[&#039;date&#039;],&lt;br /&gt;
			&#039;text&#039;        =&amp;gt; $row[&#039;name&#039;],&lt;br /&gt;
			&#039;browsernav&#039;  =&amp;gt; &#039;1&#039;&lt;br /&gt;
		);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==INI file(s)==&lt;br /&gt;
For internationalization it is good to use the INI files. You can add everything to the language file that outputs text to the user, in this order:&lt;br /&gt;
*XML description tag&lt;br /&gt;
*XML label and description attributes from parameters&lt;br /&gt;
*JText::_( &#039;string&#039; ) used by the plugin&lt;br /&gt;
&lt;br /&gt;
Start your INI file with something like this:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;INI&amp;quot;&amp;gt;# $Id: en-GB.plg_search_nameofplugin.ini&lt;br /&gt;
# Joomla! Project&lt;br /&gt;
# Copyright (C) 2005 - 2007 Open Source Matters. All rights reserved.&lt;br /&gt;
# License http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL, see LICENSE.php&lt;br /&gt;
# Note : All ini files need to be saved as UTF-8 - No BOM&amp;lt;/source&amp;gt;&lt;br /&gt;
Of course, you could also add other information, like the author. &lt;br /&gt;
&lt;br /&gt;
For example, this parameter:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;XML&amp;quot;&amp;gt;&amp;lt;param name=&amp;quot;search_limit&amp;quot; type=&amp;quot;text&amp;quot; size=&amp;quot;5&amp;quot; default=&amp;quot;50&amp;quot; label=&amp;quot;Search Limit&amp;quot; &lt;br /&gt;
description=&amp;quot;Number of Search items to return&amp;quot;/&amp;gt;&amp;lt;/source&amp;gt;&lt;br /&gt;
Will cause the following output in the INI file:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;INI&amp;quot;&amp;gt;&lt;br /&gt;
SEARCH LIMIT=Search Limit&lt;br /&gt;
NUMBER OF SEARCH ITEMS TO RETURN=Number of Search items to return&amp;lt;/source&amp;gt;&lt;br /&gt;
The file looks repetitive, but will be very useful for translaters.&lt;br /&gt;
&lt;br /&gt;
When you want to make your search plugin available in more languages, first add them to the &amp;lt;languages&amp;gt; tag in the XML file. Then create the same INI file, and change the part after the =, for example the dutch version would be:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;INI&amp;quot;&amp;gt;&lt;br /&gt;
SEARCH LIMIT=Zoek limiet&lt;br /&gt;
NUMBER OF SEARCH ITEMS TO RETURN=Aantal weer te geven zoekresultaten&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Coding examples==&lt;br /&gt;
There are six Joomla! Core Search Plugins. If you look at them you can learn a lot, especially about the query part.&lt;br /&gt;
You can see them &#039;working&#039; when you go to the back-end of your Joomla! 1.5 installation, then go to the menu &#039;Extensions&#039; and select the &#039;Plugin Manager&#039;. Click on the name of the plugin to edit it; and see it working.&lt;br /&gt;
*Plugin Search - Categories&lt;br /&gt;
**\plugins\search\categories.XML&lt;br /&gt;
**\plugins\search\categories.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_categories.INI&lt;br /&gt;
*Plugin Search - Contacts&lt;br /&gt;
**\plugins\search\contacts.XML&lt;br /&gt;
**\plugins\search\contacts.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_contacts.INI&lt;br /&gt;
*Plugin Search - Content&lt;br /&gt;
**\plugins\search\content.XML&lt;br /&gt;
**\plugins\search\content.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_content.INI&lt;br /&gt;
*Plugin Search - Newsfeeds&lt;br /&gt;
**\plugins\search\newsfeeds.XML&lt;br /&gt;
**\plugins\search\newsfeeds.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_newsfeeds.INI&lt;br /&gt;
*Plugin Search - Sections&lt;br /&gt;
**\plugins\search\sections.XML&lt;br /&gt;
**\plugins\search\sections.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_sections.INI&lt;br /&gt;
*Plugin Search - Weblinks&lt;br /&gt;
**\plugins\search\weblinks.XML&lt;br /&gt;
**\plugins\search\weblinks.PHP&lt;br /&gt;
**\language\en-GB\en-GB.plg_search_weblinks.INI&lt;br /&gt;
&lt;br /&gt;
==Quick tips==&lt;br /&gt;
*In the PHP file, people often forget to place an semicolon (;) at the end of a row. This causes errors. Check this before you test your plugin.&lt;br /&gt;
*Make sure the parameters in the XML file are closed correctly. When you add options, for example, you need to close it with &amp;lt;/param&amp;gt;.&lt;br /&gt;
*It is easy to test on a localhost when you are still busy with editing your plugin.&lt;br /&gt;
*When making a zip-file to test it, do not forget to make the directories for the language files. A typical zip will contain the following:&lt;br /&gt;
**nameofplugin.XML&lt;br /&gt;
**nameofplugin.PHP&lt;br /&gt;
**language\en-GB\en-GB.plg_search_nameofplugin.INI&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Search_Engine_Friendly_URLs&amp;diff=20557</id>
		<title>Search Engine Friendly URLs</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Search_Engine_Friendly_URLs&amp;diff=20557"/>
		<updated>2009-12-02T21:21:00Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: Added link to http://docs.joomla.org/Routing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;&#039;Joomla Routes&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Joomla routes are created by the JRouter class.  This class looks in the component root of the component specified in the &amp;quot;option&amp;quot; portion of the query string and includes the router.php file in that component&#039;s root directory.  It then calls one of two functions: one for creating the SEF link and one for interpreting the SEF link.&lt;br /&gt;
&lt;br /&gt;
The JRouter class is overridden by the Joomla CMS in /includes/router.php.  In this file the build and parse functions are overridden to properly build and parse the URLs for the Joomla CMS.&lt;br /&gt;
&lt;br /&gt;
com_component/router.php&lt;br /&gt;
&lt;br /&gt;
The router.php file should contain the following two functions:&lt;br /&gt;
* ContentBuildRoute - this builds the SEF url&lt;br /&gt;
** Parameters&lt;br /&gt;
*** $query - this is a named array containing the querystring variables&lt;br /&gt;
** Returns: an array of segments where each segment is separated by a &#039;/&#039; when later combined to create the actual link (the items in the array should not contain &#039;/&#039; characters)&lt;br /&gt;
* ContentParseRoute - this interprets an SEF url&lt;br /&gt;
** Parameters&lt;br /&gt;
*** $segments - this is an array that contains the segments of the url requested.&lt;br /&gt;
** Returns: a name =&amp;gt; value array of the querystring variables that the link maps to&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;The SEF Plugin&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The Joomla System SEF plugin inherits JPlugin and overrides the onAfterRender() function.  In this function the body of the response that will be sent to the browser is retrieved using JResponse::getBody().  The body of the response is then searched for links containing &amp;quot;/index.php...&amp;quot; and replaces them with a correct SEF url by calling JRoute::_(url).&lt;br /&gt;
&lt;br /&gt;
JRoute builds SEF URLs by instantiating a JRouter object and requesting that it build the correct link from the passed in URL.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Handling SEF URLs&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
By default the SEF URLs are handled by the the JRouterSite object (from /includes/router.php) and is called by a call to JApplication::route() in index.php.  This call is made on the $mainframe variable which is actually an instance of JSite (from /includes/application.php).&lt;br /&gt;
&lt;br /&gt;
JApplication::route() has a non-destructive result on the $_GET array.  By this I mean that JApplication::route() sets variables in $_GET by calling JRequest::set() with the overwrite flag set to false.  Thus if a variable name is returned from JRouter::route() that is already in $_GET then it will not put that value into $_GET.  This allows for custom routing.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Custom Routing&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Joomla allows you to create your own routing mechanism.  In order to create this mechanism you must have a plugin that overrides the JPlugin::onAfterInitialise() function.  This function then parses the URL and creates the needed variables in $_GET before the standard Joomla routing is done.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
http://docs.joomla.org/Routing&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J2.5:Supporting_SEF_URLs_in_your_component&amp;diff=20537</id>
		<title>J2.5:Supporting SEF URLs in your component</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J2.5:Supporting_SEF_URLs_in_your_component&amp;diff=20537"/>
		<updated>2009-11-30T22:41:52Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: /* The Slug */  changed word hyphen to colon as dcoumentation is referencing the &amp;#039;:&amp;#039; symbol&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{incomplete}}&lt;br /&gt;
{{RightTOC}}&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
== Routing Overview ==&lt;br /&gt;
&lt;br /&gt;
Joomla! 1.5 is capable of creating and parsing URLs in any format, including human readable URL&#039;s. Another improvement is that this still works even if Joomla! runs a server other than Apache with the mod_rewrite module.&lt;br /&gt;
&lt;br /&gt;
A good example of this is the &amp;quot;Welcome to Joomla&amp;quot; article. The first link shown was generated without mod_rewrite, and the second link was generated with mod_rewrite:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/index.php/the-­news/1-­latest­-news/1­-welcome­-to­-joomla&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/the-­news/1­-latest-­news/1-­welcome-­to­-joomla&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Preparing Your Data for Routing ==&lt;br /&gt;
&lt;br /&gt;
=== The Alias ===&lt;br /&gt;
&lt;br /&gt;
The first step is the generation of the so called alias. The alias is used in the URL instead of the title (the title is the text you want to have in the url). The alias has to be URI safe, which means accented UTF­8 characters are replaced by their ASCII­7 equivalents, white spaces by hyphens, etc.&lt;br /&gt;
&lt;br /&gt;
The alias can be defined by the user, but you should ensure that the above requirements for a URL safe alias are met. A good way to do so is to use the JTable::check() method during the save process. Have a look at this example code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function check()&lt;br /&gt;
{&lt;br /&gt;
    jimport( &#039;joomla.filter.output&#039; );&lt;br /&gt;
    if(empty($this-&amp;gt;alias)) {&lt;br /&gt;
	    $this-&amp;gt;alias = $this-&amp;gt;title;&lt;br /&gt;
    }&lt;br /&gt;
    $this-&amp;gt;alias = JFilterOutput::stringURLSafe($this-&amp;gt;alias);&lt;br /&gt;
&lt;br /&gt;
    /* All your other checks */&lt;br /&gt;
    return true;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the alias field is empty the title will be used as alias. Then the alias will be made URLSafe using the JFilterOutput::stringURLSafe() method.&lt;br /&gt;
&lt;br /&gt;
=== The Slug ===&lt;br /&gt;
&lt;br /&gt;
Continuing with the same example, the &amp;quot;slug&amp;quot; - &amp;quot;1­-welcome­-to­-joomla&amp;quot; has two parts. The first part is the article identifier (id) and the second is the alias. They are separated by a colon. These two elements were combined during the database query in the model:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$query = &#039;SELECT a.*,&#039;.&lt;br /&gt;
        &#039; CASE WHEN CHAR_LENGTH(a.alias) THEN CONCAT_WS(\&#039;:\&#039;, a.id, a.alias) ELSE a.id END as slug,&#039;.&lt;br /&gt;
        [...];&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After this step the slug is used instead of the id.&lt;br /&gt;
&lt;br /&gt;
== Routing URL&#039;s ==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;code&amp;gt;JRoute::_&amp;lt;/code&amp;gt; method translates the internal Joomla! URL to a custom URL. &amp;lt;code&amp;gt;JRoute&amp;lt;/code&amp;gt; has three parameters and its prototype is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;JRoute::_( $url, $xhtml = true, $ssl=0 );&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Where:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;$url&amp;lt;/code&amp;gt; is a string containing the absolute or relative internal Joomla! URL.&lt;br /&gt;
* &amp;lt;code&amp;gt;$xhtml&amp;lt;/code&amp;gt; is a boolean value that specifies whether or not the output should be in XHTML. This parameter is optional and if omitted defaults to true.&lt;br /&gt;
* &amp;lt;code&amp;gt;$ssl&amp;lt;/code&amp;gt; is an integer value that specifies whether the URI should be secure. It should be set to 1 to force the URI to be secure using the global secure site URI, 0 to leave it in the same state as when it was passed, and -1 to force the URI to be unsecure using the global unsecure site URI.&lt;br /&gt;
&lt;br /&gt;
The most important parameter is &amp;lt;code&amp;gt;$url&amp;lt;/code&amp;gt;. A call to this method might look like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;JRoute::_( &#039;index.php?view=article&amp;amp;id=&#039;.$row-&amp;gt;slug );&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;$row-­&amp;gt;slug&amp;lt;/code&amp;gt; is the value that was generated in step 2 from a combination of id and title alias.&lt;br /&gt;
&lt;br /&gt;
Another advantage of using JRoute is that the router now handles $option (the component name) and the $Itemid (the menu item ID). The component itself doesn’t have to know its name ($option) or the active menu item ($Itemid) like it did in previous version of Joomla!.&lt;br /&gt;
&lt;br /&gt;
It is important that you think about the sequence of the URL parameter in this stage. This will be more clear when we have a deeper look at the router.php in the next section.&lt;br /&gt;
&lt;br /&gt;
The building process of JRouter is divided into two steps:&lt;br /&gt;
&lt;br /&gt;
* Create the application route. The application route is fully handled by JRouter and the component developer doesn’t have to do anything to make it work.&lt;br /&gt;
* Create the component route. To create the component route, JRouter looks for the router.php in the component directory which is responsible for building the route for the component.&lt;br /&gt;
&lt;br /&gt;
== The Component Router ==&lt;br /&gt;
&lt;br /&gt;
We will have two functions In the router.php. One is responsible for building the URL and the other is responsible for parsing it. In the next examples, a very basic and a more advanced one, we assume that we have three views that links can point to. The first is a categories overview (view=categories), the second is a single category (view=category) and the third is a single article (view=article).&lt;br /&gt;
&lt;br /&gt;
The file router.php should be in the site area of your component. It is not used on admin/backend pages. Don&#039;t forget to add it to your installation XML in the site folder.&lt;br /&gt;
&lt;br /&gt;
=== A Simple Example ===&lt;br /&gt;
&lt;br /&gt;
This simple example will illustrate the basics of implementing a router for your component.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function [componentname]BuildRoute( &amp;amp;$query )&lt;br /&gt;
{&lt;br /&gt;
       $segments = array();&lt;br /&gt;
       if(isset($query[&#039;view&#039;]))&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;view&#039;];&lt;br /&gt;
                unset( $query[&#039;view&#039;] );&lt;br /&gt;
       }&lt;br /&gt;
       if(isset($query[&#039;id&#039;]))&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;id&#039;];&lt;br /&gt;
                unset( $query[&#039;id&#039;] );&lt;br /&gt;
       };&lt;br /&gt;
       return $segments;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt; passes a $query array to the &amp;lt;code&amp;gt;[&#039;&#039;componentname&#039;&#039;]BuildRoute&amp;lt;/code&amp;gt; function. This function will add the relevant parts of the array to the $segments array in the right order and will return the properly ordered array. The content of the &amp;lt;code&amp;gt;$query&amp;lt;/code&amp;gt; array needs to be unset, otherwise &amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt; will add it to the URL in the form of a query string (i.e. any variables that are not handled by the router will be passed in the query string).&lt;br /&gt;
&lt;br /&gt;
The prefix &#039;&#039;componentname&#039;&#039; is the name for your component, as found in the directory holding the component&#039;s files. For instance, a component &amp;quot;Magic&amp;quot; in directory &amp;lt;code&amp;gt;/components/com_magic/...&amp;lt;/code&amp;gt; would use a prefix &amp;lt;code&amp;gt;magic&amp;lt;/code&amp;gt; (all lower case).&lt;br /&gt;
&lt;br /&gt;
The next function in the &amp;lt;code&amp;gt;router.php&amp;lt;/code&amp;gt; parses the URL:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function [componentname]ParseRoute( $segments )&lt;br /&gt;
{&lt;br /&gt;
       $vars = array();&lt;br /&gt;
       switch($segments[0])&lt;br /&gt;
       {&lt;br /&gt;
               case &#039;categories&#039;:&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;categories&#039;;&lt;br /&gt;
                       break;&lt;br /&gt;
               case &#039;category&#039;:&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;category&#039;;&lt;br /&gt;
                       $id = explode( &#039;:&#039;, $segments[1] );&lt;br /&gt;
                       $vars[&#039;id&#039;] = (int) $id[0];&lt;br /&gt;
                       break;&lt;br /&gt;
               case &#039;article&#039;:&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;article&#039;;&lt;br /&gt;
                       $id = explode( &#039;:&#039;, $segments[1] );&lt;br /&gt;
                       $vars[&#039;id&#039;] = (int) $id[0];&lt;br /&gt;
                       break;&lt;br /&gt;
       }&lt;br /&gt;
       return $vars;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
What happens here? In the function &amp;lt;code&amp;gt;[&#039;&#039;componentname&#039;&#039;]BuildRoute&amp;lt;/code&amp;gt; we arranged the items in the &amp;lt;code&amp;gt;$query&amp;lt;/code&amp;gt; array in a specific sequence. This means that in this example the view is first, the catid is second and the id is third in the array.&lt;br /&gt;
&lt;br /&gt;
By reading &amp;lt;code&amp;gt;$segments[0]&amp;lt;/code&amp;gt;, we access the name of the view. We set the right view and/or identifier depending on its value and we return the &amp;lt;code&amp;gt;$vars&amp;lt;/code&amp;gt; array to &amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt;. $vars should be an associative array similar to the array that was passed to the BuildRoute method.&lt;br /&gt;
&lt;br /&gt;
The above example of the &amp;lt;code&amp;gt;router.php&amp;lt;/code&amp;gt; is a very simple way to generate sef URL&#039;s but should show how this works quite clearly.&lt;br /&gt;
&lt;br /&gt;
The generated URL in this example contains the name of the view and doesn&#039;t reflect the content hierarchy:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]/[view]/[slug]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== A More Advanced Example ===&lt;br /&gt;
&lt;br /&gt;
In the next example we will try to get rid of the need for the view and we will try to reflect the current hierarchy level in the URL.&lt;br /&gt;
&lt;br /&gt;
The goal is URL&#039;s that look like:&lt;br /&gt;
&lt;br /&gt;
* When viewing an article: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]/[category]/[article]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When viewing a category: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]/[category]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* When viewing the categories overview: &amp;lt;code&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/[menualias]&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let&#039;s assume we have done step 1 and 2 also for the category.&lt;br /&gt;
&lt;br /&gt;
The link to the article would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JRoute::_( &#039;index.php?view=article&amp;amp;catid=&#039;.$row-­&amp;gt;catslug .&#039;&amp;amp;id=&#039;.$row-­&amp;gt;slug );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And the Link to the category would look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
JRoute::_( &#039;index.php?view=category&amp;amp;id=&#039;.$row-&amp;gt;catslug );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding &amp;lt;code&amp;gt;router.php&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
function [&#039;&#039;Componentname&#039;&#039;]BuildRoute(&amp;amp;$query)&lt;br /&gt;
{&lt;br /&gt;
       $segments = array();&lt;br /&gt;
       if(isset( $query[&#039;catid&#039;] ))&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;catid&#039;];&lt;br /&gt;
                unset( $query[&#039;catid&#039;] );&lt;br /&gt;
       };&lt;br /&gt;
       if( isset($query[&#039;id&#039;]) )&lt;br /&gt;
       {&lt;br /&gt;
                $segments[] = $query[&#039;id&#039;];&lt;br /&gt;
                unset( $query[&#039;id&#039;] );&lt;br /&gt;
       };&lt;br /&gt;
       unset( $query[&#039;view&#039;] );&lt;br /&gt;
       return $segments;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The difference now is that we don’t add the name of the view to the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array. We still unset the view key since otherwise, &amp;lt;code&amp;gt;JRouter&amp;lt;/code&amp;gt; would add it to the URL as part of the query string. Another new thing here is the additional parameter catid that we push into the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
function [&#039;&#039;Componentname&#039;&#039;]ParseRoute($segments)&lt;br /&gt;
{&lt;br /&gt;
       $vars = array();&lt;br /&gt;
       $menu =&amp;amp; JMenu::getInstance();&lt;br /&gt;
       $item =&amp;amp; $menu-&amp;gt;getActive();&lt;br /&gt;
       // Count segments&lt;br /&gt;
       $count = count( $segments );&lt;br /&gt;
       //Handle View and Identifier&lt;br /&gt;
       switch( $item-­&amp;gt;query[&#039;view&#039;] )&lt;br /&gt;
       {&lt;br /&gt;
               case &#039;categories&#039;:&lt;br /&gt;
                       if($count == 1) {&lt;br /&gt;
                               $vars[&#039;view&#039;] = &#039;category&#039;;&lt;br /&gt;
                       }&lt;br /&gt;
                       if($count == 2) {&lt;br /&gt;
                               $vars[&#039;view&#039;] = &#039;article&#039;;&lt;br /&gt;
                       }&lt;br /&gt;
                       $id = explode( &#039;:&#039;, $segments[$count-1] );&lt;br /&gt;
                       $vars[&#039;id&#039;] = (int) $id[0];&lt;br /&gt;
                       break;&lt;br /&gt;
               case &#039;category&#039;:&lt;br /&gt;
                       $id   = explode( &#039;:&#039;, $segments[$count-1] );&lt;br /&gt;
                       $vars[&#039;id&#039;]   = (int) $id[0];&lt;br /&gt;
                       $vars[&#039;view&#039;] = &#039;article&#039;;&lt;br /&gt;
                       break;&lt;br /&gt;
       }&lt;br /&gt;
       return $vars;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can see that this ParseRoute function has a lot of different code parts in comparison to the previous. The reason for this is simple. We don’t have the name of the view in the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array and we need to find another way to determine it.&lt;br /&gt;
&lt;br /&gt;
We need to find out which level of hierarchy we are in by receiving the root element. We do this by looking to the view name of the active menu item:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$item-­&amp;gt;query[&#039;view&#039;]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Also we need to know the number of items in the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$count = count( $segments );&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this information we can correctly set the view for all possible three cases:&lt;br /&gt;
&lt;br /&gt;
* The menu item is a link to the categories view and the &amp;lt;code&amp;gt;$segments&amp;lt;/code&amp;gt; array has two items (&amp;lt;code&amp;gt;$catid&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;$id&amp;lt;/code&amp;gt;). In this case we know that we need to parse a link to an article .&lt;br /&gt;
* The menu item is a link to the categories view and the $segments array has one item ($id). In this case we know that we need to parse a link to a category.&lt;br /&gt;
* The menu item is a link to a category. In this case, we know that any item in the $segments array is the identifier for an article .&lt;br /&gt;
&lt;br /&gt;
The result of all this code is nice and human readable component URL&#039;s.&lt;br /&gt;
&lt;br /&gt;
== Application Route Parsing ==&lt;br /&gt;
&lt;br /&gt;
The [[API Execution Order]] outlines that the route (URL) is parsed immediately after initialisation is complete.  Since fancy URL&#039;s are not treated (yet) in the Administrator, we will follow the route parsing process in detail when &amp;lt;code&amp;gt;JSite::route&amp;lt;/code&amp;gt; in the &amp;lt;code&amp;gt;index.php&amp;lt;/code&amp;gt; file.&lt;br /&gt;
&lt;br /&gt;
* Call to &amp;lt;code&amp;gt;JApplication::route&amp;lt;/code&amp;gt;&lt;br /&gt;
** Clone the URI&lt;br /&gt;
** Call to &amp;lt;code&amp;gt;JApplication::getRouter&amp;lt;/code&amp;gt;&lt;br /&gt;
*** Call to &amp;lt;code&amp;gt;JRouter::getInstance&amp;lt;/code&amp;gt; passing the type (&amp;quot;site&amp;quot;)&lt;br /&gt;
** Call to &amp;lt;code&amp;gt;JRouterSite::parse&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
*** Strip the suffix if applicable (added to $vars[&#039;format&#039;])&lt;br /&gt;
*** Re-set the route (URI)&lt;br /&gt;
*** Call to &amp;lt;code&amp;gt;JRouter::parse&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
**** Call to &amp;lt;code&amp;gt;JRouterSite::_processParseRules&amp;lt;/code&amp;gt; passing the URI (this will call custom route rules)&lt;br /&gt;
***** Call to &amp;lt;code&amp;gt;JRouter::_processParseRules&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
****** Call any custom routing rules (probably added via a system plugin using the &amp;lt;code&amp;gt;onAfterInitialise&amp;lt;/code&amp;gt; event trigger) passing the URI&lt;br /&gt;
****** Returns an array of vars&lt;br /&gt;
***** If SEF mode, replace &amp;lt;code&amp;gt;start&amp;lt;/code&amp;gt; variable with &amp;lt;/code&amp;gt;limitstart&amp;lt;/code&amp;gt;&lt;br /&gt;
**** If raw mode, call to &amp;lt;code&amp;gt;JRouterSite::_parseRawRoute&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
**** If SEF mode, call to &amp;lt;code&amp;gt;JRouterSite::_parseSefRoute&amp;lt;/code&amp;gt; passing the URI&lt;br /&gt;
***** If the route (the URI path) is empty, load it from the default menu item; set the active menu item as the default&lt;br /&gt;
***** If first part is &amp;lt;code&amp;gt;/component/com_content&amp;lt;/code&amp;gt;, set the &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt; as the second segement.  Null the &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt;.&lt;br /&gt;
***** Else, loop through menu alias values and take off segments that match as the menu tree is traversed.  Set &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt; based on the last menu item found.&lt;br /&gt;
***** If the &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt; is set in the URL, set the active menu item based on this value.&lt;br /&gt;
***** Push the vars collected so far (eg, &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;Itemid&amp;lt;/code&amp;gt;, etc) into the router object (&amp;lt;code&amp;gt;$this&amp;lt;/code&amp;gt;).&lt;br /&gt;
***** If the route and &amp;lt;code&amp;gt;option&amp;lt;/code&amp;gt; is set, load the component router;&lt;br /&gt;
***** Else, get the active menu item and get the route vars from it&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Application Route Building ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Custom Router Rules ==&lt;br /&gt;
&lt;br /&gt;
TODO&lt;br /&gt;
&lt;br /&gt;
== Additional References ==&lt;br /&gt;
&lt;br /&gt;
There is a useful thread on this subject here: [[jtopic:148632]] (note, may be out of date)&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_add_breadcrumbs&amp;diff=20536</id>
		<title>J1.5:How to add breadcrumbs</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J1.5:How_to_add_breadcrumbs&amp;diff=20536"/>
		<updated>2009-11-30T22:17:46Z</updated>

		<summary type="html">&lt;p&gt;Creuzerm: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Breadcrumbs are nice way to display the connection from the root. It gives you a hierarchical representation with click able links so that user can visit upper links easily. Breadcrumbs can be added in templates by using the object returned by $mainframe-&amp;gt;getPathWay(). The member function addItem() allows to add a breadcrumb with the title of choice. &lt;br /&gt;
&lt;br /&gt;
There are two parameters used for breadcrumbs creation process, and the first parameter is the title for the breadcrumb and the second parameter is the URL. If we do not need the breadcrumb to work like a link then we need to simply pass a blank string and then it will not work like a click able URL. This term is useful for hierarchical components where we have subcategories: we can generate a link to each and then end with the title of the current record or category.&lt;br /&gt;
&lt;br /&gt;
The JPathway is currently used by the breadcrumbs module. If you are adding a new component and have already configured breadcrumbs, you may need to go into the breadcrumbs configuration and add the menu item for you component to the selection on the menu selelist.&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
A view&#039;s view.php could look something like this.&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class exampleViewdefault extends JView {&lt;br /&gt;
	function display($tpl = null) {&lt;br /&gt;
&lt;br /&gt;
		&lt;br /&gt;
		$mainframe = &amp;amp;JFactory::getApplication();&lt;br /&gt;
		$document  = &amp;amp;JFactory::getDocument();		&lt;br /&gt;
		$pathway   =&amp;amp; $mainframe-&amp;gt;getPathway();&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		JHTML::_(&#039;behavior.modal&#039;);&lt;br /&gt;
		$model =&amp;amp; $this-&amp;gt;getModel();&lt;br /&gt;
		$data = $model-&amp;gt;getData();&lt;br /&gt;
&lt;br /&gt;
		$this-&amp;gt;assignRef( &#039;events&#039;, $data);&lt;br /&gt;
&lt;br /&gt;
		$document-&amp;gt;setTitle( $this-&amp;gt;events[&#039;name&#039;] );		&lt;br /&gt;
		$pathway-&amp;gt;addItem($this-&amp;gt;events[&#039;name&#039;], &#039;&#039;);&lt;br /&gt;
&lt;br /&gt;
		parent::display($tpl);&lt;br /&gt;
&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== See Also==&lt;br /&gt;
* http://docs.joomla.org/JPathway&lt;br /&gt;
* http://api.joomla.org/Joomla-Framework/Application/JPathway.html&lt;/div&gt;</summary>
		<author><name>Creuzerm</name></author>
	</entry>
</feed>