<?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=Cmb</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=Cmb"/>
	<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/Special:Contributions/Cmb"/>
	<updated>2026-06-05T05:31:58Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.0</generator>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_do_you_add_a_PayPal_button%3F&amp;diff=1020484</id>
		<title>How do you add a PayPal button?</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_do_you_add_a_PayPal_button%3F&amp;diff=1020484"/>
		<updated>2024-01-13T18:24:51Z</updated>

		<summary type="html">&lt;p&gt;Cmb: URL update. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{Joomla version|version=3.x}}{{Joomla version|version=2.5|status=eos}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
PayPal, Google Checkout and other ecommerce sites often provide HTML code that you can use to insert links such as &#039;&#039;Add to Cart&#039;&#039; and &#039;&#039;Buy Now&#039;&#039; buttons into your Website.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
It is generally preferable to create a Custom HTML module instead of just pasting the code into an article. This way you can put the link in a module position on as many page as you like. You can also put the module inside an article using the [[S:MyLanguage/How_do_you_put_a_module_inside_an_article%3F|{loadposition myposition}]] command.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== PayPal Technical Documentation == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
Specifications and examples of the HTML code are shown in the [https://developer.paypal.com/api/nvp-soap/paypal-payments-standard/integration-guide/pps-integration/ PayPal Payments Standard Integration Guide].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== HTML Editor Pitfalls == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
You can insert this type of HTML code, including forms, either inside an Article or in a Custom HTML Module. However, the TinyMCE editor will normally strip out HTML code. If you try to paste in some types of HTML code using this editor, it will not work; the editor will remove the code when you save the Article or Module.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== TinyMCE Editor Solution === &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
To avoid this problem while using the TinyMCE editor:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
#Go to the User Manager and change the User Editor to &#039;&#039;No editor&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
#Go to the article or Custom HTML module and paste in the desired HTML code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
#Go back to the User Manager and change the User Editor back to TinyMCE.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Note that you will need to repeat this any time you want to edit the code (unless you use the alternate solution below).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== JCE Editor Solution === &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
#Install the JCE editor from [https://extensions.joomla.org/extension/jce/ the Joomla Extensions Directory]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
#Change the default editor {{rarr|Global Configuration,Site,Default WYSIWYG Editor}} to JCE from TinyMCE. You may also need to change the default editor for other users.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
#Go to the article or Custom HTML module and hit the &#039;&#039;show/hide&#039;&#039; button, which will change the edit box to allow you to input HTML code instead of WYSIWYG text.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
#Paste the HTML code into the editor.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
When you navigate back to the article or module in the Backend, it will already be set to HTML input; the code will not get garbled. This is easier than having to change the user settings each time you want to edit the code while you are testing different button settings.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Email Cloaking Pitfalls == &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
The PayPal code includes an email address for your Website. Joomla! has a Plugin called &#039;&#039;Content - Email Cloaking&#039;&#039; that attempts to disguise emails in Articles. If you wish to paste the PayPal code directly inside an Article, you may need to disable this Plugin. Navigate to {{rarr|Extensions,Plugins}}, find the Plugin &#039;&#039;Content - Email Cloaking&#039;&#039; and click the green checkbox in the Enabled column to disable it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Plugins are not processed in modules, so should you use a Custom HTML module, you will still be able to have email cloaking enabled.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Article-Specific Email Cloaking Switch === &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
You can disable email cloaking in an article by entering &#039;&#039;{emailcloak=off}&#039;&#039; anywhere in the article before the email address. With this control, you do not need to disable global email cloaking.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Secure Merchant Account ID in Place of the Email Address === &amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
PayPal offers a Secure Merchant Account ID (an alphanumeric string used in place of the merchant email address) at no cost. It is available for Web Payments Standard customers as well as in the extra-cost plans. Email cloaking does not affect the Secure Merchant Account ID.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== PayPal Button Function Invoked by a Joomla Menu Item == &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
You may use a menu item to act as a PayPal button. For example, the PayPal View Cart button simply sends a query string as part of a Uniform Resource Locator (URL) using an HTML form. You can create a Joomla menu item that performs the same function.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
In the Menu Item Manager create a new External Link menu item. In the Menu Item Details section, go to the Link field and enter at URL of the form:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=text&amp;gt;https://www.paypal.com/us/cgi-bin/webscr&amp;amp;business=myusername@mysite.com&amp;amp;cmd=_cart&amp;amp;display=1&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
Replace &#039;&#039;myusername@mysite.com&#039;&#039; in the URL example above with the unique username of &#039;&#039;&#039;your&#039;&#039;&#039; PayPal account.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
To test the operation in the PayPal Sandbox, simply modify the URL slightly so that &#039;&#039;www.paypal.com&#039;&#039; becomes &#039;&#039;www.sandbox.paypal.com&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=text&amp;gt;https://www.sandbox.paypal.com/us/cgi-bin/webscr&amp;amp;business=myusername@mysite.com&amp;amp;cmd=_cart&amp;amp;display=1&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:FAQ{{#translation:}}]]&lt;br /&gt;
[[Category:Administration FAQ{{#translation:}}]]&lt;br /&gt;
[[Category:Article Management{{#translation:}}]]&lt;br /&gt;
[[Category:Component Development{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Web_Assets&amp;diff=1016006</id>
		<title>J4.x:Web Assets</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Web_Assets&amp;diff=1016006"/>
		<updated>2023-10-25T23:23:16Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some phrasing and markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Concept == &amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:115--&amp;gt; In the Frontend world many assets are related. For example, our &#039;&#039;keepalive&#039;&#039; script depends on the &#039;&#039;core.js&#039;&#039; file for options management. In Joomla there never was an easy way to specify this; you just had to include multiple files. Joomla 4 changes this with the concept of web assets.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Definition == &amp;lt;!--T:116--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt; Related assets are defined in a JSON file such as [https://github.com/joomla/joomla-cms/blob/7b72c565b610e02c1b01f8958d622879631fa6a2/build/media_source/system/joomla.asset.json#L14-L21 system/joomla.asset.json#L14-L21]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:118--&amp;gt; This has a structure of having a schema definition (for validation), name, version, license and then one or more asset definitions. Assets comprise a list of JavaScript files and CSS files related to the assets and any dependencies. The dependencies section is just a list of asset names that are required for the asset to function. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;Joomla CMS&amp;quot;,&lt;br /&gt;
  &amp;quot;license&amp;quot;: &amp;quot;GPL-2.0+&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.css&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;beer&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/beer.css&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;bar&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;beer&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;core&amp;quot;,&lt;br /&gt;
        &amp;quot;bar&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/beer.js&amp;quot;,&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;defer&amp;quot;: true,&lt;br /&gt;
        &amp;quot;data-foo&amp;quot;: &amp;quot;bar&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt; The &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; inline&amp;gt;$schema&amp;lt;/syntaxhighlight&amp;gt; attribute is a schema definition file that allows you to validate your file using JSON Schema. Read [https://json-schema.org/understanding-json-schema/index.html the official website] for more information on how JSON schema validation works.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:120--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Having &#039;&#039;joomla.asset.json&#039;&#039; for your extension or template are recommended but not required for WebAsset to work. (See the next section).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:121--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; It is not recommended to add an inline asset to a JSON file. Prefer to use a file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Explaining Asset Stages == &amp;lt;!--T:122--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:123--&amp;gt; Each asset has two stages: registered and used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:124--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Registered&#039;&#039;&#039; is where an asset is loaded into &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;. That means &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; knows about the existence of these assets, but will not attach them to a document while rendering. All assets loaded from joomla.asset.json is at &#039;&#039;&#039;registered&#039;&#039;&#039; stage.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:125--&amp;gt; &#039;&#039;&#039;Used&#039;&#039;&#039; is where an asset is enabled via &#039;&#039;$wa-&amp;gt;useAsset()&#039;&#039; (-&amp;gt;useScript(), -&amp;gt;useStyle(), -&amp;gt;registerAndUseX() etc). That means &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; will attach these assets and their dependencies to a document while rendering.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;gt; An asset cannot be used if it was not previously registered. This will cause an unknown asset exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Register an Asset == &amp;lt;!--T:127--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:128--&amp;gt; All known assets loaded and then stored in &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;. (To enable/disable an asset item, use &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;. See the next section.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:129--&amp;gt; Joomla! will look for next assets definition automatically at runtime (in following order):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
media/vendor/joomla.asset.json (on first access to WebAssetRegistry)&lt;br /&gt;
media/system/joomla.asset.json&lt;br /&gt;
media/legacy/joomla.asset.json&lt;br /&gt;
media/{com_active_component}/joomla.asset.json (on dispatch the application)&lt;br /&gt;
templates/{active_template}/joomla.asset.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt; ...and load them to the registry of known assets.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:131--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Each following assets definition will override asset items from previous assets definition, by item name.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:132--&amp;gt; You can register your own assets definition via &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wr = $wa-&amp;gt;getRegistry();&lt;br /&gt;
$wr-&amp;gt;addRegistryFile(&#039;relative/path/to/your/joomla.asset.json&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:133--&amp;gt; To add a custom asset item at runtime:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wr-&amp;gt;add(&#039;script&#039;, new Joomla\CMS\WebAsset\WebAssetItem(&#039;foobar&#039;, &#039;com_foobar/file.js&#039;, [&#039;type&#039; =&amp;gt; &#039;script&#039;]));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:134--&amp;gt; Or more simply, using &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;foobar&#039;, &#039;com_foobar/file.js&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:135--&amp;gt; The new asset item &#039;&#039;foobar&#039;&#039; will be added to the registry of known assets, but will not be attached to a document until your code (a layout, template etc) requests it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt; To check whether an asset exists:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($wa-&amp;gt;assetExists(&#039;script&#039;, &#039;foobar&#039;))&lt;br /&gt;
{&lt;br /&gt;
    var_dump(&#039;Script &amp;quot;foobar&amp;quot; exists!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Enabling an Asset == &amp;lt;!--T:137--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:138--&amp;gt; All asset management in the current document is handled by the &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;, which is accessible with &#039;&#039;&#039;$doc-&amp;gt;getWebAssetManager();&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:139--&amp;gt; By using AssetManager you can enable or disable needed assets easily in Joomla! through standard methods.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:140--&amp;gt; To enable an asset in the page, use the &#039;&#039;useAsset&#039;&#039; function:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;keepalive&#039;);&lt;br /&gt;
&lt;br /&gt;
// Or multiple&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;keepalive&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;fields.validate&#039;)&lt;br /&gt;
    -&amp;gt;useStyle(&#039;foobar&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add the new asset item with dependency and use it&lt;br /&gt;
$wa-&amp;gt;registerAndUseScript(&#039;bar&#039;, &#039;com_foobar/bar.js&#039;, [], [], [&#039;core&#039;, &#039;foobar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:141--&amp;gt; &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; will look to &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039; whether the requested asset exists, and will enable it for current Document instance. Otherwise it will throw an UnknownAssetException.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:142--&amp;gt; To disable an asset in the page use the &#039;&#039;disableAsset&#039;&#039; function. The example below will disable the &#039;&#039;jquery-noconflict&#039;&#039; asset from being loaded.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wa-&amp;gt;disableScript(&#039;jquery-noconflict&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:143--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; If there are any dependencies to the disabled asset, this asset will be re-enabled automatically, no matter what.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:144--&amp;gt; To check whether an asset is enabled, and determine the asset state:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Checking whether an asset are active (enabled manually or automatically as dependency).&lt;br /&gt;
if ($wa-&amp;gt;isAssetActive(&#039;script&#039;, &#039;foobar&#039;))&lt;br /&gt;
{&lt;br /&gt;
    var_dump(&#039;Script &amp;quot;foobar&amp;quot; is active!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checking state&lt;br /&gt;
switch($wa-&amp;gt;getAssetState(&#039;script&#039;, &#039;foobar&#039;)){&lt;br /&gt;
	case Joomla\CMS\WebAsset\WebAssetManager::ASSET_STATE_ACTIVE:&lt;br /&gt;
		var_dump(&#039;Active! Was enabled manually&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	case Joomla\CMS\WebAsset\WebAssetManager::ASSET_STATE_DEPENDENCY:&lt;br /&gt;
		var_dump(&#039;Active! Was enabled automatically while resolving dependencies&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	default:&lt;br /&gt;
		var_dump(&#039;not active!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Overriding an Asset == &amp;lt;!--T:145--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:146--&amp;gt;&lt;br /&gt;
Overriding may be useful when you need to redefine the URI of an asset item or its dependencies.&lt;br /&gt;
As already noted, each of the following asset definitions from the &#039;&#039;joomla.asset.json&#039;&#039; file will override asset items from previous assets definitions, by item name.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:147--&amp;gt;&lt;br /&gt;
If you provide a &#039;&#039;joomla.asset.json&#039;&#039; file that contains already-loaded asset items, they will be replaced with your items.&lt;br /&gt;
Another way to override in the code is to register an item with the same name.&lt;br /&gt;
Example: we have &#039;&#039;foobar&#039;&#039; script, that loads the &#039;&#039;com_example/foobar.js&#039;&#039; library, and we want to use CDN for this exact library:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:148--&amp;gt; How it defined in the system initially:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:149--&amp;gt; To override the URI, we define the asset item with &#039;&#039;foobar&#039;&#039; name in our &#039;&#039;joomla.asset.json&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;http://foobar.cdn.blabla/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:150--&amp;gt; Or, register a new asset item with the AssetManager:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;foobar&#039;, &#039;http://fobar.cdn.blabla/foobar.js&#039;, [], [], [&#039;core&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with Styles == &amp;lt;!--T:151--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt; The Asset Manager allows you to manage style sheet files. Style sheet asset items have a type &#039;&#039;style&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:153--&amp;gt; Example JSON definition of item in &#039;&#039;joomla.asset.json&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.css&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Styles === &amp;lt;!--T:154--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:155--&amp;gt; AssetManager offers the following methods to work with style files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach foobar to the document&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable foobar from being attached&lt;br /&gt;
$wa-&amp;gt;disableStyle(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerStyle(&#039;bar&#039;, &#039;com_example/bar.css&#039;, [], [&#039;data-foo&#039; =&amp;gt; &#039;some attribute&#039;], [&#039;some.dependency&#039;]);&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUseStyle(&#039;bar&#039;, &#039;com_example/bar.css&#039;, [], [&#039;data-foo&#039; =&amp;gt; &#039;some attribute&#039;], [&#039;some.dependency&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add Inline Style === &amp;lt;!--T:156--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:157--&amp;gt;&lt;br /&gt;
Additionally to style files, WebAssetManager allows you to add an inline style, and maintain their relation to the file asset.&lt;br /&gt;
Inline styles may be placed directly before the dependency, after the dependency, or as usual after all styles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:158--&amp;gt; Inline asset may have a name as well as other assets (but it is not required). The name can be used to retrieve the asset item from a registry, or as a dependency to another inline asset. If the name is not specified, a generated name based on a content hash will be used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Add an inline content as usual, will be rendered in flow after all assets&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline1&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed after &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [&#039;data-foo&#039; =&amp;gt; &#039;bar&#039;], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed before &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline3&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Named inline asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline4&#039;, [&#039;name&#039; =&amp;gt; &#039;my.inline.asset&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:159--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; The &#039;&#039;foobar&#039;&#039; asset must exist in the asset registry, otherwise you will get an unsatisfied dependency exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:160--&amp;gt; The example above will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline3&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;foobar.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style data-foo=&amp;quot;bar&amp;quot;&amp;gt;content of inline2&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline1&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline4&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:161--&amp;gt; If an inline asset has multiple dependencies, the last one will be used for positioning. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline1&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:162--&amp;gt; Will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;foo.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline1&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;bar.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline2&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:163--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Named inline assets may be a dependency to another inline asset, however it is not recommended to use an inline asset as dependency to non-inline asset. This might work, but this behavior may change in the future. Prefer to use &#039;&#039;position&#039;&#039; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with Scripts == &amp;lt;!--T:164--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:165--&amp;gt; The AssetManager allows you to manage JavaScript files. Script asset items have a type &#039;&#039;script&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:166--&amp;gt; Example JSON definition of item in &#039;&#039;joomla.asset.json&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:167--&amp;gt; An example JSON definition of ES6 module script, with fallback to legacy:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar-legacy&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-as5.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;nomodule&amp;quot;: true,&lt;br /&gt;
    &amp;quot;defer&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;core&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar-legacy&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Scripts === &amp;lt;!--T:168--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:169--&amp;gt; &lt;br /&gt;
The AssetManager offers these methods to work with script files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach foobar to the document&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable foobar from being attached&lt;br /&gt;
$wa-&amp;gt;disableScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;bar&#039;, &#039;com_example/bar.js&#039;, [], [&#039;defer&#039; =&amp;gt; true], [&#039;core&#039;]);&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUseScript(&#039;bar&#039;,&#039;com_example/bar.js&#039;, [], [&#039;defer&#039; =&amp;gt; true], [&#039;core&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add Inline Script === &amp;lt;!--T:170--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:171--&amp;gt;&lt;br /&gt;
In addition to script files, the WebAssetManager allows you to add an inline script, and maintain their relation to the file asset.&lt;br /&gt;
Inline script may be placed directly before the dependency, after the dependency, or as usual after all scripts.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:172--&amp;gt; Inline asset may have a name as well as other assets (but not required). The name can be used to retrieve the asset item form a registry, or as dependency to another inline asset. If a name is not specified, a generated name based on a content hash will be used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Add an inline content as usual. It will be rendered in flow after all assets.&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline1&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed after &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [&#039;data-foo&#039; =&amp;gt; &#039;bar&#039;], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed before &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline3&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Named inline asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline4&#039;, [&#039;name&#039; =&amp;gt; &#039;my.inline.asset&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Specify script type&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline5&#039;, [], [&#039;type&#039; =&amp;gt; &#039;module&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:173--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; The &#039;&#039;foobar&#039;&#039; asset should exist in the asset registry, otherwise you will get an unsatisfied dependency exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:174--&amp;gt; Example above will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline3&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;foobar.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script data-foo=&amp;quot;bar&amp;quot;&amp;gt;content of inline2&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline1&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline4&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;module&amp;quot;&amp;gt;content of inline5&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:175--&amp;gt; If an inline asset has multiple dependencies, the last one will be used for positioning. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline1&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:176--&amp;gt; Will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script src=&amp;quot;foo.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline1&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;bar.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline2&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:177--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Named inline assets may be a dependency on another inline asset. It is not recommended to use an inline asset as dependency to non-inline asset. This might work, but this behavior may changes in future. Prefer to use &#039;&#039;position&#039;&#039; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with a Web Component == &amp;lt;!--T:178--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:179--&amp;gt;&lt;br /&gt;
Joomla! allows you to use [https://developer.mozilla.org/en-US/docs/Web/Web_Components Web Components] for your needs. In Joomla! Web Components are not loaded as regular scripts, but loaded via the Web Component loader so that they are loaded asynchronously. Therefore, a Web Component asset item must have a flag &#039;&#039;webcomponent&#039;&#039; set to the boolean &#039;&#039;true&#039;&#039;.&lt;br /&gt;
In all other aspects, working with Web Components in the AssetManager is the same as working with a &#039;&#039;script&#039;&#039; asset item.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:180--&amp;gt; Example JSON definitions of some Web Components in the &#039;&#039;joomla.asset.json&#039;&#039; file (as ES6 module):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.css&amp;quot;,&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
     &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:181--&amp;gt; Example with fallback, for browsers that do not support ES6 &amp;quot;module&amp;quot; feature. Note that the legacy script should have &#039;&#039;wcpolyfill&#039;&#039; dependency, and module script should have dependency from the legacy script:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.css&amp;quot;,&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar-legacy&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element-es5.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;nomodule&amp;quot;: true,&lt;br /&gt;
    &amp;quot;defer&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;wcpolyfill&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;webcomponent.foobar-legacy&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:182--&amp;gt; Alternatively you can register them in PHP (as an ES6 module):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerStyle(&#039;webcomponent.foobar&#039;, &#039;com_example/foobar-custom-element.css&#039;)&lt;br /&gt;
    -&amp;gt;registerScript(&#039;webcomponent.foobar&#039;, &#039;com_example/foobar-custom-element.js&#039;, [&#039;type&#039; =&amp;gt; &#039;module&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:183--&amp;gt; Attach to document:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;webcomponent.foobar&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;webcomponent.foobar&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:184--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; It is preferred to prefix the asset name with &#039;&#039;webcomponent.&#039;&#039; to make it easy to spot, and distinguish it from regular scripts in a layout.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Web Component === &amp;lt;!--T:185--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:186--&amp;gt; All methods to work with a Web Component are the same as methods to work with script asset items.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with a Presets == &amp;lt;!--T:187--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:188--&amp;gt;&lt;br /&gt;
A &#039;&#039;preset&#039;&#039; is a special kind of asset item that holds a list of items to be enabled, in the same way as a direct call of &#039;&#039;useAsset()&#039;&#039; to each of item in the list.&lt;br /&gt;
Presets can hold mixed types of assets (script, style, another preset, etc.). The type should be provided after a # symbol and follows after an asset name. Example: foo#style, bar#script.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:189--&amp;gt; Example of a JSON definition of an item in &#039;&#039;joomla.asset.json&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;preset&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;core#script&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar#style&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar#script&amp;quot;,&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Preset === &amp;lt;!--T:190--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:191--&amp;gt; The AssetManager offers these methods to work with preset items:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach all items from foobar preset to the document&lt;br /&gt;
$wa-&amp;gt;usePreset(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable all items from foobar preset from being attached&lt;br /&gt;
$wa-&amp;gt;disablePreset(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerPreset(&#039;bar&#039;, &#039;&#039;, [], [], [&#039;core#script&#039;, &#039;bar#script&#039;]);&lt;br /&gt;
&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;usePreset(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUsePreset(&#039;bar&#039;,&#039;&#039;, [], [], [&#039;core#script&#039;, &#039;bar#script&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Advanced: Custom WebAssetItem Class == &amp;lt;!--T:192--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:193--&amp;gt; The default class for all WebAsset items is &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:194--&amp;gt; You are also allowed to use a custom class, which must implement &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItemInterface&#039;&#039;&#039; or extend &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:195--&amp;gt; A custom class allows you to do advanced actions. For example, including a script file depending on an active language:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class MyComExampleAssetItem extends WebAssetItem&lt;br /&gt;
{&lt;br /&gt;
	public function getUri($resolvePath = true): string&lt;br /&gt;
	{&lt;br /&gt;
		$langTag = Factory::getApplication()-&amp;gt;getLanguage()-&amp;gt;getTag();&lt;br /&gt;
		// For script asset use &amp;quot;.js&amp;quot;, for style we would use &amp;quot;.css&amp;quot;&lt;br /&gt;
		$path    = &#039;com_example/bar-&#039; . $langTag . &#039;.js&#039;;&lt;br /&gt;
&lt;br /&gt;
		if ($resolvePath)&lt;br /&gt;
		{&lt;br /&gt;
			// For script asset use &amp;quot;script&amp;quot;, for style we would use &amp;quot;stylesheet&amp;quot;&lt;br /&gt;
			$path = $this-&amp;gt;resolvePath($path, &#039;script&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return $path;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:196--&amp;gt; Additionally, implementing &#039;&#039;Joomla\CMS\WebAsset\WebAssetAttachBehaviorInterface&#039;&#039; allows you to add script options (which may depend on the environment) when your asset is enabled and attached to the Document.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class MyFancyFoobarAssetItem extends WebAssetItem implements WebAssetAttachBehaviorInterface&lt;br /&gt;
{&lt;br /&gt;
	public function onAttachCallback(Document $doc): void&lt;br /&gt;
	{&lt;br /&gt;
		$user = Factory::getApplication()-&amp;gt;getIdentity();&lt;br /&gt;
		$doc-&amp;gt;addScriptOptions(&#039;com_example.fancyfoobar&#039;, [&#039;userName&#039; =&amp;gt; $user-&amp;gt;username]);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:197--&amp;gt; &#039;&#039;&#039;Important Note&#039;&#039;&#039; An asset item that implements &#039;&#039;WebAssetAttachBehaviorInterface&#039;&#039; should be enabled before a [https://docs.joomla.org/Plugin/Events/System#onBeforeCompileHead onBeforeCompileHead] event, otherwise &#039;&#039;onAttachCallback&#039;&#039; will be ignored.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Defining a Custom WebAssetItem Class in &#039;&#039;joomla.asset.json&#039;&#039; === &amp;lt;!--T:198--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:199--&amp;gt;&lt;br /&gt;
In joomla.asset.json you can define which Class should be used with a specific Asset Item.&lt;br /&gt;
For this you can use two properties &#039;&#039;namespace&#039;&#039; and &#039;&#039;class&#039;&#039;. &#039;&#039;namespace&#039;&#039; can be defined at the Root level. Then it will be used as default namespace for all Asset items in the &#039;&#039;joomla.asset.json&#039;&#039; file or in the Item level. For example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;namespace&amp;quot;: &amp;quot;Joomla\Component\Example\WebAsset&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;foo&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;FooAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/foo.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;namespace&amp;quot;: &amp;quot;MyFooBar\Library\Example\WebAsset&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;BarAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:200--&amp;gt; Here the asset &#039;&#039;foo&#039;&#039; will be associated with class &#039;&#039;Joomla\Component\Example\WebAsset\FooAssetItem&#039;&#039;, and &#039;&#039;bar&#039;&#039; with class &#039;&#039;MyFooBar\Library\Example\WebAsset\BarAssetItem&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:201--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; If &#039;&#039;namespace&#039;&#039; is not defined, by default &#039;&#039;Joomla\CMS\WebAsset&#039;&#039; will be used. When &#039;&#039;namespace&#039;&#039; is defined but empty, no namespace will be used, only &#039;&#039;class&#039;&#039; will be used. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;foo&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;FooAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/foo.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;namespace&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;BarAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:202--&amp;gt; Here the asset &#039;&#039;foo&#039;&#039; will be associated with class &#039;&#039;Joomla\CMS\WebAsset\FooAssetItem&#039;&#039;, and &#039;&#039;bar&#039;&#039; with class &#039;&#039;BarAssetItem&#039;&#039; (without a namespace).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.0{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Standard_Module_Chromes&amp;diff=1015259</id>
		<title>Standard Module Chromes</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Standard_Module_Chromes&amp;diff=1015259"/>
		<updated>2023-10-09T21:04:42Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
Note that this example includes class additions because the examples are taken using &#039;&#039;mod_mainmenu&#039;&#039;. The suffix &amp;quot;_menu&amp;quot; on the div class and the &#039;&#039;menu&#039;&#039; class on the unordered list (ul) tag are not present with other modules.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;width:100%&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
Comparison of the Joomla! standard Module chromes&amp;lt;/translate&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
These are the same from Joomla! 1.5 through 3.x&amp;lt;/translate&amp;gt;&lt;br /&gt;
!width=&amp;quot;100&amp;quot; | &amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
Style&amp;lt;/translate&amp;gt;&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
Output&amp;lt;/translate&amp;gt;&lt;br /&gt;
!width=&amp;quot;210&amp;quot; | &amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
Appearance&amp;lt;/translate&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
rounded&amp;lt;/translate&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;module_menu&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div&amp;gt;&lt;br /&gt;
    &amp;lt;div&amp;gt;&lt;br /&gt;
      &amp;lt;div&amp;gt;&lt;br /&gt;
        &amp;lt;h3&amp;gt;Main Menu&amp;lt;/h3&amp;gt;&lt;br /&gt;
        &amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
          &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
        &amp;lt;/ul&amp;gt;&lt;br /&gt;
      &amp;lt;/div&amp;gt;&lt;br /&gt;
    &amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|[[Image:Module_chrome_rounded.png]]&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
none&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
[[Image:Module_chrome_none.png]]&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
table&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;table cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; class=&amp;quot;moduletable_menu&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;th valign=&amp;quot;top&amp;quot;&amp;gt;Main Menu&amp;lt;/th&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td&amp;gt;&lt;br /&gt;
      &amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
      &amp;lt;/ul&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|[[Image:Module_chrome_table.png]]&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
horz&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;table cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;0&amp;quot; border=&amp;quot;0&amp;quot; width=&amp;quot;100%&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;table cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;0&amp;quot; class=&amp;quot;moduletable_menu&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
          &amp;lt;th valign=&amp;quot;top&amp;quot;&amp;gt;Main Menu&amp;lt;/th&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
        &amp;lt;tr&amp;gt;&lt;br /&gt;
          &amp;lt;td&amp;gt;&lt;br /&gt;
            &amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
              &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
            &amp;lt;/ul&amp;gt;&lt;br /&gt;
          &amp;lt;/td&amp;gt;&lt;br /&gt;
        &amp;lt;/tr&amp;gt;&lt;br /&gt;
      &amp;lt;/table&amp;gt;&lt;br /&gt;
    &amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|[[Image:Module_chrome_horz.png]]&lt;br /&gt;
|-&lt;br /&gt;
!xhtml&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;moduletable_menu&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;h3&amp;gt;Main Menu&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
|[[Image:Module_chrome_xhtml.png]]&lt;br /&gt;
|-&lt;br /&gt;
!html5&lt;br /&gt;
|&amp;lt;!--- leave as html4strict/html5 not available yet ---&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;well _menu&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;h3 class=&amp;quot;page-header&amp;quot;&amp;gt;Main Menu&amp;lt;/h3&amp;gt;&lt;br /&gt;
  &amp;lt;ul class=&amp;quot;nav menu&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
  &amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlightv&amp;gt;&lt;br /&gt;
|[[Image:Module_chrome_html5.png]]&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
outline&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod-preview&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;mod-preview-info&amp;quot;&amp;gt;left[outline]&amp;lt;/div&amp;gt;&lt;br /&gt;
  &amp;lt;div class=&amp;quot;mod-preview-wrapper&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;ul class=&amp;quot;menu&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;li&amp;gt;&amp;lt;!-- various menu items --&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
    &amp;lt;/ul&amp;gt;&lt;br /&gt;
  &amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
| [[Image:Module_chrome_outline.png]]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Note that the Module chrome doesn&#039;t change the appearance all that much—this depends on the CSS used in the template. For example, the &#039;&#039;none&#039;&#039; and &#039;&#039;horz&#039;&#039; chromes look similar, although the underlying HTML code is different.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
Other notes: The &#039;&#039;horz&#039;&#039; is just the &#039;&#039;table&#039;&#039; layout, wrapped in a &#039;&#039;table&#039;&#039;, &#039;&#039;tr&#039;&#039;, and &#039;&#039;td&#039;&#039;.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
Until Joomla! 3: The software controlling these is in the file&amp;lt;/translate&amp;gt; &#039;&#039;/templates/system/html/modules.php&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Changes since Joomla! 4&#039;&#039;&#039;&lt;br /&gt;
* The standard chromes &#039;&#039;horz&#039;&#039;, &#039;&#039;rounded&#039;&#039; and &#039;&#039;xhtml&#039;&#039; have been removed from core.&lt;br /&gt;
* The core module chromes are controlled by &#039;&#039;JLayout&#039;&#039; files in directory &#039;&#039;/layouts/chromes/&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
[[Category:Advanced|Chrome]]&lt;br /&gt;
[[Category:Module Development]]&lt;br /&gt;
[[Category:Template Development]]&lt;br /&gt;
[[Category:CSS]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Using_Bootstrap_Components_in_Joomla_4&amp;diff=1014598</id>
		<title>J4.x:Using Bootstrap Components in Joomla 4</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Using_Bootstrap_Components_in_Joomla_4&amp;diff=1014598"/>
		<updated>2023-09-24T20:45:28Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Bootstrap Components ===&lt;br /&gt;
Some of the components described in the Bootstrap documentation use CSS only. For example, the Breadcrumbs component is rendered with CSS and requires no JavaScript support. Others respond to user actions such as click or hover, and need JavaScript support. The latter are referred to here as Interactive Components. This article explains how to use them in Articles and a Custom Module.&lt;br /&gt;
&lt;br /&gt;
See: [https://getbootstrap.com/docs/5.0/getting-started/introduction/ Bootstrap Documentation]&lt;br /&gt;
&lt;br /&gt;
=== Joomla 4 Introduces a Modular Approach for Interactive Components ===&lt;br /&gt;
* What is a modular approach?&lt;br /&gt;
* The functionality is broken down into individual components supported by individual files. There is no &#039;&#039;&#039;one file&#039;&#039;&#039; approach as it was with Bootstrap in Joomla 3. The modular approach is more efficient and offers performance gains. (Send only the code that is needed instead of delivering everything in case some page will need some component.)&lt;br /&gt;
&lt;br /&gt;
=== Using Interactive Components: Coders ===&lt;br /&gt;
* Load what you need per case! There are helper functions to set up individual components with appropriate arguments.&lt;br /&gt;
* See the list of Bootstrap Interactive Components.&lt;br /&gt;
&lt;br /&gt;
=== Using Interactive Components: Non-Coders ===&lt;br /&gt;
* Using components in articles is not so easy because the helper functions cannot be called from an article or standard Custom HTML module. Three possible solutions are suggested later in this tutorial:&lt;br /&gt;
** A custom module&lt;br /&gt;
** A custom plugin&lt;br /&gt;
** A custom module override&lt;br /&gt;
* Skip or scan the list of Bootstrap Interactive Components. You won&#039;t be using these function calls directly.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap Interactive Components ==&lt;br /&gt;
=== Alert ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.alert&#039;, &#039;.selector&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the alert. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* No extra options available&lt;br /&gt;
&lt;br /&gt;
=== Button ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.button&#039;, &#039;.selector&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the button. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* No extra options available&lt;br /&gt;
&lt;br /&gt;
=== Carousel ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.carousel&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the carousel. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for carousel&lt;br /&gt;
&lt;br /&gt;
Options for the carousel can be:&lt;br /&gt;
* &#039;&#039;&#039;interval&#039;&#039;&#039;, number, default:&#039;&#039;&#039;5000&#039;&#039;&#039;, The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.&lt;br /&gt;
* &#039;&#039;&#039;keyboard&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Whether the carousel should react to keyboard events.&lt;br /&gt;
* &#039;&#039;&#039;pause&#039;&#039;&#039;, string|boolean, &#039;&#039;&#039;hover&#039;&#039;&#039; Pauses the cycling of the carousel on &#039;&#039;mouseenter&#039;&#039; and resumes the cycling of the carousel on &#039;&#039;mouseleave&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;slide&#039;&#039;&#039;, string|boolean, default:&#039;&#039;&#039;false&#039;&#039;&#039; Autoplays the carousel after the user manually cycles the first item. If &amp;quot;carousel&amp;quot;, autoplays the carousel on load.&lt;br /&gt;
&lt;br /&gt;
=== Collapse ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.collapse&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the collapse. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for collapse&lt;br /&gt;
&lt;br /&gt;
Options for the collapse can be:&lt;br /&gt;
* &#039;&#039;&#039;parent&#039;&#039;&#039;, string, default:&#039;&#039;&#039;false&#039;&#039;&#039; If parent is provided, then all collapsible elements under the specified parent will be closed when this collapsible item is shown.&lt;br /&gt;
* &#039;&#039;&#039;toggle&#039;&#039;&#039;, boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Toggles the collapsible element on invocation&lt;br /&gt;
&lt;br /&gt;
=== Dropdown ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.dropdown&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the dropdown. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for dropdown&lt;br /&gt;
&lt;br /&gt;
Options for the collapse can be:&lt;br /&gt;
* &#039;&#039;&#039;flip&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Allow Dropdown to flip in case of an overlapping on the reference element&lt;br /&gt;
* &#039;&#039;&#039;boundary&#039;&#039;&#039;, string, default:&#039;&#039;&#039;scrollParent&#039;&#039;&#039; Overflow constraint boundary of the dropdown menu&lt;br /&gt;
* &#039;&#039;&#039;reference&#039;&#039;&#039;, string, default:&#039;&#039;&#039;toggle&#039;&#039;&#039; Reference element of the dropdown menu. Accepts &#039;&#039;&#039;toggle&#039;&#039;&#039; or &#039;&#039;&#039;parent&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;display&#039;&#039;&#039;, string, default:&#039;&#039;&#039;dynamic&#039;&#039;&#039; By default, we use Popper for dynamic positioning. Disable this with &#039;&#039;&#039;static&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Modal ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.modal&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the modal. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for modal&lt;br /&gt;
&lt;br /&gt;
Options for the modal can be:&lt;br /&gt;
* &#039;&#039;&#039;backdrop&#039;&#039;&#039;, string|boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Includes a modal-backdrop element. Alternatively, specify static for a backdrop which doesn&#039;t close the modal on click.&lt;br /&gt;
* &#039;&#039;&#039;keyboard&#039;&#039;&#039;, boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Closes the modal when escape key is pressed&lt;br /&gt;
* &#039;&#039;&#039;focus&#039;&#039;&#039;, boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Closes the modal when escape key is pressed&lt;br /&gt;
&lt;br /&gt;
=== Offcanvas ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.offcanvas&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the offcanvas. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for offcanvas&lt;br /&gt;
&lt;br /&gt;
Options for the offcanvas can be:&lt;br /&gt;
* &#039;&#039;&#039;backdrop&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Apply a backdrop on body while offcanvas is open&lt;br /&gt;
* &#039;&#039;&#039;keyboard&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Closes the offcanvas when escape key is pressed&lt;br /&gt;
* &#039;&#039;&#039;scroll&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;false&#039;&#039;&#039; Allow body scrolling while offcanvas is open&lt;br /&gt;
&lt;br /&gt;
=== Popover ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.popover&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the popover. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for popover&lt;br /&gt;
&lt;br /&gt;
Options for the popover can be:&lt;br /&gt;
* &#039;&#039;&#039;animation&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Apply a CSS fade transition to the popover&lt;br /&gt;
* &#039;&#039;&#039;container&#039;&#039;&#039;, string|boolean, default:&#039;&#039;&#039;false&#039;&#039;&#039;  Appends the popover to a specific element. Eg.: &#039;&#039;&#039;body&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;content&#039;&#039;&#039;, string, default:&#039;&#039;&#039;null&#039;&#039;&#039;   Default content value if data-bs-content attribute isn&#039;t present&lt;br /&gt;
* &#039;&#039;&#039;delay&#039;&#039;&#039;, number, default:&#039;&#039;&#039;0&#039;&#039;&#039;      Delay showing and hiding the popover (ms) does not apply to manual trigger type&lt;br /&gt;
* &#039;&#039;&#039;html&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039;   Insert HTML into the popover. If &#039;&#039;&#039;false&#039;&#039;&#039;, innerText property will be used to insert content into the DOM.&lt;br /&gt;
* &#039;&#039;&#039;placement&#039;&#039;&#039;, string, default:&#039;&#039;&#039;right&#039;&#039;&#039;  How to position the popover - &#039;&#039;&#039;auto&#039;&#039;&#039; | &#039;&#039;&#039;top&#039;&#039;&#039; | &#039;&#039;&#039;bottom&#039;&#039;&#039; | &#039;&#039;&#039;left&#039;&#039;&#039; | &#039;&#039;&#039;right&#039;&#039;&#039;. When auto is specified, it will dynamically reorient the popover&lt;br /&gt;
* &#039;&#039;&#039;selector&#039;&#039;&#039;, string, default:&#039;&#039;&#039;false&#039;&#039;&#039;  If a selector is provided, popover objects will be delegated to the specified targets.&lt;br /&gt;
* &#039;&#039;&#039;template&#039;&#039;&#039;, string, default:&#039;&#039;&#039;null&#039;&#039;&#039;   Base HTML to use when creating the popover.&lt;br /&gt;
* &#039;&#039;&#039;title&#039;&#039;&#039;, string, default:&#039;&#039;&#039;null&#039;&#039;&#039;   Default title value if &#039;&#039;&#039;title&#039;&#039;&#039; tag isn&#039;t present&lt;br /&gt;
* &#039;&#039;&#039;trigger&#039;&#039;&#039;, string, default:&#039;&#039;&#039;click&#039;&#039;&#039;  How popover is triggered - &#039;&#039;&#039;click&#039;&#039;&#039; | &#039;&#039;&#039;hover&#039;&#039;&#039; | &#039;&#039;&#039;focus&#039;&#039;&#039; | &#039;&#039;&#039;manual&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;, integer, default:&#039;&#039;&#039;0&#039;&#039;&#039;      Offset of the popover relative to its target.&lt;br /&gt;
&lt;br /&gt;
=== Scrollspy ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.scrollspy&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the scrollspy. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for scrollspy&lt;br /&gt;
&lt;br /&gt;
Options for the Scrollspy can be:&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;  number  Pixels to offset from top when calculating position of scroll.&lt;br /&gt;
* &#039;&#039;&#039;method&#039;&#039;&#039;  string  Finds which section the spied element is in.&lt;br /&gt;
* &#039;&#039;&#039;target&#039;&#039;&#039;  string  Specifies element to apply Scrollspy plugin.&lt;br /&gt;
&lt;br /&gt;
=== Tab ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tab&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the tab. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for tab&lt;br /&gt;
&lt;br /&gt;
Options for the Tab can be:&lt;br /&gt;
&lt;br /&gt;
=== Tooltip ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tooltip&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the tooltip. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for tooltip&lt;br /&gt;
&lt;br /&gt;
Options for the tooltip can be:&lt;br /&gt;
* &#039;&#039;&#039;animation&#039;&#039;&#039;, boolean          apply a css fade transition to the popover&lt;br /&gt;
* &#039;&#039;&#039;container&#039;&#039;&#039;, string|boolean   Appends the popover to a specific element: { container: &#039;&#039;&#039;body&#039;&#039;&#039; }&lt;br /&gt;
* &#039;&#039;&#039;delay&#039;&#039;&#039;, number|object    delay showing and hiding the popover (ms) - does not apply to manual trigger type If a number is supplied, delay is applied to both hide/show Object structure is: delay: { show: 500, hide: 100 }&lt;br /&gt;
* &#039;&#039;&#039;html&#039;&#039;&#039;, boolean Insert HTML into the popover. If false, jQuery&#039;s text method will be used to insert content into the dom.&lt;br /&gt;
* &#039;&#039;&#039;placement&#039;&#039;&#039;, string|function  how to position the popover - &#039;&#039;&#039;top&#039;&#039;&#039; | &#039;&#039;&#039;bottom&#039;&#039;&#039; | &#039;&#039;&#039;left&#039;&#039;&#039; | &#039;&#039;&#039;right&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;selector&#039;&#039;&#039; string If a selector is provided, popover objects will be delegated to the specified targets.&lt;br /&gt;
* &#039;&#039;&#039;template&#039;&#039;&#039;, string           Base HTML to use when creating the popover.&lt;br /&gt;
* &#039;&#039;&#039;title&#039;&#039;&#039;, string|function  default title value if &#039;&#039;&#039;title&#039;&#039;&#039; tag isn&#039;t present&lt;br /&gt;
* &#039;&#039;&#039;trigger&#039;&#039;&#039;, string           how popover is triggered - hover | focus | manual&lt;br /&gt;
* &#039;&#039;&#039;constraints&#039;&#039;&#039;, array            An array of constraints - passed through to Popper.&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;, string           Offset of the popover relative to its target.&lt;br /&gt;
&lt;br /&gt;
=== Toast ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.toast&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the toast. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for toast&lt;br /&gt;
&lt;br /&gt;
Options for the toast can be:&lt;br /&gt;
* &#039;&#039;&#039;animation&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Apply a CSS fade transition to the toast&lt;br /&gt;
* &#039;&#039;&#039;autohide&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Auto hide the toast&lt;br /&gt;
* &#039;&#039;&#039;delay&#039;&#039;&#039;, number	, default:&#039;&#039;&#039;5000&#039;&#039;&#039; Delay hiding the toast (ms)&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
* &#039;&#039;&#039;Accordian&#039;&#039;&#039; uses Collapse to display panels of data.&lt;br /&gt;
* &#039;&#039;&#039;List Group&#039;&#039;&#039; can be combined with Tab to display tabbed content.&lt;br /&gt;
&lt;br /&gt;
== Using Bootstrap Components in Articles ==&lt;br /&gt;
The HTML mark-up for most components can be included in an article or a module that can itself be included in an article. The snag is that the HTMLHelper call to set up the JavaScript support cannot be included there. There are several possible approaches to this problem. Three approaches are suggested here, using a custom Module, using a Plugin or using a Template override.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Caution:&#039;&#039;&#039; The TinyMCE and JCE editors remove white space on Save and make editing code difficult! The simple solution is to go to the top right of your Administrator screen and select {{rarr|User Menu,Edit Account}} and set the Editor to Code Mirror.&lt;br /&gt;
&lt;br /&gt;
== Approach 1: Using a Custom Module ==&lt;br /&gt;
This is probably the least error prone approach because the Bootstrap component support options are selected with check boxes. The steps involved are as follows:&lt;br /&gt;
&lt;br /&gt;
* Download, install and enable this module: https://github.com/ceford/j4xdemos-mod-custom-bscompos/raw/master/mod_custom_bscompos.zip&lt;br /&gt;
* From the Administrator menu go to {{rarr|Content,Site Modules,New}}&lt;br /&gt;
* Select &#039;&#039;&#039;Custom BS Components&#039;&#039;&#039;&lt;br /&gt;
* Enter a Title&lt;br /&gt;
* Toggle the Editor to plain text mode and paste in or type in the HTML code for the component you want to use.&lt;br /&gt;
* In the Options tab scroll down to the list of BS Components and select type of component in this instance of the module. Note that you can select more than one if your using more than one component.&lt;br /&gt;
* Select a module Position: either&lt;br /&gt;
** a template defined position if you want to use the module in a specific location or &lt;br /&gt;
** type in a position if you wish to use the module within a specific article: in the article type in &amp;amp;lt;div&amp;gt;{loadposition whatever}&amp;amp;lt;/div&amp;gt;&lt;br /&gt;
* Save and go to the site to Test!&lt;br /&gt;
&lt;br /&gt;
=== Selectors ===&lt;br /&gt;
For some components JavaScript action is triggered by a specific &#039;&#039;&#039;class&#039;&#039;&#039; in the HTML code. In other components action is triggered by a &#039;&#039;&#039;data-bs-whatever&#039;&#039;&#039; attribute. The following are the current triggers and may change:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Alert&#039;&#039;&#039; triggered by class=&amp;quot;alert ...&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Button&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;button&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Carousel&#039;&#039;&#039; triggered by data-bs-ride=&amp;quot;whatever&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Collapse&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;collapse&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Dropdown&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;dropdown&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Modal&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;modal&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Offcanvas&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;offcanvas&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Popover&#039;&#039;&#039; triggered by class=&amp;quot;btn ...&amp;quot; or &amp;amp;lt;a ...&amp;gt; tag (could be changed to class=&amp;quot;haspopover ...&amp;quot;) AND data-bs-toggle=&amp;quot;popover&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Scrollspy&#039;&#039;&#039; triggered by data-bs-spy=&amp;quot;scroll&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Tab&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;tab&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Toast&#039;&#039;&#039; triggered by class=&amp;quot;toast ...&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Tooltip&#039;&#039;&#039; triggered by class=&amp;quot;btn ...&amp;quot; or &amp;amp;lt;a ...&amp;gt; tag (could be changed to class=&amp;quot;hastooltip ...&amp;quot;) AND data-bs-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Example 1: Alert ===&lt;br /&gt;
Alerts may be used in html code without JavaScript support. This is only needed for the dismiss capability. HTML code example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;alert alert-warning alert-dismissible fade show&amp;quot; role=&amp;quot;alert&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;strong&amp;gt;Holy guacamole!&amp;lt;/strong&amp;gt; You should check in on some of those fields below.&lt;br /&gt;
  &amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn-close&amp;quot; data-bs-dismiss=&amp;quot;alert&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example result of including a module in an article:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-alert-demo.png|border|Alert Demo]]&lt;br /&gt;
&lt;br /&gt;
Note that without JavaScript support, the alert will appear exactly as above but a click on the close button [X] will not dismiss the alert. Also, the alert will appear on every page load.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Buttons ===&lt;br /&gt;
Buttons may be used in HTML code without JavaScript support. This is only needed for the sometimes subtle change of style applied to buttons with a change of state, styled active. Bootstrap example code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot; autocomplete=&amp;quot;off&amp;quot;&amp;gt;Toggle button&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary active&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot; autocomplete=&amp;quot;off&amp;quot; aria-pressed=&amp;quot;true&amp;quot;&amp;gt;Active toggle button&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary&amp;quot; disabled data-bs-toggle=&amp;quot;button&amp;quot; autocomplete=&amp;quot;off&amp;quot;&amp;gt;Disabled toggle button&amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;btn btn-primary&amp;quot; role=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot;&amp;gt;Toggle link&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;btn btn-primary active&amp;quot; role=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot; aria-pressed=&amp;quot;true&amp;quot;&amp;gt;Active toggle link&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;btn btn-primary disabled&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-disabled=&amp;quot;true&amp;quot; role=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot;&amp;gt;Disabled toggle link&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this style in the template user.css:&lt;br /&gt;
&amp;lt;pre&amp;gt;.btn.btn-primary.active {&lt;br /&gt;
	background-color: green;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-button-demo.png|border|Button Demo]]&lt;br /&gt;
&lt;br /&gt;
The buttons toggle between blue and green.&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Carousel ===&lt;br /&gt;
The Carousel offers a slide show cycling through a series of images or text panes. The following example used images from the Joomla 4 Sample. Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;carouselExampleCaptions&amp;quot; class=&amp;quot;carousel slide&amp;quot; data-bs-ride=&amp;quot;carousel&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;carousel-indicators&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;button class=&amp;quot;active&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;0&amp;quot; aria-current=&amp;quot;true&amp;quot; aria-label=&amp;quot;Slide 1&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
		&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;1&amp;quot; aria-label=&amp;quot;Slide 2&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
		&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;2&amp;quot; aria-label=&amp;quot;Slide 3&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;carousel-inner&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;carousel-item active&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa1-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5&amp;gt;First slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;p&amp;gt;Some representative placeholder content for the first slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa2-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5&amp;gt;Second slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;p&amp;gt;Some representative placeholder content for the second slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa3-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5&amp;gt;Third slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;p&amp;gt;Some representative placeholder content for the third slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;button class=&amp;quot;carousel-control-prev&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;prev&amp;quot;&amp;gt; &lt;br /&gt;
		&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Previous&amp;lt;/span&amp;gt; &lt;br /&gt;
	&amp;lt;/button&amp;gt; &lt;br /&gt;
	&amp;lt;button class=&amp;quot;carousel-control-next&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;next&amp;quot;&amp;gt; &lt;br /&gt;
		&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Next&amp;lt;/span&amp;gt; &lt;br /&gt;
	&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-carousel-demo.jpg|border|Carousel Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Collapse ===&lt;br /&gt;
Collapse is widely used in Joomla and you may not need to use a module or plugin to trigger action. The click opens a pane with extra information. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
	&amp;lt;a class=&amp;quot;btn btn-primary&amp;quot; role=&amp;quot;button&amp;quot; href=&amp;quot;#collapseExample&amp;quot; data-bs-toggle=&amp;quot;collapse&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-controls=&amp;quot;collapseExample&amp;quot;&amp;gt; Link with href &amp;lt;/a&amp;gt; &lt;br /&gt;
	&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;collapse&amp;quot; data-bs-target=&amp;quot;#collapseExample&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-controls=&amp;quot;collapseExample&amp;quot;&amp;gt; &lt;br /&gt;
		Button with data-bs-target &lt;br /&gt;
	&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;collapseExample&amp;quot; class=&amp;quot;collapse&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;card card-body&amp;quot;&amp;gt;&lt;br /&gt;
		Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger.&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-collapse-demo.png|border|Collapse Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Dropdown ===&lt;br /&gt;
Dropdowns are toggleable, contextual overlays for displaying lists of links and more. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;btn-group&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;button class=&amp;quot;btn btn-danger dropdown-toggle&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;dropdown&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt; Action &amp;lt;/button&amp;gt;&lt;br /&gt;
	&amp;lt;ul class=&amp;quot;dropdown-menu&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Another action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Something else here&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;hr class=&amp;quot;dropdown-divider&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Separated link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-dropdown-demo.png|border|Dropdown Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Modal ===&lt;br /&gt;
The Modal component opens a dialog box in the middle of the screen. There are quite a few options to control the size and content of the modal. See the Bootstrap documentation for more details. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;modal&amp;quot; data-bs-target=&amp;quot;#exampleModal&amp;quot;&amp;gt; Launch demo modal &amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;exampleModal&amp;quot; class=&amp;quot;modal fade&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-labelledby=&amp;quot;exampleModalLabel&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;modal-dialog&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;modal-content&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5 id=&amp;quot;exampleModalLabel&amp;quot; class=&amp;quot;modal-title&amp;quot;&amp;gt;Modal title&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn-close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;&lt;br /&gt;
				...&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-footer&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt; &lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot;&amp;gt;Save changes&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-modal-demo.png|Modal Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Offcanvas ===&lt;br /&gt;
At the moment this component is not supported in Joomla. Watch this space - coming soon!&lt;br /&gt;
&lt;br /&gt;
=== Example 8: Popover ===&lt;br /&gt;
Popovers are like Tooltips but with a Title. They have some accessibility and performance issues so should be used with caution. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-lg btn-danger&amp;quot; title=&amp;quot;Popover title&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;popover&amp;quot; data-bs-content=&amp;quot;And here&#039;s some amazing content. It&#039;s very engaging. Right?&amp;quot;&amp;gt;Click to toggle popover&amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-popover-demo.png|border|Popover Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 9: Scrollspy ===&lt;br /&gt;
Example code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;col-4&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;nav id=&amp;quot;navbar-example3&amp;quot; class=&amp;quot;navbar navbar-light bg-light flex-column&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Navbar&amp;lt;/a&amp;gt;&amp;lt;nav class=&amp;quot;nav nav-pills flex-column&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;a class=&amp;quot;nav-link active&amp;quot; href=&amp;quot;#item-1&amp;quot;&amp;gt;Item 1&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;nav class=&amp;quot;nav nav-pills flex-column&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-1-1&amp;quot;&amp;gt;Item 1-1&amp;lt;/a&amp;gt; &lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-1-2&amp;quot;&amp;gt;Item 1-2&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/nav&amp;gt;&lt;br /&gt;
			&amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;#item-2&amp;quot;&amp;gt;Item 2&amp;lt;/a&amp;gt; &lt;br /&gt;
			&amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;#item-3&amp;quot;&amp;gt;Item 3&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;nav class=&amp;quot;nav nav-pills flex-column&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-3-1&amp;quot;&amp;gt;Item 3-1&amp;lt;/a&amp;gt; &lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-3-2&amp;quot;&amp;gt;Item 3-2&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/nav&amp;gt;&lt;br /&gt;
		&amp;lt;/nav&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;col-8&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;scrollspy-example&amp;quot; tabindex=&amp;quot;0&amp;quot; data-bs-spy=&amp;quot;scroll&amp;quot; data-bs-target=&amp;quot;#navbar-example3&amp;quot; data-bs-offset=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;h4 id=&amp;quot;item-1&amp;quot;&amp;gt;Item 1&amp;lt;/h4&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 1. Takes you miles high, so high, &#039;cause she’s got that one international smile. There&#039;s a stranger in my bed, there&#039;s a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents&#039; liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin&#039; heavy. Her love is like a drug. I guess that I forgot I had a choice.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-1-1&amp;quot;&amp;gt;Item 1-1&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to the item 1-1. You got the finest architecture. Passport stamps, she&#039;s cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I&#039;d be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she&#039;s the one. Greetings loved ones let&#039;s take a journey. Just own the night like the 4th of July! But you&#039;d rather get wasted.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-1-2&amp;quot;&amp;gt;Item 1-2&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to the item 1-2. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. &#039;Cause she&#039;s the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I&#039;m walking, I&#039;m walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h4 id=&amp;quot;item-2&amp;quot;&amp;gt;Item 2&amp;lt;/h4&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 2. Don&#039;t need apologies. There is no fear now, let go and just be free, I will love you unconditionally. Last Friday night. Don&#039;t be a shy kinda guy I&#039;ll bet it&#039;s beautiful. Summer after high school when we first met. &#039;Cause she&#039;s the muse and the artist. What? Wait. No, no, no, no. Thought that I was the exception.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h4 id=&amp;quot;item-3&amp;quot;&amp;gt;Item 3&amp;lt;/h4&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 3. Word on the street, you got somethin&#039; to show me, me. All this money can&#039;t buy me a time machine. Make it like your birthday everyday. So we hit the boulevard. You make me feel like I&#039;m livin&#039; a teenage dream, the way you turn me on Skip the talk, heard it all, time to walk the walk. Word on the street, you got somethin&#039; to show me, me. It&#039;s no big deal, it&#039;s no big deal, it&#039;s no big deal.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-3-1&amp;quot;&amp;gt;Item 3-1&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 3-1. Baby do you dare to do this? This is no big deal. Yeah, you&#039;re lucky if you&#039;re on her plane. Just own the night like the 4th of July! Standing on the frontline when the bombs start to fall. So just be sure before you give it all to me.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-3-2&amp;quot;&amp;gt;Item 3-2&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 3-2. You&#039;re original, cannot be replaced. All night they&#039;re playing, your song. California girls we&#039;re undeniable. Like a bird without a cage. There is no fear now, let go and just be free, I will love you unconditionally. I can see the writing on the wall. You could travel the world but nothing comes close to the golden coast.&amp;lt;/p&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-scrollspy-demo.png|border|Scrollspy Demo]]&lt;br /&gt;
&lt;br /&gt;
Also, some styling is needed in user.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;.scrollspy-example {&lt;br /&gt;
	height: 350px;&lt;br /&gt;
	overflow-y: scroll;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Snag: the menu does not coordinate well with the content in this example!&lt;br /&gt;
&lt;br /&gt;
=== Example 10: Tab ===&lt;br /&gt;
Tabs are often used as navigation elements combined with dropdowns. Bootstrap example code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ul class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link active&amp;quot; href=&amp;quot;#&amp;quot; aria-current=&amp;quot;page&amp;quot;&amp;gt;Active&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item dropdown&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; role=&amp;quot;button&amp;quot; href=&amp;quot;#&amp;quot; data-bs-toggle=&amp;quot;dropdown&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;Dropdown&amp;lt;/a&amp;gt;&lt;br /&gt;
		&amp;lt;ul class=&amp;quot;dropdown-menu&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Another action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Something else here&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;hr class=&amp;quot;dropdown-divider&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Separated link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link disabled&amp;quot; tabindex=&amp;quot;-1&amp;quot; href=&amp;quot;#&amp;quot; aria-disabled=&amp;quot;true&amp;quot;&amp;gt;Disabled&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-tab-demo.png|border|Tab Demo]]&lt;br /&gt;
&lt;br /&gt;
Remember to check both the Tab and Dropdown options for the dropdown part to work.&lt;br /&gt;
&lt;br /&gt;
=== Example 11: Toast ===&lt;br /&gt;
Toasts are lightweight notifications designed to mimic the push notifications that have been popularized by mobile and desktop operating systems. They’re built with flexbox, so they’re easy to align and position. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;toast fade show&amp;quot; role=&amp;quot;alert&amp;quot; aria-live=&amp;quot;assertive&amp;quot; aria-atomic=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;toast-header&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;img class=&amp;quot;rounded me-2&amp;quot; src=&amp;quot;...&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt; &lt;br /&gt;
		&amp;lt;strong class=&amp;quot;me-auto&amp;quot;&amp;gt;Bootstrap&amp;lt;/strong&amp;gt; &amp;lt;small&amp;gt;11 mins ago&amp;lt;/small&amp;gt; &lt;br /&gt;
		&amp;lt;button class=&amp;quot;btn-close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;toast&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;toast-body&amp;quot;&amp;gt;Hello, world! This is a toast message.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-toast-demo.png|border|Toast Demo]]&lt;br /&gt;
&lt;br /&gt;
Note that the Bootstrap demo that uses a button to show the Toast message needs some extra JavaScript. It seems this component needs a coder to make good use of it!&lt;br /&gt;
&lt;br /&gt;
=== Example 12: Tooltip ===&lt;br /&gt;
A tooltip is a small piece of text that appears on hover over a button or link element to explain what it is or does. The tooltip can be positioned above or below or to the left or right of the element. If not specified the default position is top. The tooltip will switch to another position if there is insufficient room in the specified position. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on left&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;left&amp;quot;&amp;gt; Tooltip on left &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot;&amp;gt; Tooltip &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on top&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;top&amp;quot;&amp;gt; Tooltip on top &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on right&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;right&amp;quot;&amp;gt; Tooltip on right &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on bottom&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;bottom&amp;quot;&amp;gt; Tooltip on bottom &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;&amp;amp;lt;em&amp;amp;gt;Tooltip&amp;amp;lt;/em&amp;amp;gt; &amp;amp;lt;u&amp;amp;gt;with&amp;amp;lt;/u&amp;amp;gt; &amp;amp;lt;b&amp;amp;gt;HTML&amp;amp;lt;/b&amp;amp;gt;&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-html=&amp;quot;true&amp;quot;&amp;gt; Tooltip with HTML &amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Tooltip triggered by class: &amp;lt;button class=&amp;quot;btn btn-warning&amp;quot; title=&amp;quot;Tooltip Message&amp;quot;&amp;gt;Alert!&amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-tooltip-demo.png|border|Tooltip Demo]]&lt;br /&gt;
&lt;br /&gt;
== Approach 2: Using a Content Plugin ==&lt;br /&gt;
The steps involved:&lt;br /&gt;
* Download, install and enable this plugin: https://github.com/ceford/j4xdemos-plg-bscompos/raw/master/plg_j4xdemos_bscompos.zip&lt;br /&gt;
* In the article add the text that the plugin acts on. For example &#039;&#039;{bscompos modal carousel}&#039;&#039; will trigger loading of the JavaScript necessary to support a modal dialog and a carousel. The plugin removes the trigger text and enclosing (now) empty &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/nowiki&amp;gt; tags.&lt;br /&gt;
* Include the Bootstrap Component HTML code directly in the article or in a module invoked in the article. There is example HTML code below for a simple Modal and a Modal containing a Carousel. Note that this will not work if the HTML code is in a module in a template location.&lt;br /&gt;
* This will also work for a standard Custom module if the &#039;&#039;Prepare Content Option&#039;&#039; is set to &#039;&#039;Yes&#039;&#039;.&lt;br /&gt;
* Test it!&lt;br /&gt;
&lt;br /&gt;
== Approach 3: Using a Template Override ==&lt;br /&gt;
The steps involved:&lt;br /&gt;
* Create a &#039;&#039;mod_custom&#039;&#039; template override.&lt;br /&gt;
* Add a module of type custom containing the component markup and trigger classes.&lt;br /&gt;
* Load the module into an article using [[How do you put a module inside an article?|&#039;&#039;loadposition&#039;&#039;, &#039;&#039;loadmodule&#039;&#039; or &#039;&#039;loadmoduleid&#039;&#039;]].&lt;br /&gt;
&lt;br /&gt;
=== The &#039;&#039;mod_custom&#039;&#039; Template Override ===&lt;br /&gt;
* In the Administrator go to {{rarr|System, Site Templates, Cassiopeia Details and Files}}.&lt;br /&gt;
* Select {{rarr|Create Overrides, mod_custom, default.php}}.&lt;br /&gt;
* On the line following &#039;&#039;defined(&#039;_JEXEC&#039;) or die;&#039;&#039; add this code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$module_class = $params-&amp;gt;get(&#039;moduleclass_sfx&#039;);&lt;br /&gt;
if (!empty($module_class))&lt;br /&gt;
{&lt;br /&gt;
    $classes = explode(&#039; &#039;, $module_class);&lt;br /&gt;
    foreach ($classes as $class)&lt;br /&gt;
    {&lt;br /&gt;
	switch ($class)&lt;br /&gt;
        {&lt;br /&gt;
          case &#039;bs-alert&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.alert&#039;, &#039;.alert&#039;);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-button&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.button&#039;, &#039;.btn&#039;);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-carousel&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.carousel&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-collapse&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.collapse&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-dropdown&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.dropdown&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-modal&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.modal&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-offcanvas&#039;:&lt;br /&gt;
            // Not Found&lt;br /&gt;
            //\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.offcanvas&#039;, &#039;.btn&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-popover&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.popover&#039;, &#039;.btn&#039;, []);&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.popover&#039;, &#039;a&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-scrollspy&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.scrollspy&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-tab&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tab&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-tooltip&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tooltip&#039;, &#039;.btn&#039;, []);&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tooltip&#039;, &#039;a&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-toast&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.toast&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          default:&lt;br /&gt;
            // do nothing&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
This code searches for class names set in mod_custom and makes the HTMLHelper call to set up the JavaScript support. Note that the next to last item in each call is a selector that may or may not be used to trigger action. Many of the components are triggered by data attributes in the mark-up and they do not use the selectors here. For some, the selector is needed. For example, it makes sense to use the &#039;&#039;.btn&#039;&#039; class and the &#039;&#039;a&#039;&#039; tag to trigger Tooltips.&lt;br /&gt;
&lt;br /&gt;
=== A &#039;&#039;mod_custom&#039;&#039; Module for a Modal Component ===&lt;br /&gt;
* Go to {{rarr|Content, Site Modules, New}}.&lt;br /&gt;
* Select the &#039;&#039;&#039;Custom&#039;&#039;&#039; module.&lt;br /&gt;
* Fill out the form:&lt;br /&gt;
** Title: Demo Modal&lt;br /&gt;
** In the Position field type in &#039;&#039;&#039;demomodal&#039;&#039;&#039; for use in an article;&lt;br /&gt;
** Module Content: Toggle Editor for plain text entry.&lt;br /&gt;
** Paste in the following code from the Bootstrap documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Modal&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!-- Button trigger modal --&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;modal&amp;quot; data-bs-target=&amp;quot;#exampleModal&amp;quot;&amp;gt; Launch demo modal &amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;!-- Modal --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;exampleModal&amp;quot; class=&amp;quot;modal fade&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-labelledby=&amp;quot;exampleModalLabel&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;modal-dialog&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;modal-content&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5 id=&amp;quot;exampleModalLabel&amp;quot; class=&amp;quot;modal-title&amp;quot;&amp;gt;Modal title&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn-close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;&lt;br /&gt;
				...&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-footer&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt; &lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot;&amp;gt;Save changes&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Select the Advanced tab and in the Module Class field enter &#039;&#039;&#039;bs-modal&#039;&#039;&#039;&lt;br /&gt;
* Optional: set Ttitle to Hide to use the H2 in the pasted code.&lt;br /&gt;
* Save and Close (do not worry that the modal looks all wrong in the editor).&lt;br /&gt;
&lt;br /&gt;
=== Create an Article and Menu Item ===&lt;br /&gt;
* Create a new article, Demo Modal, and in plain text entry mode set the content to &amp;lt;pre&amp;gt;&amp;lt;div&amp;gt;{loadposition demomodal}&amp;lt;/div&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create a Single Article menu item.&lt;br /&gt;
* Test it:&lt;br /&gt;
[[File:Demomodal.png|none|Bootstrap Modal in an Article]]&lt;br /&gt;
&lt;br /&gt;
=== A Modal Component Containing a Carousel ===&lt;br /&gt;
* Create a new Custom module with a new Title: Demo Modal Carousel&lt;br /&gt;
* Position: demomodalcarousel&lt;br /&gt;
* {{rarr|Advance tab, Module Class}}: bs-modal bs-carousel&lt;br /&gt;
* Module Custom content in plain text:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Modal with Carousel&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod-custom custom&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;!-- Button trigger modal --&amp;gt; &lt;br /&gt;
	&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;modal&amp;quot; data-bs-target=&amp;quot;#exampleModal&amp;quot;&amp;gt; Launch demo modal &amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;exampleModal&amp;quot; class=&amp;quot;modal fade&amp;quot; style=&amp;quot;display: none;&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;modal-dialog&amp;quot; role=&amp;quot;document&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;modal-content&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt; &lt;br /&gt;
					&amp;lt;span aria-hidden=&amp;quot;true&amp;quot;&amp;gt;×&amp;lt;/span&amp;gt; &lt;br /&gt;
				&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;carouselExampleCaptions&amp;quot; class=&amp;quot;carousel slide&amp;quot; data-bs-ride=&amp;quot;carousel&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;carousel-indicators&amp;quot;&amp;gt;&lt;br /&gt;
						&amp;lt;button class=&amp;quot;active&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;0&amp;quot; aria-current=&amp;quot;true&amp;quot; aria-label=&amp;quot;Slide 1&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
						&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;1&amp;quot; aria-label=&amp;quot;Slide 2&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
						&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;2&amp;quot; aria-label=&amp;quot;Slide 3&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;carousel-inner&amp;quot;&amp;gt;&lt;br /&gt;
						&amp;lt;div class=&amp;quot;carousel-item active&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa1-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
							&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
								&amp;lt;h5&amp;gt;First slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
								&amp;lt;p&amp;gt;Some representative placeholder content for the first slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
							&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa2-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
							&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
								&amp;lt;h5&amp;gt;Second slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
								&amp;lt;p&amp;gt;Some representative placeholder content for the second slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
							&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa3-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
							&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
								&amp;lt;h5&amp;gt;Third slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
								&amp;lt;p&amp;gt;Some representative placeholder content for the third slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
							&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;button class=&amp;quot;carousel-control-prev&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;prev&amp;quot;&amp;gt; &lt;br /&gt;
						&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Previous&amp;lt;/span&amp;gt; &lt;br /&gt;
					&amp;lt;/button&amp;gt; &lt;br /&gt;
					&amp;lt;button class=&amp;quot;carousel-control-next&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;next&amp;quot;&amp;gt; &lt;br /&gt;
						&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Next&amp;lt;/span&amp;gt; &lt;br /&gt;
					&amp;lt;/button&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Create a new Article with &amp;lt;nowiki&amp;gt;&amp;lt;div&amp;gt;{loadposition demomodalcarousel}&amp;lt;/div&amp;gt;&amp;lt;/nowiki&amp;gt; in the content.&lt;br /&gt;
* Create a new single article menu item: Demo Modal Carousel&lt;br /&gt;
* Test it:&lt;br /&gt;
[[File:Demomodalcarousel.png|Demo Modal containing a Carousel]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Plugin Development{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla!_4.x{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Using_Bootstrap_Components_in_Joomla_4&amp;diff=1014597</id>
		<title>J4.x:Using Bootstrap Components in Joomla 4</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Using_Bootstrap_Components_in_Joomla_4&amp;diff=1014597"/>
		<updated>2023-09-22T22:24:49Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
&lt;br /&gt;
=== Bootstrap Components ===&lt;br /&gt;
Some of the components described in the Bootstrap documentation use CSS only. For example, the Breadcrumbs component is rendered with CSS and requires no JavaScript support. Others respond to user actions such as click or hover, and need JavaScript support. The latter are referred to here as Interactive Components. This article explains how to use them in Articles and a Custom Module.&lt;br /&gt;
&lt;br /&gt;
See: [https://getbootstrap.com/docs/5.0/getting-started/introduction/ Bootstrap Documentation]&lt;br /&gt;
&lt;br /&gt;
=== Joomla 4 Introduces a Modular Approach for Interactive Components ===&lt;br /&gt;
* What is a modular approach?&lt;br /&gt;
* The functionality is broken down into individual components supported by individual files. There is no &#039;&#039;&#039;one file&#039;&#039;&#039; approach as it was with Bootstrap in Joomla 3. The modular approach is more efficient and offers performance gains. (Send only the code that is needed instead of delivering everything in case some page will need some component.)&lt;br /&gt;
&lt;br /&gt;
=== Using Interactive Components: Coders ===&lt;br /&gt;
* Load what you need per case! There are helper functions to set up individual components with appropriate arguments.&lt;br /&gt;
* See the list of Bootstrap Interactive Components.&lt;br /&gt;
&lt;br /&gt;
=== Using Interactive Components: Non-Coders ===&lt;br /&gt;
* Using components in articles is not so easy because the helper functions cannot be called from an article or standard Custom HTML module. Three possible solutions are suggested later in this tutorial:&lt;br /&gt;
** A custom module&lt;br /&gt;
** A custom plugin&lt;br /&gt;
** A custom module override&lt;br /&gt;
* Skip or scan the list of Bootstrap Interactive Components. You won&#039;t be using these function calls directly.&lt;br /&gt;
&lt;br /&gt;
== Bootstrap Interactive Components ==&lt;br /&gt;
=== Alert ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.alert&#039;, &#039;.selector&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the alert. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* No extra options available&lt;br /&gt;
&lt;br /&gt;
=== Button ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.button&#039;, &#039;.selector&#039;);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the button. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* No extra options available&lt;br /&gt;
&lt;br /&gt;
=== Carousel ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.carousel&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the carousel. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for carousel&lt;br /&gt;
&lt;br /&gt;
Options for the carousel can be:&lt;br /&gt;
* &#039;&#039;&#039;interval&#039;&#039;&#039;, number, default:&#039;&#039;&#039;5000&#039;&#039;&#039;, The amount of time to delay between automatically cycling an item. If false, carousel will not automatically cycle.&lt;br /&gt;
* &#039;&#039;&#039;keyboard&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Whether the carousel should react to keyboard events.&lt;br /&gt;
* &#039;&#039;&#039;pause&#039;&#039;&#039;, string|boolean, &#039;&#039;&#039;hover&#039;&#039;&#039; Pauses the cycling of the carousel on &#039;&#039;mouseenter&#039;&#039; and resumes the cycling of the carousel on &#039;&#039;mouseleave&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;slide&#039;&#039;&#039;, string|boolean, default:&#039;&#039;&#039;false&#039;&#039;&#039; Autoplays the carousel after the user manually cycles the first item. If &amp;quot;carousel&amp;quot;, autoplays the carousel on load.&lt;br /&gt;
&lt;br /&gt;
=== Collapse ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.collapse&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the collapse. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for collapse&lt;br /&gt;
&lt;br /&gt;
Options for the collapse can be:&lt;br /&gt;
* &#039;&#039;&#039;parent&#039;&#039;&#039;, string, default:&#039;&#039;&#039;false&#039;&#039;&#039; If parent is provided, then all collapsible elements under the specified parent will be closed when this collapsible item is shown.&lt;br /&gt;
* &#039;&#039;&#039;toggle&#039;&#039;&#039;, boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Toggles the collapsible element on invocation&lt;br /&gt;
&lt;br /&gt;
=== Dropdown ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.dropdown&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the dropdown. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for dropdown&lt;br /&gt;
&lt;br /&gt;
Options for the collapse can be:&lt;br /&gt;
* &#039;&#039;&#039;flip&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Allow Dropdown to flip in case of an overlapping on the reference element&lt;br /&gt;
* &#039;&#039;&#039;boundary&#039;&#039;&#039;, string, default:&#039;&#039;&#039;scrollParent&#039;&#039;&#039; Overflow constraint boundary of the dropdown menu&lt;br /&gt;
* &#039;&#039;&#039;reference&#039;&#039;&#039;, string, default:&#039;&#039;&#039;toggle&#039;&#039;&#039; Reference element of the dropdown menu. Accepts &#039;&#039;&#039;toggle&#039;&#039;&#039; or &#039;&#039;&#039;parent&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;display&#039;&#039;&#039;, string, default:&#039;&#039;&#039;dynamic&#039;&#039;&#039; By default, we use Popper for dynamic positioning. Disable this with &#039;&#039;&#039;static&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Modal ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.modal&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the modal. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for modal&lt;br /&gt;
&lt;br /&gt;
Options for the modal can be:&lt;br /&gt;
* &#039;&#039;&#039;backdrop&#039;&#039;&#039;, string|boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Includes a modal-backdrop element. Alternatively, specify static for a backdrop which doesn&#039;t close the modal on click.&lt;br /&gt;
* &#039;&#039;&#039;keyboard&#039;&#039;&#039;, boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Closes the modal when escape key is pressed&lt;br /&gt;
* &#039;&#039;&#039;focus&#039;&#039;&#039;, boolean default:&#039;&#039;&#039;true&#039;&#039;&#039; Closes the modal when escape key is pressed&lt;br /&gt;
&lt;br /&gt;
=== Offcanvas ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.offcanvas&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the offcanvas. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for offcanvas&lt;br /&gt;
&lt;br /&gt;
Options for the offcanvas can be:&lt;br /&gt;
* &#039;&#039;&#039;backdrop&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Apply a backdrop on body while offcanvas is open&lt;br /&gt;
* &#039;&#039;&#039;keyboard&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Closes the offcanvas when escape key is pressed&lt;br /&gt;
* &#039;&#039;&#039;scroll&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;false&#039;&#039;&#039; Allow body scrolling while offcanvas is open&lt;br /&gt;
&lt;br /&gt;
=== Popover ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.popover&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the popover. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for popover&lt;br /&gt;
&lt;br /&gt;
Options for the popover can be:&lt;br /&gt;
* &#039;&#039;&#039;animation&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Apply a CSS fade transition to the popover&lt;br /&gt;
* &#039;&#039;&#039;container&#039;&#039;&#039;, string|boolean, default:&#039;&#039;&#039;false&#039;&#039;&#039;  Appends the popover to a specific element. Eg.: &#039;&#039;&#039;body&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;content&#039;&#039;&#039;, string, default:&#039;&#039;&#039;null&#039;&#039;&#039;   Default content value if data-bs-content attribute isn&#039;t present&lt;br /&gt;
* &#039;&#039;&#039;delay&#039;&#039;&#039;, number, default:&#039;&#039;&#039;0&#039;&#039;&#039;      Delay showing and hiding the popover (ms) does not apply to manual trigger type&lt;br /&gt;
* &#039;&#039;&#039;html&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039;   Insert HTML into the popover. If &#039;&#039;&#039;false&#039;&#039;&#039;, innerText property will be used to insert content into the DOM.&lt;br /&gt;
* &#039;&#039;&#039;placement&#039;&#039;&#039;, string, default:&#039;&#039;&#039;right&#039;&#039;&#039;  How to position the popover - &#039;&#039;&#039;auto&#039;&#039;&#039; | &#039;&#039;&#039;top&#039;&#039;&#039; | &#039;&#039;&#039;bottom&#039;&#039;&#039; | &#039;&#039;&#039;left&#039;&#039;&#039; | &#039;&#039;&#039;right&#039;&#039;&#039;. When auto is specified, it will dynamically reorient the popover&lt;br /&gt;
* &#039;&#039;&#039;selector&#039;&#039;&#039;, string, default:&#039;&#039;&#039;false&#039;&#039;&#039;  If a selector is provided, popover objects will be delegated to the specified targets.&lt;br /&gt;
* &#039;&#039;&#039;template&#039;&#039;&#039;, string, default:&#039;&#039;&#039;null&#039;&#039;&#039;   Base HTML to use when creating the popover.&lt;br /&gt;
* &#039;&#039;&#039;title&#039;&#039;&#039;, string, default:&#039;&#039;&#039;null&#039;&#039;&#039;   Default title value if &#039;&#039;&#039;title&#039;&#039;&#039; tag isn&#039;t present&lt;br /&gt;
* &#039;&#039;&#039;trigger&#039;&#039;&#039;, string, default:&#039;&#039;&#039;click&#039;&#039;&#039;  How popover is triggered - &#039;&#039;&#039;click&#039;&#039;&#039; | &#039;&#039;&#039;hover&#039;&#039;&#039; | &#039;&#039;&#039;focus&#039;&#039;&#039; | &#039;&#039;&#039;manual&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;, integer, default:&#039;&#039;&#039;0&#039;&#039;&#039;      Offset of the popover relative to its target.&lt;br /&gt;
&lt;br /&gt;
=== Scrollspy ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.scrollspy&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the scrollspy. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for scrollspy&lt;br /&gt;
&lt;br /&gt;
Options for the Scrollspy can be:&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;  number  Pixels to offset from top when calculating position of scroll.&lt;br /&gt;
* &#039;&#039;&#039;method&#039;&#039;&#039;  string  Finds which section the spied element is in.&lt;br /&gt;
* &#039;&#039;&#039;target&#039;&#039;&#039;  string  Specifies element to apply Scrollspy plugin.&lt;br /&gt;
&lt;br /&gt;
=== Tab ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tab&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the tab. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for tab&lt;br /&gt;
&lt;br /&gt;
Options for the Tab can be:&lt;br /&gt;
&lt;br /&gt;
=== Tooltip ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tooltip&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the tooltip. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for tooltip&lt;br /&gt;
&lt;br /&gt;
Options for the tooltip can be:&lt;br /&gt;
* &#039;&#039;&#039;animation&#039;&#039;&#039;, boolean          apply a css fade transition to the popover&lt;br /&gt;
* &#039;&#039;&#039;container&#039;&#039;&#039;, string|boolean   Appends the popover to a specific element: { container: &#039;&#039;&#039;body&#039;&#039;&#039; }&lt;br /&gt;
* &#039;&#039;&#039;delay&#039;&#039;&#039;, number|object    delay showing and hiding the popover (ms) - does not apply to manual trigger type If a number is supplied, delay is applied to both hide/show Object structure is: delay: { show: 500, hide: 100 }&lt;br /&gt;
* &#039;&#039;&#039;html&#039;&#039;&#039;, boolean Insert HTML into the popover. If false, jQuery&#039;s text method will be used to insert content into the dom.&lt;br /&gt;
* &#039;&#039;&#039;placement&#039;&#039;&#039;, string|function  how to position the popover - &#039;&#039;&#039;top&#039;&#039;&#039; | &#039;&#039;&#039;bottom&#039;&#039;&#039; | &#039;&#039;&#039;left&#039;&#039;&#039; | &#039;&#039;&#039;right&#039;&#039;&#039;&lt;br /&gt;
* &#039;&#039;&#039;selector&#039;&#039;&#039; string If a selector is provided, popover objects will be delegated to the specified targets.&lt;br /&gt;
* &#039;&#039;&#039;template&#039;&#039;&#039;, string           Base HTML to use when creating the popover.&lt;br /&gt;
* &#039;&#039;&#039;title&#039;&#039;&#039;, string|function  default title value if &#039;&#039;&#039;title&#039;&#039;&#039; tag isn&#039;t present&lt;br /&gt;
* &#039;&#039;&#039;trigger&#039;&#039;&#039;, string           how popover is triggered - hover | focus | manual&lt;br /&gt;
* &#039;&#039;&#039;constraints&#039;&#039;&#039;, array            An array of constraints - passed through to Popper.&lt;br /&gt;
* &#039;&#039;&#039;offset&#039;&#039;&#039;, string           Offset of the popover relative to its target.&lt;br /&gt;
&lt;br /&gt;
=== Toast ===&lt;br /&gt;
Assuming you have the HTML part already in your Layout, you will also need to include the interactivity (the JavaScript part): &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.toast&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* The &#039;&#039;&#039;.selector&#039;&#039;&#039; refers to the CSS selector for the toast. You can call this function multiple times with different CSS selectors&lt;br /&gt;
* The third argument refers to the options available for toast&lt;br /&gt;
&lt;br /&gt;
Options for the toast can be:&lt;br /&gt;
* &#039;&#039;&#039;animation&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Apply a CSS fade transition to the toast&lt;br /&gt;
* &#039;&#039;&#039;autohide&#039;&#039;&#039;, boolean, default:&#039;&#039;&#039;true&#039;&#039;&#039; Auto hide the toast&lt;br /&gt;
* &#039;&#039;&#039;delay&#039;&#039;&#039;, number	, default:&#039;&#039;&#039;5000&#039;&#039;&#039; Delay hiding the toast (ms)&lt;br /&gt;
&lt;br /&gt;
=== See Also ===&lt;br /&gt;
* &#039;&#039;&#039;Accordian&#039;&#039;&#039; uses Collapse to display panels of data.&lt;br /&gt;
* &#039;&#039;&#039;List Group&#039;&#039;&#039; can be combined with Tab to display tabbed content.&lt;br /&gt;
&lt;br /&gt;
== Using Bootstrap Components in Articles ==&lt;br /&gt;
The HTML mark-up for most components can be included in an article or a module that can itself be included in an article. The snag is that the HTMLHelper call to set up the JavaScript support cannot be included there. There are several possible approaches to this problem. Three approaches are suggested here, using a custom Module, using a Plugin or using a Template override.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Caution:&#039;&#039;&#039; The TinyMCE and JCE editors remove white space on Save and make editing code difficult! The simple solution is to go to the top right of your Administrator screen and select {{rarr|User Menu,Edit Account}} and set the Editor to Code Mirror.&lt;br /&gt;
&lt;br /&gt;
== Approach 1: Using a Custom Module ==&lt;br /&gt;
This is probably the least error prone approach because the Bootstrap component support options are selected with check boxes. The steps involved are as follows:&lt;br /&gt;
&lt;br /&gt;
* Download, install and enable this module: https://github.com/ceford/j4xdemos-mod-custom-bscompos/raw/master/mod_custom_bscompos.zip&lt;br /&gt;
* From the Administrator menu go to {{rarr|Content,Site Modules,New}}&lt;br /&gt;
* Select &#039;&#039;&#039;Custom BS Components&#039;&#039;&#039;&lt;br /&gt;
* Enter a Title&lt;br /&gt;
* Toggle the Editor to plain text mode and paste in or type in the HTML code for the component you want to use.&lt;br /&gt;
* In the Options tab scroll down to the list of BS Components and select type of component in this instance of the module. Note that you can select more than one if your using more than one component.&lt;br /&gt;
* Select a module Position: either&lt;br /&gt;
** a template defined position if you want to use the module in a specific location or &lt;br /&gt;
** type in a position if you wish to use the module within a specific article: in the article type in &amp;amp;lt;div&amp;gt;{loadposition whatever}&amp;amp;lt;/div&amp;gt;&lt;br /&gt;
* Save and go to the site to Test!&lt;br /&gt;
&lt;br /&gt;
=== Selectors ===&lt;br /&gt;
For some components JavaScript action is triggered by a specific &#039;&#039;&#039;class&#039;&#039;&#039; in the HTML code. In other components action is triggered by a &#039;&#039;&#039;data-bs-whatever&#039;&#039;&#039; attribute. The following are the current triggers and may change:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Alert&#039;&#039;&#039; triggered by class=&amp;quot;alert ...&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Button&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;button&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Carousel&#039;&#039;&#039; triggered by data-bs-ride=&amp;quot;whatever&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Collapse&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;collapse&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Dropdown&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;dropdown&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Modal&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;modal&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Offcanvas&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;offcanvas&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Popover&#039;&#039;&#039; triggered by class=&amp;quot;btn ...&amp;quot; or &amp;amp;lt;a ...&amp;gt; tag (could be changed to class=&amp;quot;haspopover ...&amp;quot;) AND data-bs-toggle=&amp;quot;popover&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Scrollspy&#039;&#039;&#039; triggered by data-bs-spy=&amp;quot;scroll&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Tab&#039;&#039;&#039; triggered by data-bs-toggle=&amp;quot;tab&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Toast&#039;&#039;&#039; triggered by class=&amp;quot;toast ...&amp;quot;&lt;br /&gt;
* &#039;&#039;&#039;Tooltip&#039;&#039;&#039; triggered by class=&amp;quot;btn ...&amp;quot; or &amp;amp;lt;a ...&amp;gt; tag (could be changed to class=&amp;quot;hastooltip ...&amp;quot;) AND data-bs-toggle=&amp;quot;tooltip&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Example 1: Alert ===&lt;br /&gt;
Alerts may be used in html code without JavaScript support. This is only needed for the dismiss capability. HTML code example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;div class=&amp;quot;alert alert-warning alert-dismissible fade show&amp;quot; role=&amp;quot;alert&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;strong&amp;gt;Holy guacamole!&amp;lt;/strong&amp;gt; You should check in on some of those fields below.&lt;br /&gt;
  &amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn-close&amp;quot; data-bs-dismiss=&amp;quot;alert&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Example result of including a module in an article:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-alert-demo.png|border|Alert Demo]]&lt;br /&gt;
&lt;br /&gt;
Note that without JavaScript support, the alert will appear exactly as above but a click on the close button [X] will not dismiss the alert. Also, the alert will appear on every page load.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Buttons ===&lt;br /&gt;
Buttons may be used in HTML code without JavaScript support. This is only needed for the sometimes subtle change of style applied to buttons with a change of state, styled active. Bootstrap example code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot; autocomplete=&amp;quot;off&amp;quot;&amp;gt;Toggle button&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary active&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot; autocomplete=&amp;quot;off&amp;quot; aria-pressed=&amp;quot;true&amp;quot;&amp;gt;Active toggle button&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;button type=&amp;quot;button&amp;quot; class=&amp;quot;btn btn-primary&amp;quot; disabled data-bs-toggle=&amp;quot;button&amp;quot; autocomplete=&amp;quot;off&amp;quot;&amp;gt;Disabled toggle button&amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;btn btn-primary&amp;quot; role=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot;&amp;gt;Toggle link&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;btn btn-primary active&amp;quot; role=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot; aria-pressed=&amp;quot;true&amp;quot;&amp;gt;Active toggle link&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;#&amp;quot; class=&amp;quot;btn btn-primary disabled&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-disabled=&amp;quot;true&amp;quot; role=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;button&amp;quot;&amp;gt;Disabled toggle link&amp;lt;/a&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this style in the template user.css:&lt;br /&gt;
&amp;lt;pre&amp;gt;.btn.btn-primary.active {&lt;br /&gt;
	background-color: green;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-button-demo.png|border|Button Demo]]&lt;br /&gt;
&lt;br /&gt;
The buttons toggle between blue and green.&lt;br /&gt;
&lt;br /&gt;
=== Example 3: Carousel ===&lt;br /&gt;
The Carousel offers a slide show cycling through a series of images or text panes. The following example used images from the Joomla 4 Sample. Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;carouselExampleCaptions&amp;quot; class=&amp;quot;carousel slide&amp;quot; data-bs-ride=&amp;quot;carousel&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;carousel-indicators&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;button class=&amp;quot;active&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;0&amp;quot; aria-current=&amp;quot;true&amp;quot; aria-label=&amp;quot;Slide 1&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
		&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;1&amp;quot; aria-label=&amp;quot;Slide 2&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
		&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;2&amp;quot; aria-label=&amp;quot;Slide 3&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;carousel-inner&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;carousel-item active&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa1-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5&amp;gt;First slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;p&amp;gt;Some representative placeholder content for the first slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa2-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5&amp;gt;Second slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;p&amp;gt;Some representative placeholder content for the second slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa3-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5&amp;gt;Third slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;p&amp;gt;Some representative placeholder content for the third slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;button class=&amp;quot;carousel-control-prev&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;prev&amp;quot;&amp;gt; &lt;br /&gt;
		&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Previous&amp;lt;/span&amp;gt; &lt;br /&gt;
	&amp;lt;/button&amp;gt; &lt;br /&gt;
	&amp;lt;button class=&amp;quot;carousel-control-next&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;next&amp;quot;&amp;gt; &lt;br /&gt;
		&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Next&amp;lt;/span&amp;gt; &lt;br /&gt;
	&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-carousel-demo.jpg|border|Carousel Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Collapse ===&lt;br /&gt;
Collapse is widely used in Joomla and you may not need to use a module or plugin to trigger action. The click opens a pane with extra information. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
	&amp;lt;a class=&amp;quot;btn btn-primary&amp;quot; role=&amp;quot;button&amp;quot; href=&amp;quot;#collapseExample&amp;quot; data-bs-toggle=&amp;quot;collapse&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-controls=&amp;quot;collapseExample&amp;quot;&amp;gt; Link with href &amp;lt;/a&amp;gt; &lt;br /&gt;
	&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;collapse&amp;quot; data-bs-target=&amp;quot;#collapseExample&amp;quot; aria-expanded=&amp;quot;false&amp;quot; aria-controls=&amp;quot;collapseExample&amp;quot;&amp;gt; &lt;br /&gt;
		Button with data-bs-target &lt;br /&gt;
	&amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;collapseExample&amp;quot; class=&amp;quot;collapse&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;card card-body&amp;quot;&amp;gt;&lt;br /&gt;
		Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger.&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-collapse-demo.png|border|Collapse Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Dropdown ===&lt;br /&gt;
Dropdowns are toggleable, contextual overlays for displaying lists of links and more. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;btn-group&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;button class=&amp;quot;btn btn-danger dropdown-toggle&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;dropdown&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt; Action &amp;lt;/button&amp;gt;&lt;br /&gt;
	&amp;lt;ul class=&amp;quot;dropdown-menu&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Another action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Something else here&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;hr class=&amp;quot;dropdown-divider&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Separated link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-dropdown-demo.png|border|Dropdown Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Modal ===&lt;br /&gt;
The Modal component opens a dialog box in the middle of the screen. There are quite a few options to control the size and content of the modal. See the Bootstrap documentation for more details. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;modal&amp;quot; data-bs-target=&amp;quot;#exampleModal&amp;quot;&amp;gt; Launch demo modal &amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;exampleModal&amp;quot; class=&amp;quot;modal fade&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-labelledby=&amp;quot;exampleModalLabel&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;modal-dialog&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;modal-content&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5 id=&amp;quot;exampleModalLabel&amp;quot; class=&amp;quot;modal-title&amp;quot;&amp;gt;Modal title&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn-close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;&lt;br /&gt;
				...&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-footer&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt; &lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot;&amp;gt;Save changes&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-modal-demo.png|Modal Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Offcanvas ===&lt;br /&gt;
At the moment this component is not supported in Joomla. Watch this space - coming soon!&lt;br /&gt;
&lt;br /&gt;
=== Example 8: Popover ===&lt;br /&gt;
Popovers are like Tooltips but with a Title. They have some accessibility and performance issues so should be used with caution. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-lg btn-danger&amp;quot; title=&amp;quot;Popover title&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;popover&amp;quot; data-bs-content=&amp;quot;And here&#039;s some amazing content. It&#039;s very engaging. Right?&amp;quot;&amp;gt;Click to toggle popover&amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-popover-demo.png|border|Popover Demo]]&lt;br /&gt;
&lt;br /&gt;
=== Example 9: Scrollspy ===&lt;br /&gt;
Example code:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;row&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;col-4&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;nav id=&amp;quot;navbar-example3&amp;quot; class=&amp;quot;navbar navbar-light bg-light flex-column&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;a class=&amp;quot;navbar-brand&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Navbar&amp;lt;/a&amp;gt;&amp;lt;nav class=&amp;quot;nav nav-pills flex-column&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;a class=&amp;quot;nav-link active&amp;quot; href=&amp;quot;#item-1&amp;quot;&amp;gt;Item 1&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;nav class=&amp;quot;nav nav-pills flex-column&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-1-1&amp;quot;&amp;gt;Item 1-1&amp;lt;/a&amp;gt; &lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-1-2&amp;quot;&amp;gt;Item 1-2&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/nav&amp;gt;&lt;br /&gt;
			&amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;#item-2&amp;quot;&amp;gt;Item 2&amp;lt;/a&amp;gt; &lt;br /&gt;
			&amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;#item-3&amp;quot;&amp;gt;Item 3&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;nav class=&amp;quot;nav nav-pills flex-column&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-3-1&amp;quot;&amp;gt;Item 3-1&amp;lt;/a&amp;gt; &lt;br /&gt;
				&amp;lt;a class=&amp;quot;nav-link ms-3 my-1&amp;quot; href=&amp;quot;#item-3-2&amp;quot;&amp;gt;Item 3-2&amp;lt;/a&amp;gt;&lt;br /&gt;
			&amp;lt;/nav&amp;gt;&lt;br /&gt;
		&amp;lt;/nav&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;col-8&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;scrollspy-example&amp;quot; tabindex=&amp;quot;0&amp;quot; data-bs-spy=&amp;quot;scroll&amp;quot; data-bs-target=&amp;quot;#navbar-example3&amp;quot; data-bs-offset=&amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;h4 id=&amp;quot;item-1&amp;quot;&amp;gt;Item 1&amp;lt;/h4&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 1. Takes you miles high, so high, &#039;cause she’s got that one international smile. There&#039;s a stranger in my bed, there&#039;s a pounding in my head. Oh, no. In another life I would make you stay. ‘Cause I, I’m capable of anything. Suiting up for my crowning battle. Used to steal your parents&#039; liquor and climb to the roof. Tone, tan fit and ready, turn it up cause its gettin&#039; heavy. Her love is like a drug. I guess that I forgot I had a choice.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-1-1&amp;quot;&amp;gt;Item 1-1&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to the item 1-1. You got the finest architecture. Passport stamps, she&#039;s cosmopolitan. Fine, fresh, fierce, we got it on lock. Never planned that one day I&#039;d be losing you. She eats your heart out. Your kiss is cosmic, every move is magic. I mean the ones, I mean like she&#039;s the one. Greetings loved ones let&#039;s take a journey. Just own the night like the 4th of July! But you&#039;d rather get wasted.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-1-2&amp;quot;&amp;gt;Item 1-2&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to the item 1-2. Her love is like a drug. All my girls vintage Chanel baby. Got a motel and built a fort out of sheets. &#039;Cause she&#039;s the muse and the artist. (This is how we do) So you wanna play with magic. So just be sure before you give it all to me. I&#039;m walking, I&#039;m walking on air (tonight). Skip the talk, heard it all, time to walk the walk. Catch her if you can. Stinging like a bee I earned my stripes.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h4 id=&amp;quot;item-2&amp;quot;&amp;gt;Item 2&amp;lt;/h4&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 2. Don&#039;t need apologies. There is no fear now, let go and just be free, I will love you unconditionally. Last Friday night. Don&#039;t be a shy kinda guy I&#039;ll bet it&#039;s beautiful. Summer after high school when we first met. &#039;Cause she&#039;s the muse and the artist. What? Wait. No, no, no, no. Thought that I was the exception.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h4 id=&amp;quot;item-3&amp;quot;&amp;gt;Item 3&amp;lt;/h4&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 3. Word on the street, you got somethin&#039; to show me, me. All this money can&#039;t buy me a time machine. Make it like your birthday everyday. So we hit the boulevard. You make me feel like I&#039;m livin&#039; a teenage dream, the way you turn me on Skip the talk, heard it all, time to walk the walk. Word on the street, you got somethin&#039; to show me, me. It&#039;s no big deal, it&#039;s no big deal, it&#039;s no big deal.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-3-1&amp;quot;&amp;gt;Item 3-1&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 3-1. Baby do you dare to do this? This is no big deal. Yeah, you&#039;re lucky if you&#039;re on her plane. Just own the night like the 4th of July! Standing on the frontline when the bombs start to fall. So just be sure before you give it all to me.&amp;lt;/p&amp;gt;&lt;br /&gt;
			&amp;lt;h5 id=&amp;quot;item-3-2&amp;quot;&amp;gt;Item 3-2&amp;lt;/h5&amp;gt;&lt;br /&gt;
			&amp;lt;p&amp;gt;Placeholder content for the scrollspy example. This one relates to item 3-2. You&#039;re original, cannot be replaced. All night they&#039;re playing, your song. California girls we&#039;re undeniable. Like a bird without a cage. There is no fear now, let go and just be free, I will love you unconditionally. I can see the writing on the wall. You could travel the world but nothing comes close to the golden coast.&amp;lt;/p&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-scrollspy-demo.png|border|Scrollspy Demo]]&lt;br /&gt;
&lt;br /&gt;
Also, some styling is needed in user.css:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;.scrollspy-example {&lt;br /&gt;
	height: 350px;&lt;br /&gt;
	overflow-y: scroll;&lt;br /&gt;
}&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Snag: the menu does not coordinate well with the content in this example!&lt;br /&gt;
&lt;br /&gt;
=== Example 10: Tab ===&lt;br /&gt;
Tabs are often used as navigation elements combined with dropdowns. Bootstrap example code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;ul class=&amp;quot;nav nav-tabs&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link active&amp;quot; href=&amp;quot;#&amp;quot; aria-current=&amp;quot;page&amp;quot;&amp;gt;Active&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item dropdown&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link dropdown-toggle&amp;quot; role=&amp;quot;button&amp;quot; href=&amp;quot;#&amp;quot; data-bs-toggle=&amp;quot;dropdown&amp;quot; aria-expanded=&amp;quot;false&amp;quot;&amp;gt;Dropdown&amp;lt;/a&amp;gt;&lt;br /&gt;
		&amp;lt;ul class=&amp;quot;dropdown-menu&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Another action&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Something else here&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;hr class=&amp;quot;dropdown-divider&amp;quot; /&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
			&amp;lt;li&amp;gt;&amp;lt;a class=&amp;quot;dropdown-item&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Separated link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
		&amp;lt;/ul&amp;gt;&lt;br /&gt;
	&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link&amp;quot; href=&amp;quot;#&amp;quot;&amp;gt;Link&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
	&amp;lt;li class=&amp;quot;nav-item&amp;quot;&amp;gt;&amp;lt;a class=&amp;quot;nav-link disabled&amp;quot; tabindex=&amp;quot;-1&amp;quot; href=&amp;quot;#&amp;quot; aria-disabled=&amp;quot;true&amp;quot;&amp;gt;Disabled&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-tab-demo.png|border|Tab Demo]]&lt;br /&gt;
&lt;br /&gt;
Remember to check both the Tab and Dropdown options for the dropdown part to work.&lt;br /&gt;
&lt;br /&gt;
=== Example 11: Toast ===&lt;br /&gt;
Toasts are lightweight notifications designed to mimic the push notifications that have been popularized by mobile and desktop operating systems. They’re built with flexbox, so they’re easy to align and position. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;toast fade show&amp;quot; role=&amp;quot;alert&amp;quot; aria-live=&amp;quot;assertive&amp;quot; aria-atomic=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;toast-header&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;img class=&amp;quot;rounded me-2&amp;quot; src=&amp;quot;...&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt; &lt;br /&gt;
		&amp;lt;strong class=&amp;quot;me-auto&amp;quot;&amp;gt;Bootstrap&amp;lt;/strong&amp;gt; &amp;lt;small&amp;gt;11 mins ago&amp;lt;/small&amp;gt; &lt;br /&gt;
		&amp;lt;button class=&amp;quot;btn-close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;toast&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;toast-body&amp;quot;&amp;gt;Hello, world! This is a toast message.&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-toast-demo.png|border|Toast Demo]]&lt;br /&gt;
&lt;br /&gt;
Note that the Bootstrap demo that uses a button to show the Toast message needs some extra JavaScript. It seems this component needs a coder to make good use of it!&lt;br /&gt;
&lt;br /&gt;
=== Example 12: Tooltip ===&lt;br /&gt;
A tooltip is a small piece of text that appears on hover over a button or link element to explain what it is or does. The tooltip can be positioned above or below or to the left or right of the element. If not specified the default position is top. The tooltip will switch to another position if there is insufficient room in the specified position. Example Bootstrap code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on left&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;left&amp;quot;&amp;gt; Tooltip on left &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot;&amp;gt; Tooltip &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on top&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;top&amp;quot;&amp;gt; Tooltip on top &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on right&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;right&amp;quot;&amp;gt; Tooltip on right &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;Tooltip on bottom&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-placement=&amp;quot;bottom&amp;quot;&amp;gt; Tooltip on bottom &amp;lt;/button&amp;gt; &lt;br /&gt;
&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; title=&amp;quot;&amp;amp;lt;em&amp;amp;gt;Tooltip&amp;amp;lt;/em&amp;amp;gt; &amp;amp;lt;u&amp;amp;gt;with&amp;amp;lt;/u&amp;amp;gt; &amp;amp;lt;b&amp;amp;gt;HTML&amp;amp;lt;/b&amp;amp;gt;&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;tooltip&amp;quot; data-bs-html=&amp;quot;true&amp;quot;&amp;gt; Tooltip with HTML &amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Tooltip triggered by class: &amp;lt;button class=&amp;quot;btn btn-warning&amp;quot; title=&amp;quot;Tooltip Message&amp;quot;&amp;gt;Alert!&amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Result:&lt;br /&gt;
&lt;br /&gt;
[[File:using-bootstrap-components-in-joomla-4-tooltip-demo.png|border|Tooltip Demo]]&lt;br /&gt;
&lt;br /&gt;
== Approach 2: Using a Content Plugin ==&lt;br /&gt;
The steps involved:&lt;br /&gt;
&lt;br /&gt;
* Download, install and enable this plugin: https://github.com/ceford/j4xdemos-plg-bscompos/raw/master/plg_j4xdemos_bscompos.zip&lt;br /&gt;
* In the article add the text that the plugin acts on, for example &#039;&#039;{bscompos modal carousel}&#039;&#039; will trigger loading of the JavaScript necessary to support a modal dialog and a carousel. The plugin removes the trigger text and enclosing (now) empty &amp;lt;nowiki&amp;gt;&amp;lt;p&amp;gt;&amp;lt;/p&amp;gt;&amp;lt;/nowiki&amp;gt; tags.&lt;br /&gt;
* Include the Bootstrap Component HTML code directly in the article or in a module included in the article. There is example HTML code below for a simple Modal and a Modal containing a Carousel. Note that this will not work if the HTML code is in a module in a template location.&lt;br /&gt;
* This will also work for a standard Custom module if the &#039;&#039;Prepare Content Option&#039;&#039; is set to &#039;&#039;Yes&#039;&#039;.&lt;br /&gt;
* Test it!&lt;br /&gt;
&lt;br /&gt;
== Approach 3: Using a Template Override ==&lt;br /&gt;
The steps involved:&lt;br /&gt;
* Create a mod_custom template override.&lt;br /&gt;
* Add a mod_custom module containing the component markup and trigger classes.&lt;br /&gt;
* Include the module in an article.&lt;br /&gt;
&lt;br /&gt;
=== The mod_custom Template Override ===&lt;br /&gt;
* In the Administrator interface go to {{rarr|System, Site Templates, Cassiopeia Details and Files}}.&lt;br /&gt;
* Select {{rarr|Create Overrides, mod_custom, default.php}}.&lt;br /&gt;
* On the line following &#039;&#039;defined(&#039;_JEXEC&#039;) or die;&#039;&#039; add this code:&lt;br /&gt;
&amp;lt;pre&amp;gt;$module_class = $params-&amp;gt;get(&#039;moduleclass_sfx&#039;);&lt;br /&gt;
if (!empty($module_class))&lt;br /&gt;
{&lt;br /&gt;
    $classes = explode(&#039; &#039;, $module_class);&lt;br /&gt;
    foreach ($classes as $class)&lt;br /&gt;
    {&lt;br /&gt;
	switch ($class)&lt;br /&gt;
        {&lt;br /&gt;
          case &#039;bs-alert&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.alert&#039;, &#039;.alert&#039;);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-button&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.button&#039;, &#039;.btn&#039;);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-carousel&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.carousel&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-collapse&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.collapse&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-dropdown&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.dropdown&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-modal&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.modal&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-offcanvas&#039;:&lt;br /&gt;
            // Not Found&lt;br /&gt;
            //\Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.offcanvas&#039;, &#039;.btn&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-popover&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.popover&#039;, &#039;.btn&#039;, []);&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.popover&#039;, &#039;a&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-scrollspy&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.scrollspy&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-tab&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tab&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-tooltip&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tooltip&#039;, &#039;.btn&#039;, []);&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.tooltip&#039;, &#039;a&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          case &#039;bs-toast&#039;:&lt;br /&gt;
            \Joomla\CMS\HTML\HTMLHelper::_(&#039;bootstrap.toast&#039;, &#039;.selector&#039;, []);&lt;br /&gt;
            break;&lt;br /&gt;
          default:&lt;br /&gt;
            // do nothing&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
This code searches for class names set in mod_custom and makes the HTMLHelper call to set up the JavaScript support. Note that the last item in each call is a selector that may or may not be used to trigger action. Many of the components are triggered by data attributes in the mark-up and they do not use the selectors here. For some, the selector is needed. For example, it makes sense to use the &#039;&#039;&#039;.btn&#039;&#039;&#039; class and the &#039;&#039;&#039;a&#039;&#039;&#039; tag to trigger Tooltips.&lt;br /&gt;
&lt;br /&gt;
=== A &#039;&#039;mod_custom&#039;&#039; Module for a Modal Component ===&lt;br /&gt;
* Go to {{rarr|Content, Site Modules, New}}.&lt;br /&gt;
* Select the &#039;&#039;&#039;Custom&#039;&#039;&#039; module.&lt;br /&gt;
* Fill out the form:&lt;br /&gt;
** Title: Demo Modal&lt;br /&gt;
** In the Position field type in &#039;&#039;&#039;demomodal&#039;&#039;&#039; for use in an article;&lt;br /&gt;
** Module Content: Toggle Editor for plain text entry.&lt;br /&gt;
** Paste in the following code from the Bootstrap documentation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Modal&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;!-- Button trigger modal --&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;modal&amp;quot; data-bs-target=&amp;quot;#exampleModal&amp;quot;&amp;gt; Launch demo modal &amp;lt;/button&amp;gt;&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;!-- Modal --&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;exampleModal&amp;quot; class=&amp;quot;modal fade&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-labelledby=&amp;quot;exampleModalLabel&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;modal-dialog&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;modal-content&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;h5 id=&amp;quot;exampleModalLabel&amp;quot; class=&amp;quot;modal-title&amp;quot;&amp;gt;Modal title&amp;lt;/h5&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn-close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;&lt;br /&gt;
				...&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-footer&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-secondary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot;&amp;gt;Close&amp;lt;/button&amp;gt; &lt;br /&gt;
				&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot;&amp;gt;Save changes&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Select the Advanced tab and in the Module Class field enter &#039;&#039;&#039;bs-modal&#039;&#039;&#039;&lt;br /&gt;
* Optional: set Ttitle to Hide to use the H2 in the pasted code.&lt;br /&gt;
* Save and Close (do not worry that the modal looks all wrong in the editor).&lt;br /&gt;
&lt;br /&gt;
=== Create an Article and Menu Item ===&lt;br /&gt;
* Create a new article, Demo Modal, and in plain text entry mode set the content to &amp;lt;pre&amp;gt;&amp;lt;div&amp;gt;{loadposition demomodal}&amp;lt;/div&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
* Create a Single Article menu item.&lt;br /&gt;
* Test it:&lt;br /&gt;
[[File:Demomodal.png|none|Bootstrap Modal in an Article]]&lt;br /&gt;
&lt;br /&gt;
=== A Modal Component Containing a Carousel ===&lt;br /&gt;
* Create a new Custom module with a new Title: Demo Modal Carousel&lt;br /&gt;
* Position: demomodalcarousel&lt;br /&gt;
* {{rarr|Advance tab, Module Class}}: bs-modal bs-carousel&lt;br /&gt;
* Module Custom content in plain text:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;h2&amp;gt;Modal with Carousel&amp;lt;/h2&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;mod-custom custom&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;!-- Button trigger modal --&amp;gt; &lt;br /&gt;
	&amp;lt;button class=&amp;quot;btn btn-primary&amp;quot; type=&amp;quot;button&amp;quot; data-bs-toggle=&amp;quot;modal&amp;quot; data-bs-target=&amp;quot;#exampleModal&amp;quot;&amp;gt; Launch demo modal &amp;lt;/button&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;exampleModal&amp;quot; class=&amp;quot;modal fade&amp;quot; style=&amp;quot;display: none;&amp;quot; tabindex=&amp;quot;-1&amp;quot; aria-hidden=&amp;quot;true&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;div class=&amp;quot;modal-dialog&amp;quot; role=&amp;quot;document&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;div class=&amp;quot;modal-content&amp;quot;&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-header&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;button class=&amp;quot;close&amp;quot; type=&amp;quot;button&amp;quot; data-bs-dismiss=&amp;quot;modal&amp;quot; aria-label=&amp;quot;Close&amp;quot;&amp;gt; &lt;br /&gt;
					&amp;lt;span aria-hidden=&amp;quot;true&amp;quot;&amp;gt;×&amp;lt;/span&amp;gt; &lt;br /&gt;
				&amp;lt;/button&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;div class=&amp;quot;modal-body&amp;quot;&amp;gt;&lt;br /&gt;
				&amp;lt;div id=&amp;quot;carouselExampleCaptions&amp;quot; class=&amp;quot;carousel slide&amp;quot; data-bs-ride=&amp;quot;carousel&amp;quot;&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;carousel-indicators&amp;quot;&amp;gt;&lt;br /&gt;
						&amp;lt;button class=&amp;quot;active&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;0&amp;quot; aria-current=&amp;quot;true&amp;quot; aria-label=&amp;quot;Slide 1&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
						&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;1&amp;quot; aria-label=&amp;quot;Slide 2&amp;quot;&amp;gt;&amp;lt;/button&amp;gt; &lt;br /&gt;
						&amp;lt;button type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide-to=&amp;quot;2&amp;quot; aria-label=&amp;quot;Slide 3&amp;quot;&amp;gt;&amp;lt;/button&amp;gt;&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;div class=&amp;quot;carousel-inner&amp;quot;&amp;gt;&lt;br /&gt;
						&amp;lt;div class=&amp;quot;carousel-item active&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa1-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
							&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
								&amp;lt;h5&amp;gt;First slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
								&amp;lt;p&amp;gt;Some representative placeholder content for the first slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
							&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa2-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
							&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
								&amp;lt;h5&amp;gt;Second slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
								&amp;lt;p&amp;gt;Some representative placeholder content for the second slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
							&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;div class=&amp;quot;carousel-item&amp;quot;&amp;gt;&lt;br /&gt;
							&amp;lt;img class=&amp;quot;d-block w-100&amp;quot; src=&amp;quot;images/sampledata/cassiopeia/nasa3-1200.jpg&amp;quot; alt=&amp;quot;...&amp;quot; /&amp;gt;&lt;br /&gt;
							&amp;lt;div class=&amp;quot;carousel-caption d-none d-md-block&amp;quot;&amp;gt;&lt;br /&gt;
								&amp;lt;h5&amp;gt;Third slide label&amp;lt;/h5&amp;gt;&lt;br /&gt;
								&amp;lt;p&amp;gt;Some representative placeholder content for the third slide.&amp;lt;/p&amp;gt;&lt;br /&gt;
							&amp;lt;/div&amp;gt;&lt;br /&gt;
						&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;/div&amp;gt;&lt;br /&gt;
					&amp;lt;button class=&amp;quot;carousel-control-prev&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;prev&amp;quot;&amp;gt; &lt;br /&gt;
						&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Previous&amp;lt;/span&amp;gt; &lt;br /&gt;
					&amp;lt;/button&amp;gt; &lt;br /&gt;
					&amp;lt;button class=&amp;quot;carousel-control-next&amp;quot; type=&amp;quot;button&amp;quot; data-bs-target=&amp;quot;#carouselExampleCaptions&amp;quot; data-bs-slide=&amp;quot;next&amp;quot;&amp;gt; &lt;br /&gt;
						&amp;lt;span class=&amp;quot;visually-hidden&amp;quot;&amp;gt;Next&amp;lt;/span&amp;gt; &lt;br /&gt;
					&amp;lt;/button&amp;gt;&lt;br /&gt;
				&amp;lt;/div&amp;gt;&lt;br /&gt;
			&amp;lt;/div&amp;gt;&lt;br /&gt;
		&amp;lt;/div&amp;gt;&lt;br /&gt;
	&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
* Create a new Article with &amp;lt;nowiki&amp;gt;&amp;lt;div&amp;gt;{loadposition demomodalcarousel}&amp;lt;/div&amp;gt;&amp;lt;/nowiki&amp;gt; in the content.&lt;br /&gt;
* Create a new single article menu item: Demo Modal Carousel&lt;br /&gt;
* Test it:&lt;br /&gt;
[[File:Demomodalcarousel.png|Demo Modal containing a Carousel]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Plugin Development{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla!_4.x{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J3.x:Sharing_layouts_across_views_or_extensions_with_JLayout&amp;diff=1014596</id>
		<title>J3.x:Sharing layouts across views or extensions with JLayout</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J3.x:Sharing_layouts_across_views_or_extensions_with_JLayout&amp;diff=1014596"/>
		<updated>2023-09-21T23:18:42Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Joomla version|version=3.x|comment=&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
series&amp;lt;/translate&amp;gt;}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
It is common that parts of pages are replicated across several views inside an extension, or even across several extensions. Examples might be:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
* An extension sharing some display layouts between Frontend and Backend views, or with one or more modules&lt;br /&gt;
* Backend extensions that have some common settings, and thus have to replicate common display layouts to allow users to change them&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Up until Joomla! 3.0, the loading (and template overriding) of layout files was restricted to a given view.&lt;br /&gt;
The JLayout interface and set of classes was added to Joomla! 3.0 to help solve this very problem. It encapsulates a layout and the data required to display it so that they can be reused across views and extensions.&lt;br /&gt;
At the time of writing, JLayout is used by the JHtmlSidebar class to display the submenu and filters found in most Backend extensions pages.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
JLayout consists in an interface and two classes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
* JLayout interface defines escape and render methods, much like the JView class of Joomla! platform&lt;br /&gt;
* JLayoutBase implements a basic layout class, where layout may be hard-coded in the class itself, for instance&lt;br /&gt;
* JLayoutFile, the most commonly used class, wraps and render a layout stored in a file, checking for overrides in template before doing so.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
Here is a basic usage example of JLayoutFile:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;// Create a layout object and ask it to render the sidebar&lt;br /&gt;
$layout      = new JLayoutFile(&#039;joomla.sidebars.submenu&#039;, $basePath = null);&lt;br /&gt;
$sidebarHtml = $layout-&amp;gt;render($data);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Executing this code creates a JLayoutFile object, wrapping a layout file, and passing in a $data structure that may be required for the display itself.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
The first parameter, &#039;joomla.sidebars.submenu&#039; is the file identifier. The last part (&#039;submenu&#039;)is the file name, everything before (&#039;joomla.sidebars&#039;) is the relative path. An optional $basePath parameter can be prepended to the relative path. If $basePath is missing, layout files will be searched inside the /layouts directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
Our example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;new JLayoutFile(&#039;joomla.sidebars.submenu&#039;, $basePath = null)&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
will result in the &#039;submenu.php&#039; layout file being loaded from the &#039;/layouts/joomla/sidebars&#039; directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Passing in a non-empty base path allows accessing and storing layout files anywhere on the site directory structure, for instance:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$layout = new JLayoutFile(&#039;my_layout&#039;, JPATH_ROOT .&#039;/components/com_something/layouts&#039;);&lt;br /&gt;
$html = $layout-&amp;gt;render($data);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
will load and render the &#039;my_layout.php&#039; layout file found in  JPATH_ROOT .&#039;/components/com_something/layouts&#039; directory.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Setting the client parameter as 3rd parameter allows loading layout files from the frontend directory also in the backed, for instance:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$layout = new JLayoutFile(&#039;my_layout&#039;, NULL, array(&#039;client&#039; =&amp;gt; 0));&lt;br /&gt;
$html = $layout-&amp;gt;render($data);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
will load and render the &#039;my_layout.php&#039; layout file found in JPATH_ROOT .&#039;/components/com_something/layouts&#039; directory but could still be overridden in the template.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Template Overrides&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
When executing the render() method, that is actually loading the layout file, JLayoutFile will check for the existence of an override in the currently selected template, inside a &#039;layouts&#039; directory. Looking back at our initial example, should you want to override the sidebar layout of all backend Joomla! extensions, you should place a &#039;submenu.php&#039; file under:&lt;br /&gt;
/administrator/templates/{currently_selected_template}/html/layouts/joomla/sidebars/&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
Note: JLayoutFile will check the currently selected template for overrides. As layouts can be shared across both the Frontend and Backend, if you need to override a layout file in both cases, you&#039;ll have to put an override file in both Backend and Frontend template.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Storing Layouts&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
Layouts files can basically be stored anywhere, as a full base path can be specified when using them (and still allow template override). However, for consistency and to avoid name clashes, we would recommend the following:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
* default to storing layout files in your extension own admin layouts folder. For instance: /administrator/components/com_example/layouts&lt;br /&gt;
* if your extension doesn&#039;t have an administrative folder (front-end only component, module, plugin), then use a layouts folder such as:&lt;br /&gt;
**/components/com_example/layouts&lt;br /&gt;
**/plugins/content/example/layouts&lt;br /&gt;
**/modules/mod_example/layouts&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
In addition, note that the folder itself &#039;&#039;&#039;must&#039;&#039;&#039; be named &#039;&#039;layouts&#039;&#039;.&lt;br /&gt;
Using the root &#039;&#039;/layouts&#039;&#039; folder is normally reserved for Joomla! itself, and possibly other &amp;quot;official&amp;quot; applications in the future such as the installer.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
Lastly, though not mandatory, I advise you to put all layout files under an additional &#039;&#039;com_example&#039;&#039; or &#039;&#039;mod_example&#039;&#039; subfolder inside the main &#039;&#039;layouts&#039;&#039; folder. This serves no purpose for your extension, however, should a template override layouts for several extensions, this would avoid possible name collisions.&lt;br /&gt;
For instance, if two extensions use the &amp;quot;filters.search_all&amp;quot; JLayout, then a template cannot provide a separate override for each. A single override will be used for both extension, which may not be desirable.&lt;br /&gt;
Using &amp;quot;com_example_1.filters.search_all&amp;quot; and &amp;quot;com_example_2.filters.search_all&amp;quot; allows templates to provide overrides for layouts, even if they have the same id.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Examples&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
Here is a simple example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
Create a file, /layouts/joomla/content/helloworld.php:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
defined(&#039;JPATH_BASE&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;helloworld&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
Then in any layout file, such as components/com_content/views/article/tmpl/default.php add:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$layout      = new JLayoutFile(&#039;joomla.content.helloworld&#039;);&lt;br /&gt;
echo $layout-&amp;gt;render();&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
View an article on the front end and you will see Hello World!.&lt;br /&gt;
Of course often you will want to pass some data via the render() method.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
A simple example of that might be:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
defined(&#039;JPATH_BASE&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;div id=&amp;quot;helloworld&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;h1&amp;gt;Hello &amp;lt;?php echo $displayData[&#039;name&#039;]; ?&amp;gt;!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
(Note that the variable passed in to the layout is called $displayData)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
With the corresponding PHP&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
$layout      = new JLayoutFile(&#039;joomla.content.helloworld&#039;);&lt;br /&gt;
$data = array(&#039;name&#039; =&amp;gt; &#039;Bob&#039;);&lt;br /&gt;
echo $layout-&amp;gt;render($data);&lt;br /&gt;
 ?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
Now when you view your article you should see &#039;&#039;Hello Bob!&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
For additional information, you can also read this article on the Joomla! Community Magazine™: [http://magazine.joomla.org/issues/issue-nov-2013/item/1590-jlayout-layouts-improvements-joomla-3-2 JLayout Improvements for Joomla! 3.2] by Roberto Segura.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
[[Category:Development]][[Category:Tutorials]][[Category:Template Development]]&amp;lt;/translate&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Cassiopeia_Template_Folders_and_Files&amp;diff=1014595</id>
		<title>J4.x:Cassiopeia Template Folders and Files</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Cassiopeia_Template_Folders_and_Files&amp;diff=1014595"/>
		<updated>2023-09-21T23:03:51Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;{{Joomla version|version=4.x}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
Newcomers to Joomla, sometimes new to PHP too, may know little of the architecture of a Joomla website and how it all comes together to present a website to the end user. That was me in 2010! However, having arrived here you will realise that Cassiopeia is a Site Template that controls the appearance of a site as seen by the general public. Administrators use a different template, Atum, with a completely different appearance. These templates are sometimes referred to as Frontend and Backend templates.&lt;br /&gt;
&lt;br /&gt;
A template is a Joomla extension that consists of a collection of files that take care of different aspects of the presentation. A website may have a number of site templates, one of which must be chosen as the default template used by all pages unless another specific template is selected for a specific page. And site templates may be present but unused. &lt;br /&gt;
&lt;br /&gt;
This tutorial explains the use of the various files in the default Cassiopeia site template.&lt;br /&gt;
&lt;br /&gt;
== Changes from Joomla 4.0 to Joomla 4.1 ==&lt;br /&gt;
&lt;br /&gt;
Joomla 4.1 has moved the default media files from the templates folder to the media/templates folder. Existing media folders are moved on upgrade.&lt;br /&gt;
&lt;br /&gt;
== File Structure ==&lt;br /&gt;
&lt;br /&gt;
The following illustration shows the folder structure of the Cassiopeia template, including the files in the template root.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Joomla 4.0 !! Joomla 4.1&lt;br /&gt;
|-&lt;br /&gt;
| [[File:j4x-cassiopeia_template_explained_file_structure.png|Joomla 4.0 File Structure]] || [[File:j4x-cassiopeia_template_explained_file_structure_41.png|Joomla 4.1 File Structure]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
A lot to explain! A brief starter explanation:&lt;br /&gt;
&lt;br /&gt;
* css - the folder containing all of the template CSS files&lt;br /&gt;
* html - a folder containing component and module overrides, which may be empty&lt;br /&gt;
* images - a folder for images used by the template and its styles&lt;br /&gt;
* js - a folder for JavaScript used by the template&lt;br /&gt;
* scss - a folder for the scss files compiled to make the CSS files&lt;br /&gt;
* component.php - a layout used to display just a component without surrounding modules&lt;br /&gt;
* error.php - a simple layout used to display errors when a normal page cannot be displayed&lt;br /&gt;
* index.php - the layout used for all site pages using this template&lt;br /&gt;
* joomla.asset.json - a file specifying where to find CSS and JavaScript resources&lt;br /&gt;
* offline.php - a layout used to show a site is off-line for maintenance&lt;br /&gt;
* template_preview.php and template_details.php - images used for administration&lt;br /&gt;
* templateDetails.xml - the extension specification used for installation&lt;br /&gt;
&lt;br /&gt;
Where to start?&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;index.php&#039;&#039; ==&lt;br /&gt;
&lt;br /&gt;
You are probably aware that a very simple HTML page looks like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;html&amp;gt;&lt;br /&gt;
&amp;lt;head&amp;gt;&lt;br /&gt;
&amp;lt;/head&amp;gt;&lt;br /&gt;
&amp;lt;body&amp;gt;&lt;br /&gt;
&amp;lt;h1&amp;gt;Hello World!&amp;lt;/h1&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Message of the day.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;/body&amp;gt;&lt;br /&gt;
&amp;lt;/html&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That is what is in index.php except that it is a little more complicated. Have a look through the file with a text editor and note the following:&lt;br /&gt;
&lt;br /&gt;
* The first executable statement is &#039;&#039;&#039;defined(&#039;_JEXEC&#039;) or die;&#039;&#039;&#039; - every Joomla PHP file starts like that to prevent calling directly via an absolute URL. _JEXEC is defined when a page is accessed via mydomain.com/[site-root/]index.php (usually with index.php left off as that is used by default).&lt;br /&gt;
* The actual HTML output starts with &#039;&#039;&#039;&amp;lt;!DOCTYPE html&amp;gt;&#039;&#039;&#039; on line 127 - everything before that is PHP code to set needed variables.&lt;br /&gt;
* The head and the body contain &#039;&#039;&#039;jdoc:include&#039;&#039;&#039; statements that cause insertion of specific types of content - more on that later.&lt;br /&gt;
* The body contains landmarks such as header, main, and footer - accessibility features.&lt;br /&gt;
* The overall layout is achieved with grids - included only where the grid positions actually include modules.&lt;br /&gt;
&lt;br /&gt;
=== Favicons ===&lt;br /&gt;
Favicons are the small icons that appear in the browser tab alongside your site name. Near the top of index.php are three instructions to load favicons into the page:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Browsers support SVG favicons&lt;br /&gt;
$this-&amp;gt;addHeadLink(HTMLHelper::_(&#039;image&#039;, &#039;joomla-favicon.svg&#039;, &#039;&#039;, [], true, 1), &#039;icon&#039;, &#039;rel&#039;, [&#039;type&#039; =&amp;gt; &#039;image/svg+xml&#039;]);&lt;br /&gt;
$this-&amp;gt;addHeadLink(HTMLHelper::_(&#039;image&#039;, &#039;favicon.ico&#039;, &#039;&#039;, [], true, 1), &#039;alternate icon&#039;, &#039;rel&#039;, [&#039;type&#039; =&amp;gt; &#039;image/vnd.microsoft.icon&#039;]);&lt;br /&gt;
$this-&amp;gt;addHeadLink(HTMLHelper::_(&#039;image&#039;, &#039;joomla-favicon-pinned.svg&#039;, &#039;&#039;, [], true, 1), &#039;mask-icon&#039;, &#039;rel&#039;, [&#039;color&#039; =&amp;gt; &#039;#000&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Joomla will look for the favicons first in media/templates/cassiopeia/images - they are not there so Joomla will look in media/system/images - they are there so Joomla will load the URLs for the images there. If you want to use your own favicons rather than Joomla favicons you upload them to media/templates/cassiopeia/images. You can do that using the Templates: Customise form. They will not be affected by any update to the Cassiopeia template.&lt;br /&gt;
&lt;br /&gt;
=== Template Variables ===&lt;br /&gt;
If you look through the template you will find lines containing $this-&amp;gt;params-&amp;gt;get(...) like this one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$paramsColorName = $this-&amp;gt;params-&amp;gt;get(&#039;colorName&#039;, &#039;colors_standard&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Those parameters are set in the Advance tab of the Template: Edit Style page. That is where you can change the brand, logo, colour, layout, etc. The variables are defined in the templateDetails.xml file.&lt;br /&gt;
&lt;br /&gt;
=== The Web Asset Manager ===&lt;br /&gt;
Notice the line near the top of index.php that creates an instance of the web asset manager and later lines that use it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa = $this-&amp;gt;getWebAssetManager();&lt;br /&gt;
...&lt;br /&gt;
$wa-&amp;gt;registerAndUseStyle($assetColorName, $templatePath . &#039;/css/global/&#039; . $paramsColorName . &#039;.css&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Joomla uses information in joomla.asset.json to load assets needed by the template. A portion of that file is shown here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;cassiopeia&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;This file contains details of the assets used by Cassiopeia, the default Joomla 4 site template.&amp;quot;,&lt;br /&gt;
  &amp;quot;license&amp;quot;: &amp;quot;GPL-2.0-or-later&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;template.cassiopeia.ltr&amp;quot;,&lt;br /&gt;
      &amp;quot;description&amp;quot;: &amp;quot;The css file to be used when the site is left to right (LTR).&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;template.min.css&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;fontawesome&amp;quot;&lt;br /&gt;
      ]&lt;br /&gt;
    },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It shows that the asset named template.cassiopeia.ltr is to be found in in css/template.min.css and that asset in turn requires fontawesome, defined at the end of joomla.assets.json. Note that if you switch to debug mode, Joomla will load the versions of CSS and JavaScript without the .min part.&lt;br /&gt;
&lt;br /&gt;
=== The &#039;&#039;jdoc&#039;&#039; Statements ===&lt;br /&gt;
At some point during page creation the template index.php file is parsed (analysed) by the Joomla code and the jdoc statements picked out in reverse order. Each jdoc statement leads to code to generate a block of HTML to replace that statement. Amongst other things, that puts module content into the page.&lt;br /&gt;
&lt;br /&gt;
== The CSS Files ==&lt;br /&gt;
The &#039;&#039;css&#039;&#039; folder contains the CSS files used by the Cassiopeia template. It is worth noting the file sizes of the different variants of a single CSS style sheet. For example &#039;&#039;template.css&#039;&#039; has these varieties:&lt;br /&gt;
&lt;br /&gt;
* template.css 258,272 bytes&lt;br /&gt;
* template.min.css 205,427 bytes&lt;br /&gt;
* template.min.css.gz 32,526 butes&lt;br /&gt;
&lt;br /&gt;
The first, template.css is a human-readable variant that is used when system debugging is enabled. The second, template.min.css is used on production sites where debugging is disabled. It has all white space removed and some optimisations made. The third, template.min.css.gz is a Gzip compressed variant of the min version used if the site &#039;&#039;.htaccess&#039;&#039; file is set up to offer Gzip variants of static resources. There is an article describing how do this in the [https://magazine.joomla.org/all-issues/december-2021/joomla-performance-tuning-ii-basic-settings Community Magazine].&lt;br /&gt;
&lt;br /&gt;
Clearly the &#039;&#039;gz&#039;&#039; version is the most network bandwidth friendly.&lt;br /&gt;
&lt;br /&gt;
=== &#039;&#039;user.css&#039;&#039; ===&lt;br /&gt;
Absent from the initial list of CSS files is user.css. This is a file that you create yourself to contain additions and overrides to the existing styles. For example, module parameters typically include a Module Class text entry box in the Advanced tab. Any module class you add there should have an entry in user.css. If you wish to override an existing style you can make an entry like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
h1, .h1 {&lt;br /&gt;
  color: purple;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== The HTML Files ==&lt;br /&gt;
This is the place to keep module, component, plugin and layout template overrides. For example, when Joomla renders a module it first looks for a template here and then in the modules own tmpl folder. This allows you to override the appearance of a core Joomla extension or a third party extension without changing the original code. Any changes made there would be overwritten by an update.&lt;br /&gt;
&lt;br /&gt;
The default Cassiopeia template comes with overrides for layouts, mod_custom, mod_menu and tinymce.&lt;br /&gt;
&lt;br /&gt;
== The JavaScript Files ==&lt;br /&gt;
There is only one basic JavaScript file used by the template and like CSS it comes in three varieties: template.js, template.min.js and template.min.js.gz. There is one other variety of interest: template.es5.js, which is coded for EcmaScript 5 (the 2011 version). All of the other JavaScript files are coded for later EcmaScript versions. &lt;br /&gt;
&lt;br /&gt;
EcmaScript is currently up to Version 12 but it takes a while for browsers to catch up and adopt a new standard. JavaScript is a synonym for EcmaScript. See [https://en.wikipedia.org/wiki/ECMAScript Wikipedia] for a summary.&lt;br /&gt;
&lt;br /&gt;
== The SCSS Files ==&lt;br /&gt;
The SCSS files contain the sources used to create the CSS files. They need to be compiled with a third party compiler. More...&lt;br /&gt;
&lt;br /&gt;
== Template Positions ==&lt;br /&gt;
The positions in which modules can be placed are named in the templateDetails.xml file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;positions&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;topbar&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;below-top&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;menu&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;search&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;banner&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;top-a&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;top-b&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;main-top&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;main-bottom&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;breadcrumbs&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;sidebar-left&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;sidebar-right&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;bottom-a&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;bottom-b&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;footer&amp;lt;/position&amp;gt;&lt;br /&gt;
		&amp;lt;position&amp;gt;debug&amp;lt;/position&amp;gt;&lt;br /&gt;
	&amp;lt;/positions&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The following illustration shows in schematic form where those positions occur on the page:&lt;br /&gt;
&lt;br /&gt;
[[File:j4x-cassiopeia_template_explained_positions.png|Template Positions]]&lt;br /&gt;
&lt;br /&gt;
Notice the &#039;&#039;&#039;component&#039;&#039;&#039; position marked with a green background. That is where the output from a component view is placed and is often the largest portion of the page. Immediately above that is the message position where Joomla system messages appear. For example, &#039;&#039;Your changes have been saved&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
The illustration shows that some of the positions are within landmarks such as &#039;&#039;&#039;header&#039;&#039;&#039; and &#039;&#039;&#039;footer&#039;&#039;&#039; but others are not. Something to look into! &lt;br /&gt;
&lt;br /&gt;
With the sample data installed, the following illustration shows the Home page landmarks in the browser tools &#039;&#039;&#039;Inspector&#039;&#039;&#039; view.&lt;br /&gt;
&lt;br /&gt;
[[File:j4x-cassiopeia_template_explained_inspector_landmarks.png|Template Landmarks]]&lt;br /&gt;
&lt;br /&gt;
The header contains a &#039;&#039;&#039;brand&#039;&#039;&#039; location, not a position to which a module can be assigned. It can be left out. Beneath that is a &#039;&#039;&#039;menu&#039;&#039;&#039; and/or &#039;&#039;&#039;search&#039;&#039;&#039; position. It is used for the site menu and search box.&lt;br /&gt;
&lt;br /&gt;
The contents of the remaining divs are self-evident from their class names. There is no container-sidebar-left because the sample data does not assign any module to that position.&lt;br /&gt;
&lt;br /&gt;
== Further Information == &lt;br /&gt;
* [[J4.x:Cassiopeia Template Customisation|Cassiopeia Template Customisation]] - using the Edit Style form and user.css&lt;br /&gt;
* [[J4.x:Cassiopeia Template Simplified - A Case Study|Cassiopeia Template Simplified - A Case Study]] - a simple template based on Cassiopeia&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Joomla! 4.x]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J3.x:Layout_Overrides_in_Joomla&amp;diff=1014594</id>
		<title>J3.x:Layout Overrides in Joomla</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J3.x:Layout_Overrides_in_Joomla&amp;diff=1014594"/>
		<updated>2023-09-21T13:32:09Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{version/tutor|3.x}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Introduction to Alternative Layout Feature === &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
Joomla has a comprehensive set of features that give the site administrator more control over the display of all HTML output from their template. There are five types of alternative layouts:&amp;lt;/translate&amp;gt;&lt;br /&gt;
# &amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Module&amp;lt;/translate&amp;gt;&lt;br /&gt;
# &amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
Component&amp;lt;/translate&amp;gt;&lt;br /&gt;
# &amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
Category&amp;lt;/translate&amp;gt;&lt;br /&gt;
# &amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
Menu Item&amp;lt;/translate&amp;gt;&lt;br /&gt;
# &amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
JLayouts&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Alternative layouts work in a similar fashion to the template override feature but allow you more options and control. Each type is discussed below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Module Alternative Layouts === &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
Creating an alternative layout for a module is similar to creating a template override for a module. In both cases, you create a folder called &#039;&#039;templates/&amp;lt;your template&amp;gt;/html/&amp;lt;module name&amp;gt;&#039;&#039;. For example, the folder for a &#039;&#039;mod_login&#039;&#039; template override or alternative layout for the beez3 template would be &#039;&#039;templates/beez3/html/mod_login/&#039;&#039;.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
There are two important differences between a template override and an alternative layout. The first is the file name. For the template override, you would call the file &amp;lt;tt&amp;gt;default.php&amp;lt;/tt&amp;gt; to match the core file name. For an alternative layout, you use a different name. The only rule is that &#039;&#039;&#039;the file name should not have any underscores in it&#039;&#039;&#039;. This allows you to have complex layouts that include multiple files. The initial file to be called is named without underscores and any other files that are called from this initial file will have underscores in the name. For example, you could have the initial file called &amp;lt;tt&amp;gt;mynewlogin.php&amp;lt;/tt&amp;gt; which calls &amp;lt;tt&amp;gt;mynewlogin_1.php&amp;lt;/tt&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
The second important difference is that, unlike template override files which are called automatically whenever the module is displayed using the template with the override, an alternative layout file is only called if you select it as a parameter in the Module Manager. In version 2.5 and later, there is a new parameter under Advanced Options called Alternative Layout, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Screenshot_override_tutorial_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
This parameter will list any files (without underscores) that you have placed in the template folder for this module. You can also translate the file name using the template&#039;s system language file (Note this keeps things simple in these examples but best practice is using Joomla&#039;s [[J3.x:Language_Overrides_in_Joomla|Language Override]] tool to create this string rather than modifying the template language file). For example, if you add the line&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;TPL_BEEZ3_MOD_LOGIN_LAYOUT_NOLOGIN=&amp;quot;Alt Login Layout&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
to the file &amp;lt;tt&amp;gt;en-GB.tpl_beez3.sys.ini&amp;lt;/tt&amp;gt;, it will translate the file name &amp;lt;tt&amp;gt;nologin.php&amp;lt;/tt&amp;gt; to &amp;quot;Alt Login Layout&amp;quot;.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
It is important to understand that if specified in the Module Manager screen, an alternative layout file for a module will be used for that module regardless of what template is used to display the page where the module is shown. It is therefore the administrator&#039;s responsibility to make sure that the layout file will work as desired in any templates where this module may be shown.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Plugin Alternative Layouts (Overriding a Plugin) === &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
Yes, it&#039;s possible to override plugin outputs. It&#039;s very useful, especially for content plugins. However you can only do it if the plugin is ready to allow overrides.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{tip|&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
Joomla provides a mechanism to override a plugin but this feature is not supported by all the plugins&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
Right now the only plugin in Joomla 3.x core that allow overrides is the Pagenavigation Content plugin that shows previous/next article links in article view of content component. There may be other plugins from third party developers allowing it and more core plugins will be overridable in the future.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
You will know when a plugin is overridable because has a &#039;&#039;/tmpl/&#039;&#039; folder in it. See: https://github.com/joomla/joomla-cms/tree/staging/plugins/content/pagenavigation (note for developers: the plugin uses &amp;lt;tt&amp;gt;JPluginHelper::getLayoutPath()&amp;lt;/tt&amp;gt; )&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Plugin Override Example ==== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
To override the output of &#039;&#039;&#039;Pagenavigation content plugin&#039;&#039;&#039; in &amp;quot;beez3&amp;quot; template, create a folder named &amp;lt;tt&amp;gt;templates/beez3/html/plg_content_pagenavigation/&amp;lt;/tt&amp;gt; and copy the original layout file (&amp;lt;tt&amp;gt;plugins/content/pagenavigation/tmpl/default.php&amp;lt;/tt&amp;gt;) to this new folder.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
Now you can change this layout file to override plugin output.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
Is important to note that to build the override layout you need to create it in this path:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 templates/TEMPLATE-NAME/html/plg_PLUGIN-GROUP_PLUGIN-NAME/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
example:&amp;lt;/translate&amp;gt; &lt;br /&gt;
&amp;lt;tt&amp;gt;templates/beez3/html/plg_content_pagenavigation/&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
Where PLUGIN-GROUP is the group to which the plugin belongs. (It is the name of the first folder where the plugin is located. See: https://github.com/joomla/joomla-cms/tree/staging/plugins. Read more about Event groups at [[S:MyLanguage/Plugin/Events|Plugin/Events]])&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Component Alternative Layouts === &amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
Component alternative layouts work similarly to module layouts discussed above. Again, a file is placed in the same folder where you place a template override file. For example, to create an alternative layout for an article for the template &#039;&#039;beez3&#039;&#039;, you would put a file in the folder &amp;lt;tt&amp;gt;templates/beez3/html/com_content/article/&amp;lt;/tt&amp;gt;. As with module layouts, the file must not be named the same as the core file and must not include underscores in the name. Additionally, there should not be an XML file of the same name in this folder. (We&#039;ll discuss XML files below under Menu Item Alternative Layouts.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
You can set a global value for component layouts in the Options window of the component. For example, in the Article Manager Options window, there is a parameter for Alternative Layout as shown below:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:article_manager_alternative_layout_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|800px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
This will create a global value that individual components (articles, contacts, news feeds and Web links) can inherit from.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
As with module layouts, the component layouts are shown as parameter options in the individual component edit screen. For example, for an article, the parameter shows in the Article Options group as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:article_alternative_layout_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
As with other parameters, the Use Global setting will use the setting from the Options parameter. The From Component&#039;s Default setting will use the component&#039;s default layout. Alternative layouts that you have created for different templates are shown under each template heading.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
File names may be translated. The line below:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;TPL_BEEZ3_COM_CONTENT_ARTICLE_LAYOUT_MYLAYOUT=&amp;quot;Title Only No XML&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
will translate a file called &#039;&#039;mylayout.php&#039;&#039; as &#039;&#039;Title Only No XML&#039;&#039;.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
You can have more than one file for a layout. The initial file must be named without underscores and any additional files must have underscores.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
Component alternative layouts may be used with articles, contacts, or news feeds. Web links don&#039;t have a single-component layout so no alternative layout is available for web links.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
Component alternative layouts are only used when two conditions are met: (1) they are specified in the component parameters; and (2) there is no menu item for this specific component. For example, if you have one or more menu items of type &amp;quot;Single Article&amp;quot; set up for a given article, then the alternative layout for that article will not be used. Instead, the layout specified in the menu item will be used. This is consistent with the general way that component parameters work, where the most specific (in this case a single-article menu item) overrides the less specific (in this case, the article parameters).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Category Alternative Layouts === &amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Category alternative layouts work identically to component layouts. The rules for specifying layout files are the same. The only difference is that the folder is the category folder, not the component folder. For example, a contact category alternative layout for beez3 would go in the folder &amp;lt;tt&amp;gt;templates/beez3/html/com_contact/category&amp;lt;/tt&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
You can set category layouts globally, in the Options screen of each component. Below is an example from the Contact Manager Options screen:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:contact_component_options_category_alternative_layout_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
Category alternative layouts show up when you add or edit a category in the Category Manager under the Basic Options as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:category_options_alternative_layout_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
Category alternative layouts may be used for articles, contacts, news feeds and Web links.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
As with component layouts, category layouts only will show if (1) they are specified for the category in the global or category parameters and (2) there is no menu item specifically for this category (for example, List Contacts in a Category, List News feeds in a Category, List Web links in a Category, Category List, Category Blog).&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
If there is a menu item set up for this specific category, that layout will be used instead of the alternative category layout.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Drill Down to Blog or List === &amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
For articles, we have two core layouts available: Blog and List. Both of these options show under the &amp;quot;From Component&amp;quot; heading in the layout parameters for article category. So, like other layout options, you can now select Blog or List for categories either globally (in the Article Manager Options, shown below), or when editing a single article category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:article_manager_category_blog_alternative_layout_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
This means that, like other layout options, you can control whether article category links drill down to blog or list layouts. It is important to understand that, like other layout parameters, this option will only take effect when there is no single-category menu item for the category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Alternative Menu Items === &amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
Alternative Menu Items have one important difference with the others. To create a menu item alternative layout, you must include an XML file whose name matches the initial layout file. For example, to create an alternative menu item called &amp;quot;myarticle&amp;quot; for an article in the beez3 template, you would create two files in the &amp;lt;tt&amp;gt;templates/beez3/html/com_content/article&amp;lt;/tt&amp;gt; folder called &amp;lt;tt&amp;gt;myarticle.php&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;myarticle.xml&amp;lt;/tt&amp;gt;. If you wanted to include more layout files, you would add these files with underscores in the file names.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
The XML file uses the same format as the core Menu Item XML files. This allows you not only to create a customized layout for this menu item but also allows you to create customized parameters. For example, you could hide some parameters or add new parameters.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
Alternative Menu Items show up when you select a menu item type in the Menu Manager as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:menu_manager_alternative_menu_items_j3_&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|800px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
Alternative Menu Items are used and work the same way as standard menu items. Since they are already based on customized layouts, template overrides do not apply to alternative menu items.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
As indicated above, menu item layouts take priority over component or category alternative layouts.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt;&lt;br /&gt;
Translation of alternative menu items is done with the following tags in the XML files. The format is &amp;lt;tt&amp;gt;&amp;quot;TPL_&amp;quot;&amp;lt;template name&amp;gt;_&amp;lt;component&amp;gt;_&amp;lt;view&amp;gt;_&amp;lt;menu item name&amp;gt;_&amp;lt;tag type&amp;gt;&amp;lt;/tt&amp;gt;. For example, these lines below will translate the title, option, and description for an alternative menu item called &amp;quot;catmenuitem&amp;quot;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
TPL_BEEZ3_COM_CONTENT_CATEGORY_VIEW_CATMENUITEM_TITLE=&amp;quot;Beez3 Custom Category Layout&amp;quot;&lt;br /&gt;
TPL_BEEZ3_COM_CONTENT_CATEGORY_VIEW_CATMENUITEM_OPTION=&amp;quot;Beez3 Custom&amp;quot;&lt;br /&gt;
TPL_BEEZ3_COM_CONTENT_CATEGORY_VIEW_CATMENUITEM_DESC=&amp;quot;Description for beez3 custom category layout.&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
These strings have to be added to &amp;lt;tt&amp;gt;language/en-GB/en-GB.tpl_beez3.sys.ini&amp;lt;/tt&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
The catmenuitem.xml would start with:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;metadata&amp;gt;&lt;br /&gt;
   &amp;lt;layout title=&amp;quot;TPL_BEEZ3_COM_CONTENT_CATEGORY_VIEW_CATMENUITEM_TITLE&amp;quot; option=&amp;quot;TPL_BEEZ3_COM_CONTENT_CATEGORY_VIEW_CATMENUITEM_OPTION&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;help&lt;br /&gt;
         key = &amp;quot;JHELP_MENUS_MENU_ITEM_ARTICLE_SINGLE_ARTICLE&amp;quot;&lt;br /&gt;
      /&amp;gt;&lt;br /&gt;
      &amp;lt;message&amp;gt;&lt;br /&gt;
         &amp;lt;![CDATA[TPL_BEEZ3_COM_CONTENT_CATEGORY_VIEW_CATMENUITEM_DESC]]&amp;gt;&lt;br /&gt;
      &amp;lt;/message&amp;gt;&lt;br /&gt;
   &amp;lt;/layout&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Controlling the Template for Alternative Menu Items === &amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
As discussed above, the presence of an XML file makes an alternative layout a menu item. The format of the XML file is the same as the format for core menu item XML files. With this XML file, you can add the parameters you wish to include for this menu item. They can be the same as one of the core menu items, or you can omit core parameters or add new ones. Note that if you add new parameters, these can be used in the layout file but will not be used in the core model or view files.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt;&lt;br /&gt;
It is also possible to override parameter settings for core parameters. One example of this is to control which templates an alternative menu item layout can be displayed with. In some cases, you may want to allow a custom menu item to be displayed with any template for the site. In other cases, you may wish to limit that menu item&#039;s layout to one specific template. In this situation, you would just add the following parameter to the menu item&#039;s XML file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;XML&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;fields&amp;gt;&lt;br /&gt;
  &amp;lt;field&lt;br /&gt;
    name=&amp;quot;template_style_id&amp;quot;&lt;br /&gt;
    type=&amp;quot;templatestyle&amp;quot;&lt;br /&gt;
    label=&amp;quot;COM_MENUS_ITEM_FIELD_TEMPLATE_LABEL&amp;quot;&lt;br /&gt;
    description=&amp;quot;COM_MENUS_ITEM_FIELD_TEMPLATE_DESC&amp;quot;&lt;br /&gt;
    filter=&amp;quot;int&amp;quot;&lt;br /&gt;
    template=&amp;quot;beez3&amp;quot;&lt;br /&gt;
    class=&amp;quot;inputbox&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;/field&amp;gt;&lt;br /&gt;
 &amp;lt;/fields&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
This will override the core &amp;lt;tt&amp;gt;template_style_id&amp;lt;/tt&amp;gt; parameter. Setting the template equal to &amp;quot;beez3&amp;quot; in this case will limit the user to only selecting template styles for the &amp;quot;beez3&amp;quot; template.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JLayout Micro-Layout Overrides === &amp;lt;!--T:73--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
JLayouts is a powerful feature of Joomla! JLayouts can be loosely defined as micro-layouts. They are the micro-layouts for individual elements of Joomla! pages. For example, the read more button, the intro image, the full image, are all examples of elements that are controlled via their own JLayout.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:74--&amp;gt;&lt;br /&gt;
If you dig deeper into the Category Blog Layout view, you will find the code to call the article title, an intro image, the intro text, as well as various other relevant parts of the page. This is what it looks like when you call an element using JLayout.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;?php echo JLayoutHelper::render(&#039;joomla.content.blog_style_default_item_title&#039;, $this-&amp;gt;item); ?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
This particular bit of code calls the Article Title within the Joomla! Category Blog.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:77--&amp;gt;&lt;br /&gt;
To help you understand the location of the file for this particular element, it would help to understand that there is a naming convention in play. Looking at &amp;lt;tt&amp;gt;joomla.content.blog_style_default_item_title&amp;lt;/tt&amp;gt; the dots can be replaced with /&#039;s to understand the directory structure. All JLayouts are initially found in JOOMLAROOT/layouts. Using the naming convention we can see that this file will be located in &amp;lt;tt&amp;gt;JOOMLAROOT/layouts/joomla/content/blog_style_default_item_title.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
Let&#039;s go through an example. For this example, we will move the intro image to above the title. You could also add some additional structure around it.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
You should not edit JLayout files directly as changes would be overwritten during any core upgrade. The correct way to update the JLayout is by finding the element you want to override (such as intro_image), and copying the file to your template. You should then copy the folder structure of the element that you want to override that exists within the layouts folder within the Joomla! parent directory e.g. &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/&amp;lt;/tt&amp;gt;. You only want to copy the file(s) that you require to avoid site bloat, and to minimise the probability of causing an issue.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
An example for the intro_image would be originally found in:&lt;br /&gt;
&amp;lt;tt&amp;gt;JOOMLAROOT/layouts/joomla/content/intro_image.php&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
The copied file would be: &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/layouts/joomla/content/intro_image.php&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:80--&amp;gt;&lt;br /&gt;
As a simple example let&#039;s add a responsive image class to the intro image. First of all, we open our copied JLayout file, which we just placed in &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/layouts/joomla/content/intro_image.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:81--&amp;gt;&lt;br /&gt;
Look for the following line &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:82--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;pull-&amp;lt;?php echo htmlspecialchars($imgfloat); ?&amp;gt; item-image&amp;quot;&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:83--&amp;gt;&lt;br /&gt;
Let&#039;s add our responsive image class &amp;lt;tt&amp;gt;img-responsive&amp;lt;/tt&amp;gt; to the existing classes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:84--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;pull-&amp;lt;?php echo htmlspecialchars($imgfloat); ?&amp;gt; item-image img-responsive&amp;quot;&amp;gt; &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:85--&amp;gt;&lt;br /&gt;
Okay, we have added our class. Let&#039;s save and close the file. Ensure it is uploaded to our website. Now if we refresh the page we will see the class &amp;lt;tt&amp;gt;img-responsive&amp;lt;/tt&amp;gt; on our intro images. You have just used a JLayout, think of all the other great things you could do with JLayouts?&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
==== Creating a new JLayout that only appears on some pages ====&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
You can also create new JLayout files. They do not need to be based on existing elements. Simply add them into the &amp;lt;tt&amp;gt;YOUR_TEMPLATE/html/layouts/&amp;lt;/tt&amp;gt; directory as above and Joomla! will be able to find them. Then you need to reference the new JLayout in your code. For simplicity, in this example, I have duplicated an existing element, and made my own version.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:86--&amp;gt;&lt;br /&gt;
I will start by doing a standard &#039;&#039;&#039;HTML template override for the Blog layout&#039;&#039;&#039; (not a JLayout override). You can find out how to do this further up this page. Doing a template override will add a few files to my &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html&amp;lt;/tt&amp;gt; folder. I will create a new JLayout which I &#039;&#039;&#039;only&#039;&#039;&#039; want to use on my blog view. If I simply edited the JLayout for intro_image it would effect all of my intro_images, but I only want to alter my Category Blog View intro_images.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:87--&amp;gt;&lt;br /&gt;
The file I want to use is &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/com_content/category/blog_item.php&amp;lt;/tt&amp;gt;. Within that file I find the line &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; inline&amp;gt;&amp;lt;?php echo JLayoutHelper::render(&#039;joomla.content.intro_image&#039;, $this-&amp;gt;item); ?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt; which is calling a JLayout element. That particular code is for the intro_image element.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:88--&amp;gt;&lt;br /&gt;
For the sake of simplicity I copied the file &amp;lt;tt&amp;gt;JOOMLAROOT/layouts/joomla/content/intro_image.php&amp;lt;/tt&amp;gt;. I put it in &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/layouts/joomla/content/&amp;lt;/tt&amp;gt; and I renamed it &amp;lt;tt&amp;gt;intro_image_blog.php&amp;lt;/tt&amp;gt;.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
Now I open my template override file &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/com_content/category/blog_item.php&amp;lt;/tt&amp;gt;. I find the reference to &amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot; inline&amp;gt;&amp;lt;?php echo JLayoutHelper::render(&#039;joomla.content.intro_image&#039;, $this-&amp;gt;item); ?&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;, I remove it, I reposition the JLayout above the title, and I use my own JLayout that I just created &amp;lt;tt&amp;gt;templates/YOUR_TEMPLATE/html/layouts/joomla/content/intro_image_blog.php&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:89--&amp;gt;&lt;br /&gt;
Now my new JLayout is being used, and it has been positioned above the title. I can now make further amendments such as adding a responsive image class if need be and changes will only be reflected in the Category Blog View.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Further Reading ==&lt;br /&gt;
You can find further reading here [[J3.x:Sharing_layouts_across_views_or_extensions_with_JLayout|Sharing layouts across views or extensions with JLayout]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:90--&amp;gt;&lt;br /&gt;
[[Category:Joomla! 3.x]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Help4.x:Scheduled_Tasks&amp;diff=1014590</id>
		<title>Help4.x:Scheduled Tasks</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Help4.x:Scheduled_Tasks&amp;diff=1014590"/>
		<updated>2023-09-16T14:12:42Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected Intervale to Interval.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt; &lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Description== &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Scheduled Tasks are used to run routine site maintenance tasks as an alternative to server cron jobs. The tasks are defined in plugins in the task group. A number of task plugins are supplied and can be used as examples for creating other specialised tasks.&lt;br /&gt;
&lt;br /&gt;
==How To Access== &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Starting from the Administrator menu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:60--&amp;gt;&lt;br /&gt;
* Select {{&amp;lt;tvar name=1&amp;gt;rarr&amp;lt;/tvar&amp;gt;|System,Manage panel,Scheduled Tasks}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
The initial Scheduled Tasks list is empty so select the &#039;&#039;&#039;New&#039;&#039;&#039; button to get started. The screenshot shows the example tasks.&lt;br /&gt;
&lt;br /&gt;
==Screenshot== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[File:Help-4x-components-scheduler-manager-tasks-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Column Headers== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
In the table containing Tasks the different columns are listed below. Click on the column heading to sort the list by that column&#039;s value.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{:Chunk4x:Help screen column header Checkbox/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{:Chunk4x:Help screen column header Ordering/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{:Chunk4x:Help screen column header Status/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{:Chunk4x:Help screen column header Task Title/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{:Chunk4x:Help screen column header Task Type/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{:Chunk4x:Help screen column header Last Run Date/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{:Chunk4x:Help screen column header Test Task/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt; &#039;&#039;&#039;Task Priority&#039;&#039;&#039;. Shows the priority Low, Normal, or High. Higher priority tasks can potentially block lower priority tasks.&amp;lt;/translate&amp;gt; &lt;br /&gt;
{{:Chunk4x:Help screen column header Id/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==List Filters== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{Chunk4x:Help_screen_filters_Search_Bar_Filter/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&amp;lt;!--T:62--&amp;gt; tasks&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Filter Options=== &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_filter_bar_top_descriptor/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt; &#039;&#039;&#039;Select Status&#039;&#039;&#039;. Select from Trashed / Disabled / Enabled / All.&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; &#039;&#039;&#039;Task Type&#039;&#039;&#039;. Select from the list of available tasks.&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt; &#039;&#039;&#039;Hide Orphaned&#039;&#039;&#039;. Select from Hide Orphaned / Show Orphaned / Only Orphaned.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Pagination=== &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{:Chunk4x:Help_screen_filters_Pagination/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt; tasks&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Toolbar== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_top_descriptor/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_New/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
task&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Actions/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
task&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Enable/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
task&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Disable/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
task&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Unlock/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
task&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Trash/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
task&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;/ul&amp;gt;&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Options/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{safesubst:Chunk4x:Help_screen_toolbar_icon_Help/&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Scheduled Tasks Options == &amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
Click the &#039;&#039;&#039;Options&#039;&#039;&#039; button from the Toolbar to configure scheduled tasks.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt; &#039;&#039;&#039;Configure Tasks&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt; &#039;&#039;&#039;Task Timeout&#039;&#039;&#039;. The default is &amp;lt;tvar name=1&amp;gt;300&amp;lt;/tvar&amp;gt; seconds.&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt; &#039;&#039;&#039;Lazy Scheduler&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; &#039;&#039;&#039;Enabled&#039;&#039;&#039;. Tasks are triggered by Site visitors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt; &#039;&#039;&#039;Disabled&#039;&#039;&#039;. Tasks are to be triggered by an external cron job.&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; &#039;&#039;&#039;Request Interval&#039;&#039;&#039;. The default is &amp;lt;tvar name=1&amp;gt;300&amp;lt;/tvar&amp;gt; seconds.&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt; &#039;&#039;&#039;Web Cron&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt; &#039;&#039;&#039;Web Cron&#039;&#039;&#039;. Disabled is the default. Enabled requires a hash to trigger the task. Before the first save there is a message that a key is required. After save there is a field containing a Webcron link URL to copy.&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; &#039;&#039;&#039;Permissions&#039;&#039;&#039; The standard form to set access permissions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Available Tasks== &amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
The following screenshot shows a list of available tasks. Some are demonstrations, some are useful.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Help-4x-Scheduled-Tasks-Available-screen-&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; en&amp;lt;/translate&amp;gt;.png|800px|&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; Scheduled Tasks Available&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
Each task has its own task related parameters that should be self-explanatory. For example, the &#039;&#039;&#039;Site Offline&#039;&#039;&#039; task only makes sense if the {{&amp;lt;tvar name=1&amp;gt;rarr&amp;lt;/tvar&amp;gt;|Edit Task,Basic Fields,Execution Rule}} is set to &#039;&#039;&#039;Manual Execution&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
The other parameters are optional!&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Cathelp|4.0,4.1,4.2,4.3|Components Help Screens|Scheduled Tasks Manager Help Screens}}&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Inserting,_Updating_and_Removing_data_using_JDatabase&amp;diff=1014589</id>
		<title>Inserting, Updating and Removing data using JDatabase</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Inserting,_Updating_and_Removing_data_using_JDatabase&amp;diff=1014589"/>
		<updated>2023-09-13T16:24:15Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Corrected some URLs.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Joomla version|version=3.x}}{{Joomla version|version=2.5|status=eos}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
{{tip|&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
Note many examples online use &amp;lt;code&amp;gt;$db-&amp;gt;query()&amp;lt;/code&amp;gt; instead of &amp;lt;code&amp;gt;$db-&amp;gt;execute()&amp;lt;/code&amp;gt;. This was the old method in Joomla 1.5 and 2.5 and will throw a deprecated notice in Joomla 3.0+.&amp;lt;/translate&amp;gt;|title=&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
Version Note&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
This tutorial is split into two independent parts:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
* Inserting, updating and removing data from the database.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
* Selecting data from one or more tables and retrieving it in a variety of forms.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
This section examines inserting, updating and removing data from a database table. See also the [[S:MyLanguage/Selecting_data_using_JDatabase|other part]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Introduction== &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
Joomla provides a sophisticated database abstraction layer to simplify the usage for third party developers. New versions of the Joomla Platform API provide additional functionality which extends the database layer further and includes features such as connectors to a greater variety of database servers and the query chaining to improve readability of connection code and simplify SQL coding.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
Joomla can use different kinds of SQL database systems and 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 you need just two 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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==The Query== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Joomla&#039;s database querying has changed since the new Joomla Framework was introduced  &#039;&#039;query chaining&#039;&#039; is now the recommended method for building database queries (although string queries are still supported).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Query chaining refers to a method of connecting a number of methods, one after the other, with each method returning an object that can support the next method, improving readability and simplifying code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
To obtain a new instance of the JDatabaseQuery class we use the JDatabaseDriver getQuery method:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
// Use one of the following depending on the file and version of Joomla &lt;br /&gt;
$db = $this-&amp;gt;_db; // use in Table class, also works in Model classes, J4 onwards&lt;br /&gt;
$db = $this-&amp;gt;getDatabase(); // only works in the Field, Model or Table classes, J4 onwards&lt;br /&gt;
&lt;br /&gt;
$db = JFactory::getDbo(); //deprecated J3, removed in J4 &lt;br /&gt;
$db = Factory::getDbo(); //deprecated J4 - requires use Joomla\CMS\Factory;&lt;br /&gt;
$db = $this-&amp;gt;getDbo(); // only works in the model or table classes, deprecated J5, use $this-&amp;gt;getDatabse();&lt;br /&gt;
$db = Factory::getContainer()-&amp;gt;get(&#039;DatabaseDriver&#039;); // Not well documented &lt;br /&gt;
&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The &#039;&#039;JDatabaseDriver::getQuery&#039;&#039; takes an optional argument, &#039;&#039;$new&#039;&#039;, which can be true or false (the default being false).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
To query our data source we can call a number of JDatabaseQuery methods; these methods encapsulate the data source&#039;s query language (in most cases SQL), hiding query-specific syntax from the developer and increasing the portability of the developer&#039;s source code.&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
Some of the more frequently used methods include: select, from, join, where and order. There are also methods such as insert, update and delete for modifying records in the data store. By chaining these and other method calls, you can create almost any query against your data store without compromising portability of your code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Inserting a Record== &amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Using SQL=== &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
The JDatabaseQuery class provides a number of methods for building insert queries, the most common being insert, columns, values.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Get a db connection.&lt;br /&gt;
$db = JFactory::getDbo(); //deprecated J3, removed in J4 &lt;br /&gt;
$db = Factory::getDbo(); //deprecated J4 - requires use Joomla\CMS\Factory;&lt;br /&gt;
$db = $this-&amp;gt;getDbo(); // only works in the model or table classes, deprecated J4&lt;br /&gt;
$db = Factory::getContainer()-&amp;gt;get(&#039;DatabaseDriver&#039;); //J4 onwards, outside of the Model or Table  &lt;br /&gt;
$db = $this-&amp;gt;_db; //only works in the model or table classes, J4 onwards&lt;br /&gt;
&lt;br /&gt;
// Create a new query object.&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
// Insert columns.&lt;br /&gt;
$columns = array(&#039;user_id&#039;, &#039;profile_key&#039;, &#039;profile_value&#039;, &#039;ordering&#039;);&lt;br /&gt;
&lt;br /&gt;
// Insert values.&lt;br /&gt;
$values = array(1001, $db-&amp;gt;quote(&#039;custom.message&#039;), $db-&amp;gt;quote(&#039;Inserting a record using insert()&#039;), 1);&lt;br /&gt;
&lt;br /&gt;
// Prepare the insert query.&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;insert($db-&amp;gt;quoteName(&#039;#__user_profiles&#039;))&lt;br /&gt;
    -&amp;gt;columns($db-&amp;gt;quoteName($columns))&lt;br /&gt;
    -&amp;gt;values(implode(&#039;,&#039;, $values));&lt;br /&gt;
&lt;br /&gt;
// Set the query using our newly populated query object and execute it.&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$db-&amp;gt;execute();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
(Here the &#039;&#039;quoteName()&#039;&#039; function adds appropriate quotes around the table and column names to avoid conflicts with any database reserved word, now or in the future.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
To get the ID of the row that you just inserted, you can use the &#039;&#039;insertid&#039;&#039; method, for example.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Get the row that was just inserted&lt;br /&gt;
$new_row_id = $db-&amp;gt;insertid();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
====How to Store Empty Value as NULL==== &amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
If your default value of a column is NULL, you should not add that column name in the array. Let the database system store NULL as the default value.&lt;br /&gt;
If the default value of a column is not NULL and it is allowed to store NULL values, you should specify that in the code. See how to do it in the following example.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Get a db connection.&lt;br /&gt;
$db = JFactory::getDbo();&lt;br /&gt;
&lt;br /&gt;
// Create a new query object.&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
/** First Case [NULL as default value] **/&lt;br /&gt;
// The column &#039;profile_value&#039; has NULL as default value. So, we will not add it to the array. The database engine will store NULL as value for column &#039;profile_value&#039;.&lt;br /&gt;
// $columns = array(&#039;user_id&#039;, &#039;profile_key&#039;, &#039;profile_value&#039;, &#039;ordering&#039;);&lt;br /&gt;
$columns = array(&#039;user_id&#039;, &#039;profile_key&#039;, &#039;ordering&#039;);&lt;br /&gt;
&lt;br /&gt;
// Insert values.&lt;br /&gt;
$values = array(1001, $db-&amp;gt;quote(&#039;custom.message&#039;), 1);&lt;br /&gt;
&lt;br /&gt;
/** Second Case [string as default value and you can also store NULL value] **/&lt;br /&gt;
// The column &#039;profile_value&#039; has empty string &#039;&#039; as default value but we can also store NULL value. So, we have to add the column name and NULL value to $columns and $values.&lt;br /&gt;
$columns = array(&#039;user_id&#039;, &#039;profile_key&#039;, &#039;profile_value&#039;, &#039;ordering&#039;);&lt;br /&gt;
&lt;br /&gt;
// Insert values.&lt;br /&gt;
$values = array(1001, $db-&amp;gt;quote(&#039;custom.message&#039;), $db-&amp;gt;quote(&#039;NULL&#039;), 1);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Using an Object=== &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
The &#039;&#039;JDatabaseDriver&#039;&#039; class also provides a convenient method for saving an object directly to the database allowing us to add a record to a table without writing a single line of SQL.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Create and populate an object.&lt;br /&gt;
$profile = new stdClass();&lt;br /&gt;
$profile-&amp;gt;user_id = 1001;&lt;br /&gt;
$profile-&amp;gt;profile_key=&#039;custom.message&#039;;&lt;br /&gt;
$profile-&amp;gt;profile_value=&#039;Inserting a record using insertObject()&#039;;&lt;br /&gt;
$profile-&amp;gt;ordering=1;&lt;br /&gt;
&lt;br /&gt;
// Insert the object into the user profile table.&lt;br /&gt;
$result = JFactory::getDbo()-&amp;gt;insertObject(&#039;#__user_profiles&#039;, $profile);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
Notice here that we do not need to escape the table name; the insertObject method does this for us.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
The insertObject method will throw a error if there is a problem inserting the record into the database table.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
If you are providing a unique primary key value (as in the example above), it is highly recommended that you select from the table by that column value before attempting an insert.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
If you are simply inserting the next row in your table (i.e. the database generates a primary key value), you can specify the primary key column-name as the third parameter of the insertObject() method and the method will update the object with the newly generated primary key value.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
For example, given the following statement:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=php&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$result = $dbconnect-&amp;gt;insertObject(&#039;#__my_table&#039;, $object, &#039;primary_key&#039;); &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
after execution, $object-&amp;gt;primary_key will be updated with the newly inserted row&#039;s primary key value.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;HINT&#039;&#039;&#039; Set $object-&amp;gt;primary_key to null or 0 (zero) before inserting.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
====How to Store Empty Value as NULL When Inserting an Object==== &amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
If your default value of a column is NULL, you should not add that column name to the object. Let the database system store NULL as the default value.&lt;br /&gt;
If the default value of a column is not NULL and it is allowed to store NULL values, you should specify that in the code. See how to do it in the following example.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Create and populate an object.&lt;br /&gt;
$profile = new stdClass();&lt;br /&gt;
$profile-&amp;gt;user_id = 1001;&lt;br /&gt;
$profile-&amp;gt;profile_key=&#039;custom.message&#039;;&lt;br /&gt;
$profile-&amp;gt;ordering=1;&lt;br /&gt;
&lt;br /&gt;
/** First Case [NULL as default value] **/&lt;br /&gt;
// The column &#039;profile_value&#039; has NULL as default value. So, we will not add it to the object. The database engine will store NULL as value for column &#039;profile_value&#039;.&lt;br /&gt;
// $profile-&amp;gt;profile_value=&#039;Inserting a record using insertObject()&#039;;&lt;br /&gt;
&lt;br /&gt;
/** Second Case [string as default value and you can also store NULL value] **/&lt;br /&gt;
// The column &#039;profile_value&#039; has empty string &#039;&#039; as default value but we can also store NULL value. So, we have to add the column name and NULL value as its value.&lt;br /&gt;
$profile-&amp;gt;profile_value = $db-&amp;gt;quote(&#039;NULL&#039;);&lt;br /&gt;
&lt;br /&gt;
// Insert the object into the user profile table.&lt;br /&gt;
$result = JFactory::getDbo()-&amp;gt;insertObject(&#039;#__user_profiles&#039;, $profile);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Updating a Record== &amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Using SQL=== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
The [https://api.joomla.org/cms-3/classes/JDatabaseQuery.html JDatabaseQuery] class also provides methods for building update queries, in particular [https://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_update update] and [https://api.joomla.org/cms-3/classes/JDatabaseQuery.html#method_set set]. We also reuse another method which we used when creating select statements, the &#039;&#039;where&#039;&#039; method.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$db = JFactory::getDbo();&lt;br /&gt;
&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
// Fields to update.&lt;br /&gt;
$fields = array(&lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;profile_value&#039;) . &#039; = &#039; . $db-&amp;gt;quote(&#039;Updating custom message for user 1001.&#039;),&lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;ordering&#039;) . &#039; = 2&#039;,&lt;br /&gt;
&lt;br /&gt;
    // If you would like to store NULL value, you should specify that.&lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;avatar&#039;) . &#039; = NULL&#039;,&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
// Conditions for which records should be updated.&lt;br /&gt;
$conditions = array(&lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;user_id&#039;) . &#039; = 42&#039;, &lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;profile_key&#039;) . &#039; = &#039; . $db-&amp;gt;quote(&#039;custom.message&#039;)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$query-&amp;gt;update($db-&amp;gt;quoteName(&#039;#__user_profiles&#039;))-&amp;gt;set($fields)-&amp;gt;where($conditions);&lt;br /&gt;
&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&lt;br /&gt;
$result = $db-&amp;gt;execute();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Using an Object === &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
Like &#039;&#039;insertObject&#039;&#039;, the JDatabaseDriver class provides a convenient method for updating an object.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
Below we will update our custom table with new values using an existing id primary key:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$updateNulls = true;&lt;br /&gt;
&lt;br /&gt;
// Create an object for the record we are going to update.&lt;br /&gt;
$object = new stdClass();&lt;br /&gt;
&lt;br /&gt;
// Must be a valid primary key value.&lt;br /&gt;
$object-&amp;gt;id = 1;&lt;br /&gt;
$object-&amp;gt;title = &#039;My Custom Record&#039;;&lt;br /&gt;
$object-&amp;gt;description = &#039;A custom record being updated in the database.&#039;;&lt;br /&gt;
&lt;br /&gt;
// If you would like to store NULL value, you should specify that.&lt;br /&gt;
$object-&amp;gt;short_description = null;&lt;br /&gt;
&lt;br /&gt;
// Update their details in the users table using id as the primary key.&lt;br /&gt;
// You should provide forth parameter with value TRUE, if you would like to store the NULL values.&lt;br /&gt;
$result = JFactory::getDbo()-&amp;gt;updateObject(&#039;#__custom_table&#039;, $object, &#039;id&#039;, $updateNulls);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
Just like insertObject, updateObject takes care of escaping table names for us.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
The updateObject method will throw a error if there is a problem updating the record into the database table.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
We need to ensure that the record already exists before attempting to update it, so we would probably add some kind of record check before executing the updateObject method.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Deleting a Record== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
Finally, there is also a delete method to remove records from the database.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$db = JFactory::getDbo();&lt;br /&gt;
&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
// delete all custom keys for user 1001.&lt;br /&gt;
$conditions = array(&lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;user_id&#039;) . &#039; = 1001&#039;, &lt;br /&gt;
    $db-&amp;gt;quoteName(&#039;profile_key&#039;) . &#039; = &#039; . $db-&amp;gt;quote(&#039;custom.%&#039;)&lt;br /&gt;
);&lt;br /&gt;
&lt;br /&gt;
$query-&amp;gt;delete($db-&amp;gt;quoteName(&#039;#__user_profiles&#039;));&lt;br /&gt;
$query-&amp;gt;where($conditions);&lt;br /&gt;
&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&lt;br /&gt;
$result = $db-&amp;gt;execute();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Sample Module Code == &amp;lt;!--T:43--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
Below is the code for a simple Joomla module which you can install and run to demonstrate use of the JDatabase functionality for updating records in the database and which you can adapt to experiment with some of the concepts described above. If you are unsure about development and installing a Joomla module then following the tutorial at [[S:MyLanguage/J3.x:Creating a simple module/Introduction| Creating a simple module]] will help.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Important note: In any Joomla extensions which you develop that you should avoid accessing the core Joomla tables directly like this and should instead use the Joomla APIs if at all possible. The database structures may change without warning.&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
In a folder &#039;&#039;mod_db_update&#039;&#039; create these two files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mod_db_update.xml&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight 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;extension type=&amp;quot;module&amp;quot; version=&amp;quot;3.1&amp;quot; client=&amp;quot;site&amp;quot; method=&amp;quot;upgrade&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;Database update demo&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;version&amp;gt;1.0.1&amp;lt;/version&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;Code demonstrating use of Joomla Database class to perform SQL UPDATE statements&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;files&amp;gt;&lt;br /&gt;
        &amp;lt;filename module=&amp;quot;mod_db_update&amp;quot;&amp;gt;mod_db_update.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
    &amp;lt;/files&amp;gt;&lt;br /&gt;
&amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;mod_db_update.php&#039;&#039;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die(&#039;Restricted Access&#039;);&lt;br /&gt;
&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
&lt;br /&gt;
$db = Factory::getDbo();&lt;br /&gt;
&lt;br /&gt;
$me = Factory::getUser();&lt;br /&gt;
&lt;br /&gt;
if ($me-&amp;gt;id == 0)&lt;br /&gt;
{&lt;br /&gt;
	echo &amp;quot;Not logged on!&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
else&lt;br /&gt;
{&lt;br /&gt;
	$email = $me-&amp;gt;email; &lt;br /&gt;
	// change the case of the email address&lt;br /&gt;
	$email_uppercase = strtoupper($email);&lt;br /&gt;
	if ($email == $email_uppercase)&lt;br /&gt;
	{&lt;br /&gt;
		$new_email = strtolower($email);&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{&lt;br /&gt;
		$new_email = $email_uppercase;&lt;br /&gt;
	}&lt;br /&gt;
	&lt;br /&gt;
	$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
	$fields = array($db-&amp;gt;quoteName(&#039;email&#039;) . &amp;quot; = &#039;{$new_email}&#039;&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	$conditions = array($db-&amp;gt;quoteName(&#039;id&#039;) . &#039; = &#039; . $me-&amp;gt;id); &lt;br /&gt;
&lt;br /&gt;
	$query-&amp;gt;update($db-&amp;gt;quoteName(&#039;#__users&#039;))-&amp;gt;set($fields)-&amp;gt;where($conditions);&lt;br /&gt;
&lt;br /&gt;
	echo $db-&amp;gt;replacePrefix((string) $query);&lt;br /&gt;
	&lt;br /&gt;
	$db-&amp;gt;setQuery($query);&lt;br /&gt;
&lt;br /&gt;
	if ($result = $db-&amp;gt;execute())&lt;br /&gt;
	{&lt;br /&gt;
		echo &amp;quot;Email case successfully changed!&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
The code above updates the email address field in the &#039;&#039;users&#039;&#039; record of the currently logged-on user, toggling between upper case and lower case in successive reloads of the web page. &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
The method &#039;&#039;Factory::getUser()&#039;&#039; returns the &#039;&#039;user&#039;&#039; object of the currently logged-on user, or if not logged on, then a blank &#039;&#039;user&#039;&#039; object, whose &#039;&#039;id&#039;&#039; field is set to zero. &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
The &#039;&#039;$db-&amp;gt;replacePrefix((string) $query)&#039;&#039; expression returns the actual SQL statement and outputting this can be useful in debugging. &amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
Zip up the &#039;&#039;mod_db_update&#039;&#039; directory to create &#039;&#039;mod_db_update.zip&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
Within your Joomla administrator go to Install Extensions and via the Upload Package File tab. Upload this zip file to install this sample log module.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
Make this module visible by editing it (click on it within the Modules page) then:&lt;br /&gt;
# Make its status &#039;&#039;Published&#039;&#039;&lt;br /&gt;
# Select a position on the page for it to be shown&lt;br /&gt;
# Specify the pages it should appear on in the Menu Assignment tab&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
When you visit a site web page you should see the module in your selected position and it should output the SQL UPDATE statement and affirm that it has updated the record successfully. To confirm that it has updated the record correctly, go into PHPMyAdmin and view the &#039;&#039;users&#039;&#039; table within the Joomla database. The updates aren&#039;t visible via the admin Users functionality on the Backend; Joomla displays in lower case all the email addresses in the records.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
[[Category:Database]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Task_Scheduler&amp;diff=1014588</id>
		<title>J4.x:Task Scheduler</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Task_Scheduler&amp;diff=1014588"/>
		<updated>2023-09-13T15:59:48Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Limit Task to Command-line Interface Only ==&lt;br /&gt;
To implement a task, which is executed via the command-line interface (CLI) only, add this code to the task XML:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;fieldset name=&amp;quot;aside&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;field name=&amp;quot;cli_exclusive&amp;quot; type=&amp;quot;hidden&amp;quot; default=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/fieldset&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The fieldset must be a direct child of the form&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;form&amp;gt;&lt;br /&gt;
	&amp;lt;fieldset name=&amp;quot;aside&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;field name=&amp;quot;cli_exclusive&amp;quot; type=&amp;quot;hidden&amp;quot; default=&amp;quot;1&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/fieldset&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_3.x_to_4.x_Step_by_Step_Migration&amp;diff=1010684</id>
		<title>Joomla 3.x to 4.x Step by Step Migration</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_3.x_to_4.x_Step_by_Step_Migration&amp;diff=1010684"/>
		<updated>2023-08-17T00:40:40Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Migration duration clarified.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{warning|title=&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Warning!&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
This guide assumes you are starting on Joomla 3.10.x. If you are on a earlier version make sure you upgrade to Joomla 3.10 first before moving to Joomla 4. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
There is no rush. Make sure all your extensions are ready for Joomla 4.x. Joomla 3.10.x will be supported until 16 August 2023.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The following are step-by-step instructions to migrate your 3.10.x site to Joomla! 4.x. While there are different scenarios, this will give you the basic procedure to follow. Complex migrations will likely be a result of installed third-party extensions. You are encouraged to contact the developers of third-party extensions installed on your Joomla site for their suggested migration path.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Intro == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The migration from Joomla! 3.10.x to 4.x is considered a mini-migration. This is because the Joomla core extensions will upgrade with a “one-click” upgrade via the Joomla! Update component in the Backend (Administrator) of Joomla. Many third-party extensions are a one-click upgrade too. Some are not. Look at each one and determine what path the extension needs to follow to get from 3.10 to 4.x. If you haven&#039;t already, read the [[S:MyLanguage/Migration Step by Step Self Assessment|Self Assessment]] and [[S:MyLanguage/Planning for Mini-Migration - Joomla 3.10.x to 4.x|Planning for 3.10 to 4.x Migration]] prior to following the steps below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/br&amp;gt;Joomla! Core Extensions are:&lt;br /&gt;
* Categories&lt;br /&gt;
* Articles&lt;br /&gt;
* Menus&lt;br /&gt;
* Modules (core modules - not third-party)&lt;br /&gt;
* Action Logs&lt;br /&gt;
* Banners&lt;br /&gt;
* Fields&lt;br /&gt;
* Content History&lt;br /&gt;
* Contacts&lt;br /&gt;
* Messaging&lt;br /&gt;
* Newsfeeds&lt;br /&gt;
* Redirect&lt;br /&gt;
* Search (decoupled in 4.x. Existing 3.x sites will still migrate it. However we recommend using Smart Search going forward. See Notes under Assess Each Extension)&lt;br /&gt;
* Smart Search&lt;br /&gt;
* Tags&lt;br /&gt;
* Weblinks (decoupled but your site may be using it and it will migrate. See Notes under Assess Each Extension.)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Step by Step == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
=== Set Up a Development Location ===&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
# Make sure you are running the latest Joomla 3.10.x version before proceeding.&lt;br /&gt;
# Take a backup of your live 3.10.x site. You can use a suggested tool (see the &#039;&#039;Suggested Tools&#039;&#039; at the bottom of page) or you can do this manually.&lt;br /&gt;
#*[[S:MyLanguage/Backup_Basics_for_a_Joomla!_Web_Site|Backup Basics for a Joomla! Web Site]]&lt;br /&gt;
#*[[S:MyLanguage/What_are_the_best_practices_for_site_backups%3F|What are the best practices for site backups?]]&lt;br /&gt;
# Make sure your environment meets the [https://downloads.joomla.org/technical-requirements technical requirements for Joomla 4].&lt;br /&gt;
# Create a new database and new user to restore your 3.10.x site to. &lt;br /&gt;
# Create a testing site or build area to work in and restore the backup copy of your 3.10.x site in one of the following places:&lt;br /&gt;
#* A subdomain.&lt;br /&gt;
#* A subdirectory.&lt;br /&gt;
#* A local device. Joomla has a detailed tutorial on installing [https://sourceforge.net/projects/xampp/ XAMPP] at [[XAMPP]]. However [https://www.wampserver.com/en/ WAMP], [https://www.mamp.info/en/windows/ MAMP], [https://sourceforge.net/projects/lampas/ LAMP] are all suitable alternatives.&lt;br /&gt;
#* A new hosting account on a temporary domain in the root. (If you would like to change hosts in the process of migration.)&lt;br /&gt;
#** Restoring a site on a local device. See [[S:MyLanguage/Installing Joomla locally|Installing Joomla locally]] and [[S:MyLanguage/Setting up your workstation for Joomla development|Setting up your workstation for Joomla development]].&lt;br /&gt;
#** Restoring a site with a tool listed at the bottom of the page. (Read the developer documentation.)&lt;br /&gt;
# In your test location, update your Joomla! 3.10.x instance to the latest maintenance release.&lt;br /&gt;
# Make sure you have the latest database schema updated to the latest version 3.10.x version by going to {{rarr|Extension Manager,Database}} tab. If your schema is not up to date as in the following image, click the &#039;&#039;&#039;Fix&#039;&#039;&#039; button:&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-extension-database-fix-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
# Empty trash: Do you have any articles in the trash? Delete them (and any associated media if not in use elsewhere on the site). Articles (categories and menu items too) left in the trash can cause migration issues.&lt;br /&gt;
# Test.&lt;br /&gt;
# Backup again.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Assess Each Extension === &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
In your [[S:MyLanguage/Planning_for_Mini-Migration_-_Joomla_3.10.x_to_4.x|planning]], you determined that third-party extensions were staying or going and how they migrate. For this portion of the Step by Step, you’ll be using two different sections of the site extensively; The Pre-Update Check in {{rarr|Components,Joomla! Update}} and {{rarr|Extensions,Manage,Manage}}. You are going to be looking at every single extension installed on your site. You will be determining if they need to be updated to the latest version or uninstalled. More details in [[Special:MyLanguage/:Pre-Update_Check|Pre-Update Check]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
# Using the &#039;&#039;&#039;Pre-Update Check&#039;&#039;&#039;: in order to use the Pre-Update Check, you will need to set the Joomla! Update component to Joomla 4. To do this follow:&lt;br /&gt;
# Go to {{rarr|Components,Joomla Update}}. (It should say no updates found. If it doesn’t, update Joomla to the latest version (must be 3.10.x) and test. Then do another backup.) Click on the Options button at the top right corner.&lt;br /&gt;
# Select &#039;&#039;Joomla Next&#039;&#039; from the drop-down for Update Channel.&amp;lt;/translate&amp;gt;{{-}}[[File:Migration_J3toJ4_update_channel-&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; en&amp;lt;/translate&amp;gt;.png|border|800px]]{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
# Click Save &amp;amp; Close&lt;br /&gt;
# You will then see your Installed Joomla Version, the latest Joomla! version and the URL for the update package. Joomla will show you the requirements again for Joomla 4. If it flags that you have either an incompatible system or extensions it will tell you here. Take a moment to review this page.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-update_to_4-pre_update_check-&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; en&amp;lt;/translate&amp;gt;.png|border|800px]]&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
{{amboxNew|image=notice|style=notice|title={{{title|Important Notice}}}|text=&#039;&#039;&#039;Do NOT update to Joomla! 4 right now. This is only to prepare your third-party extensions and get the site compatible with Joomla! 4.&#039;&#039;&#039;}}&lt;br /&gt;
# Look at the Pre-Update Check and the Extension Pre-Update Check in the Pre-Update Check tab of the Joomla Update component. If any extension that isn’t in your planning is listed here, add it to your list of extensions to investigate.&lt;br /&gt;
# If you migrated from Joomla! 2.5 to 3.x in the past, there may be some leftover extensions that need to be cleaned up. The following are older 2.5 or 3.x extensions that need to be uninstalled before updating to Joomla 4:&lt;br /&gt;
#;* plg_content_geshi&lt;br /&gt;
#;* PKG_JOOMLA &lt;br /&gt;
#;* Bluestork Administrator Template&lt;br /&gt;
#;* Beez_20&lt;br /&gt;
#;* Beez5&lt;br /&gt;
#;* Atomic&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; ## When it comes to templates, uninstall all core Frontend or Backend templates except Protostar and Beez3 (site templates) and Isis or Hathor (Administrator templates). &#039;&#039;&#039;Note&#039;&#039;&#039; Protostar is &#039;&#039;&#039;not&#039;&#039;&#039; compatible with Joomla 4. Upon migration it will disappear. You&#039;ll need to have one template selected as &amp;quot;default&amp;quot; and you can use Protostar or Beez3. Protostar will disappear upon migration to Joomla 4.x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; ## If you come across other files that need to be uninstalled, please add them to this page. This is a wiki so anyone can add to the page. Thank you in advance for your service.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt; # You will notice the tags for whether an extension is compatible or not. These tags generally tell a true story if they say No or Yes. If they say “Missing Compatibility Tag” it means that the extension developer didn’t use a tag in their extension so we don’t know if it is or isn’t compatible with Joomla 4. Talk to the developer to verify.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; # &#039;&#039;&#039;Update Extensions&#039;&#039;&#039;: update any extensions that you will keep in your website. In Joomla! 3.10.x you can go to {{rarr|Extension Manager,Update tab}} and click &#039;&#039;&#039;Find Updates&#039;&#039;&#039; that will add a tooltip in the Version column, under the Manage tab, giving some compatibility information from the Backend. This functionality only supports extensions that update via the Extension Manager Update tab. If you have extensions installed that do not use the Joomla extension update they need to be assessed manually as detailed below. The same goes for those extensions that have a tooltip. You will still need to check the type of package and migration path with the extension developer to verify how to upgrade/migrate.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
# Investigate and Uninstall Extensions Extensions: go to {{rarr|Extension Manager,Manage}}&lt;br /&gt;
# Click the Button &#039;&#039;Search Tools&#039;&#039; to show the filter options&lt;br /&gt;
# Select Package from the &#039;&#039;Select Type&#039;&#039; drop-down.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-extension-manage-package-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|800px]]{{-}}{{note|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Selecting Package first is recommended because if there is something you need to uninstall in a package, it will automatically uninstall the associated Modules, Plugins, or anything else in the package at one time.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
# Uninstall any Packages that are no longer needed or will not be migrating to Joomla 4.&lt;br /&gt;
# Repeat this process of going through the Manage tab for all Types in the drop-down: Component, File, Language, Library, Module, Plugin and Template. If the Author states Joomla! Project, then leave those extensions alone. For all others, make sure that you uninstall those not in use or not compatible with Joomla!&amp;amp;nbsp;4.x.&amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;NOTE!&#039;&#039;&#039; You will not be able to uninstall any template that is set as default. Select a Core supported template such as Beez3 or Protostar and then uninstall the template if you need to do so. &amp;lt;br /&amp;gt;&#039;&#039;Another reminder:&#039;&#039; &#039;&#039;&#039;Protostar is not compatible with Joomla 4.x&#039;&#039;&#039;. Upon migration it will disappear. Selecting it as default simply gets you to Joomla 4.x.&amp;lt;/translate&amp;gt;|type=serious}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
# Make a note of any versions of Packages and Components currently running that you will be keeping on your site. You can copy/paste them into a document for reference.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt; # For any extensions you are keeping but don&#039;t use the Extension Manager to one-click update ({{rarr|Extensions,Manage,Update}}) update all extensions to the latest versions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; # Before and as you update, note if the extensions have both 3.10.x &amp;amp; 4.x versions in the same package. If so, they will be fine to &amp;quot;one-click update.&amp;quot; If not, and 3.10 and 4.x have different packages, look at them case by case. They will normally fall into one of the following scenarios:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt; #* The extension has separate packages but upon upgrading to 4.x, they automatically detect this and still work. Make sure the developer confirms this.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt; #* The extension has separate packages that need to be uninstalled in 3.10.x and then installed with the Joomla 4.x version once the site is migrated. An example of this might be a content plugin. It is simple to uninstall it in 3.10.x and then install it again in 4.x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:46--&amp;gt; #* See [[S:MyLanguage/Template_Considerations_During_Migration|Template Considerations]] for more specific information on templates and [[S:MyLanguage/J3.x:Converting_A_Previous_Joomla!_Version_Template|Converting a previous Joomla! Version template]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Search (com_search) ==== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
Search (com_search) will be decoupled in Joomla 4.x. Search (com_search) will migrate to Joomla 4. After migration, you&#039;ll need to update it to the Joomla 4.x version via com_installer. It will continue to be maintained, but more the same way a third-party extension is by receiving updates via com_installer. It is recommended to use Smart Search (com_finder) going forward. Search will still be available at https://extensions.joomla.org/category/official-extensions/.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Weblinks ==== &amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Weblinks was decoupled back in Joomla 3.4. If it was in use on a 2.5 site, the migration process would note this and migrate the Weblinks component and data. For the migration from 3.10.x to 4.x, it will be the same. It is still available and maintained on the JED at [https://extensions.joomla.org/category/official-extensions/ Official Extensions].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Legacy Routing ==== &amp;lt;!--T:64--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; Legacy routing will not be available in Joomla 4.x. Only Modern will be available. When you do the migration, if you are using Legacy routing, the system will automatically change them to Modern routing. You will want to run a broken link checker on your site after migrating to Joomla 4.x and &#039;&#039;before you go live&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Going to Joomla! 4.x === &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
Once you have either updated or uninstalled your third-party extensions so that only those compatible with Joomla! 4 remain in your installation, continue with the following steps:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
# Go to {{rarr|System,Global Configuration,Server tab}} and turn Error Reporting from System Default to Maximum. Make sure to Save &amp;amp; Close.&amp;lt;/translate&amp;gt;{{-}} [[File:J310-system-global-config-server-tab-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|500px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
# Take another backup.&lt;br /&gt;
# Go to {{rarr|Components,Joomla Update}}. (It should say no updates found. If it doesn’t, update Joomla to the latest version and test. Then do another backup.) Click on the Options button at the top right corner.&lt;br /&gt;
# Select &#039;&#039;Joomla Next&#039;&#039; from the drop-down for Update Channel.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-component-joomla-update-select-support-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|500px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
# Click Save &amp;amp; Close.&lt;br /&gt;
# You will then see your Installed Joomla Version, the Latest Joomla! version and the URL for the update package. Joomla will show you the requirements again for Joomla 4. If it flags that you have either an incompatible system or extensions it will tell you here. Take a moment to review this page.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-to-j4-dev-update-found-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
# If the update is not showing up, go to {{rarr|Extensions,Update}} and select Clear Cache from the toolbar. Now the update to Joomla! 4 should show up.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt; # Cross your fingers, and make sure you have that backup available in case.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt; # Click the Install the Update button.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt; # Make tea whilst the status bar loads to fully green. The amount of time this takes is dependent on your site, internet connection and server speed. The process can take several minutes. There are over 12,000 files comprising 75 megabytes to be extracted. When the update is finished, you might be logged out of the Administrator. Sign in again, if necessary&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; # If all goes well, you will get to a totally new look to the Backend panel.&amp;lt;/translate&amp;gt;{{-}}[[File:j4-administrator-overview-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt; # Go to {{rarr|System,Maintenance,Database}} and click &#039;&#039;Fix&#039;&#039; if any errors show.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; # In {{rarr|System,Install,Discover}} see if there are any extensions to install. (There shouldn&#039;t be any!)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt; # Go to the Frontend of your site and see if it shows up even if it’s not the right template. If so, continue. If not, see [[S:MyLanguage/Joomla 3.10 to 4.x Common Migration Errors|common errors during migration]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt; # Take a backup.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; # Install your new template or other extensions if you have them to install. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt; # Configure them. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt; # Run a broken link checker and fix any broken links.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; # Test everything. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
# If everything works as expected, turn Error Reporting back to System Default ({{rarr|System,Global Configuration,Server tab}}). Make sure to Save &amp;amp; Close.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
# Be sure to read the post-installation messages.&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Going Live with Your Joomla! 4.x Site === &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
# When you’re ready to go live, back up your 3.10 site for the last time. Restore it in a subdirectory or subdomain if you would like to.&lt;br /&gt;
# Back up your Joomla! 4.x site and move or restore your Joomla! 4.x site to the root (or change nameservers if you were building on a temporary domain at a new hosting account root).&lt;br /&gt;
# Test again.&lt;br /&gt;
# &#039;&#039;&#039;If&#039;&#039;&#039; you have made security changes to &#039;&#039;.htaccess&#039;&#039; file in the past, you may need to change a line (or lines) in it to update to Joomla 4. Please go to [https://docs.joomla.org/Htaccess_changes_after_joomla4.0.4 Htaccess changes after joomla4.0.4] to determine if you need to change your file. &lt;br /&gt;
# Remove the Joomla! 3.10 site from the server within a couple of days unless you have edited your &#039;&#039;robots.txt&#039;&#039; file to block the search engine spiders and disabled the Frontend of the site.&lt;br /&gt;
# Remove all development sites you have been working with or keep them up-to-date if they are running a current version in order to ward off hack attempts on your server. &amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
If you had data change on the 3.10 site while you were migrating to 4.x, you will want to get that data moved over to the 4.x site before going live. You can do this manually (make sure you keep the same user IDs - go in order) or by using a [https://extensions.joomla.org/category/migration-a-conversion/data-import-a-export%20transfer%20tool/third-party%20extension/ third party extension].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Suggested Tools == &amp;lt;!--T:28--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
* [http://extensions.joomla.org/extensions/access-a-security/site-security/backup/1606 Akeeba Backup] is popular for backup and restore. See more [https://extensions.joomla.org/tags/backup/ backup tools].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Related information== &amp;lt;!--T:62--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/:Pre-Update_Check|&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt; Pre-Update_Check&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
[[Category:Migration{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_3.x_to_4.x_Step_by_Step_Migration&amp;diff=1010411</id>
		<title>Joomla 3.x to 4.x Step by Step Migration</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_3.x_to_4.x_Step_by_Step_Migration&amp;diff=1010411"/>
		<updated>2023-08-13T20:59:34Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected a command sequence.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{warning|title=&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Warning!&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
This guide assumes you are starting on Joomla 3.10.x. If you are on a earlier version make sure you upgrade to Joomla 3.10 first before moving to Joomla 4. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
There is no rush. Make sure all your extensions are ready for Joomla 4.x. Joomla 3.10.x will be supported until 16 August 2023.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The following are step-by-step instructions to migrate your 3.10.x site to Joomla! 4.x. While there are different scenarios, this will give you the basic procedure to follow. Complex migrations will likely be a result of installed third-party extensions. You are encouraged to contact the developers of third-party extensions installed on your Joomla site for their suggested migration path.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Intro == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The migration from Joomla! 3.10.x to 4.x is considered a mini-migration. This is because the Joomla core extensions will upgrade with a “one-click” upgrade via the Joomla! Update component in the Backend (Administrator) of Joomla. Many third-party extensions are a one-click upgrade too. Some are not. Look at each one and determine what path the extension needs to follow to get from 3.10 to 4.x. If you haven&#039;t already, read the [[S:MyLanguage/Migration Step by Step Self Assessment|Self Assessment]] and [[S:MyLanguage/Planning for Mini-Migration - Joomla 3.10.x to 4.x|Planning for 3.10 to 4.x Migration]] prior to following the steps below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/br&amp;gt;Joomla! Core Extensions are:&lt;br /&gt;
* Categories&lt;br /&gt;
* Articles&lt;br /&gt;
* Menus&lt;br /&gt;
* Modules (core modules - not third-party)&lt;br /&gt;
* Action Logs&lt;br /&gt;
* Banners&lt;br /&gt;
* Fields&lt;br /&gt;
* Content History&lt;br /&gt;
* Contacts&lt;br /&gt;
* Messaging&lt;br /&gt;
* Newsfeeds&lt;br /&gt;
* Redirect&lt;br /&gt;
* Search (decoupled in 4.x. Existing 3.x sites will still migrate it. However we recommend using Smart Search going forward. See Notes under Assess Each Extension)&lt;br /&gt;
* Smart Search&lt;br /&gt;
* Tags&lt;br /&gt;
* Weblinks (decoupled but your site may be using it and it will migrate. See Notes under Assess Each Extension.)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Step by Step == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
=== Set Up a Development Location ===&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
# Make sure you are running the latest Joomla 3.10.x version before proceeding.&lt;br /&gt;
# Take a backup of your live 3.10.x site. You can use a suggested tool (see the &#039;&#039;Suggested Tools&#039;&#039; at the bottom of page) or you can do this manually.&lt;br /&gt;
#*[[S:MyLanguage/Backup_Basics_for_a_Joomla!_Web_Site|Backup Basics for a Joomla! Web Site]]&lt;br /&gt;
#*[[S:MyLanguage/What_are_the_best_practices_for_site_backups%3F|What are the best practices for site backups?]]&lt;br /&gt;
# Make sure your environment meets the [https://downloads.joomla.org/technical-requirements technical requirements for Joomla 4].&lt;br /&gt;
# Create a new database and new user to restore your 3.10.x site to. &lt;br /&gt;
# Create a testing site or build area to work in and restore the backup copy of your 3.10.x site in one of the following places:&lt;br /&gt;
#* A subdomain.&lt;br /&gt;
#* A subdirectory.&lt;br /&gt;
#* A local device. Joomla has a detailed tutorial on installing [https://sourceforge.net/projects/xampp/ XAMPP] at [[XAMPP]]. However [https://www.wampserver.com/en/ WAMP], [https://www.mamp.info/en/windows/ MAMP], [https://sourceforge.net/projects/lampas/ LAMP] are all suitable alternatives.&lt;br /&gt;
#* A new hosting account on a temporary domain in the root. (If you would like to change hosts in the process of migration.)&lt;br /&gt;
#** Restoring a site on a local device. See [[S:MyLanguage/Installing Joomla locally|Installing Joomla locally]] and [[S:MyLanguage/Setting up your workstation for Joomla development|Setting up your workstation for Joomla development]].&lt;br /&gt;
#** Restoring a site with a tool listed at the bottom of the page. (Read the developer documentation.)&lt;br /&gt;
# In your test location, update your Joomla! 3.10.x instance to the latest maintenance release.&lt;br /&gt;
# Make sure you have the latest database schema updated to the latest version 3.10.x version by going to {{rarr|Extension Manager,Database}} tab. If your schema is not up to date as in the following image, click the &#039;&#039;&#039;Fix&#039;&#039;&#039; button:&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-extension-database-fix-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
# Empty trash: Do you have any articles in the trash? Delete them (and any associated media if not in use elsewhere on the site). Articles (categories and menu items too) left in the trash can cause migration issues.&lt;br /&gt;
# Test.&lt;br /&gt;
# Backup again.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Assess Each Extension === &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
In your [[S:MyLanguage/Planning_for_Mini-Migration_-_Joomla_3.10.x_to_4.x|planning]], you determined that third-party extensions were staying or going and how they migrate. For this portion of the Step by Step, you’ll be using two different sections of the site extensively; The Pre-Update Check in {{rarr|Components,Joomla! Update}} and {{rarr|Extensions,Manage,Manage}}. You are going to be looking at every single extension installed on your site. You will be determining if they need to be updated to the latest version or uninstalled. More details in [[Special:MyLanguage/:Pre-Update_Check|Pre-Update Check]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
# Using the &#039;&#039;&#039;Pre-Update Check&#039;&#039;&#039;: in order to use the Pre-Update Check, you will need to set the Joomla! Update component to Joomla 4. To do this follow:&lt;br /&gt;
# Go to {{rarr|Components,Joomla Update}}. (It should say no updates found. If it doesn’t, update Joomla to the latest version (must be 3.10.x) and test. Then do another backup.) Click on the Options button at the top right corner.&lt;br /&gt;
# Select &#039;&#039;Joomla Next&#039;&#039; from the drop-down for Update Channel.&amp;lt;/translate&amp;gt;{{-}}[[File:Migration_J3toJ4_update_channel-&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; en&amp;lt;/translate&amp;gt;.png|border|800px]]{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
# Click Save &amp;amp; Close&lt;br /&gt;
# You will then see your Installed Joomla Version, the latest Joomla! version and the URL for the update package. Joomla will show you the requirements again for Joomla 4. If it flags that you have either an incompatible system or extensions it will tell you here. Take a moment to review this page.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-update_to_4-pre_update_check-&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; en&amp;lt;/translate&amp;gt;.png|border|800px]]&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
{{amboxNew|image=notice|style=notice|title={{{title|Important Notice}}}|text=&#039;&#039;&#039;Do NOT update to Joomla! 4 right now. This is only to prepare your third-party extensions and get the site compatible with Joomla! 4.&#039;&#039;&#039;}}&lt;br /&gt;
# Look at the Pre-Update Check and the Extension Pre-Update Check in the Pre-Update Check tab of the Joomla Update component. If any extension that isn’t in your planning is listed here, add it to your list of extensions to investigate.&lt;br /&gt;
# If you migrated from Joomla! 2.5 to 3.x in the past, there may be some leftover extensions that need to be cleaned up. The following are older 2.5 or 3.x extensions that need to be uninstalled before updating to Joomla 4:&lt;br /&gt;
#;* plg_content_geshi&lt;br /&gt;
#;* PKG_JOOMLA &lt;br /&gt;
#;* Bluestork Administrator Template&lt;br /&gt;
#;* Beez_20&lt;br /&gt;
#;* Beez5&lt;br /&gt;
#;* Atomic&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; ## When it comes to templates, uninstall all core Frontend or Backend templates except Protostar and Beez3 (site templates) and Isis or Hathor (Administrator templates). &#039;&#039;&#039;Note&#039;&#039;&#039; Protostar is &#039;&#039;&#039;not&#039;&#039;&#039; compatible with Joomla 4. Upon migration it will disappear. You&#039;ll need to have one template selected as &amp;quot;default&amp;quot; and you can use Protostar or Beez3. Protostar will disappear upon migration to Joomla 4.x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; ## If you come across other files that need to be uninstalled, please add them to this page. This is a wiki so anyone can add to the page. Thank you in advance for your service.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt; # You will notice the tags for whether an extension is compatible or not. These tags generally tell a true story if they say No or Yes. If they say “Missing Compatibility Tag” it means that the extension developer didn’t use a tag in their extension so we don’t know if it is or isn’t compatible with Joomla 4. Talk to the developer to verify.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; # &#039;&#039;&#039;Update Extensions&#039;&#039;&#039;: update any extensions that you will keep in your website. In Joomla! 3.10.x you can go to {{rarr|Extension Manager,Update tab}} and click &#039;&#039;&#039;Find Updates&#039;&#039;&#039; that will add a tooltip in the Version column, under the Manage tab, giving some compatibility information from the Backend. This functionality only supports extensions that update via the Extension Manager Update tab. If you have extensions installed that do not use the Joomla extension update they need to be assessed manually as detailed below. The same goes for those extensions that have a tooltip. You will still need to check the type of package and migration path with the extension developer to verify how to upgrade/migrate.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
# Investigate and Uninstall Extensions Extensions: go to {{rarr|Extension Manager,Manage}}&lt;br /&gt;
# Click the Button &#039;&#039;Search Tools&#039;&#039; to show the filter options&lt;br /&gt;
# Select Package from the &#039;&#039;Select Type&#039;&#039; drop-down.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-extension-manage-package-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|800px]]{{-}}{{note|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Selecting Package first is recommended because if there is something you need to uninstall in a package, it will automatically uninstall the associated Modules, Plugins, or anything else in the package at one time.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
# Uninstall any Packages that are no longer needed or will not be migrating to Joomla 4.&lt;br /&gt;
# Repeat this process of going through the Manage tab for all Types in the drop-down: Component, File, Language, Library, Module, Plugin and Template. If the Author states Joomla! Project, then leave those extensions alone. For all others, make sure that you uninstall those not in use or not compatible with Joomla!&amp;amp;nbsp;4.x.&amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;NOTE!&#039;&#039;&#039; You will not be able to uninstall any template that is set as default. Select a Core supported template such as Beez3 or Protostar and then uninstall the template if you need to do so. &amp;lt;br /&amp;gt;&#039;&#039;Another reminder:&#039;&#039; &#039;&#039;&#039;Protostar is not compatible with Joomla 4.x&#039;&#039;&#039;. Upon migration it will disappear. Selecting it as default simply gets you to Joomla 4.x.&amp;lt;/translate&amp;gt;|type=serious}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
# Make a note of any versions of Packages and Components currently running that you will be keeping on your site. You can copy/paste them into a document for reference.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt; # For any extensions you are keeping but don&#039;t use the Extension Manager to one-click update ({{rarr|Extensions,Manage,Update}}) update all extensions to the latest versions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; # Before and as you update, note if the extensions have both 3.10.x &amp;amp; 4.x versions in the same package. If so, they will be fine to &amp;quot;one-click update.&amp;quot; If not, and 3.10 and 4.x have different packages, look at them case by case. They will normally fall into one of the following scenarios:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt; #* The extension has separate packages but upon upgrading to 4.x, they automatically detect this and still work. Make sure the developer confirms this.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt; #* The extension has separate packages that need to be uninstalled in 3.10.x and then installed with the Joomla 4.x version once the site is migrated. An example of this might be a content plugin. It is simple to uninstall it in 3.10.x and then install it again in 4.x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:46--&amp;gt; #* See [[S:MyLanguage/Template_Considerations_During_Migration|Template Considerations]] for more specific information on templates and [[S:MyLanguage/J3.x:Converting_A_Previous_Joomla!_Version_Template|Converting a previous Joomla! Version template]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Search (com_search) ==== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
Search (com_search) will be decoupled in Joomla 4.x. Search (com_search) will migrate to Joomla 4. After migration, you&#039;ll need to update it to the Joomla 4.x version via com_installer. It will continue to be maintained, but more the same way a third-party extension is by receiving updates via com_installer. It is recommended to use Smart Search (com_finder) going forward. Search will still be available at https://extensions.joomla.org/category/official-extensions/.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Weblinks ==== &amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Weblinks was decoupled back in Joomla 3.4. If it was in use on a 2.5 site, the migration process would note this and migrate the Weblinks component and data. For the migration from 3.10.x to 4.x, it will be the same. It is still available and maintained on the JED at [https://extensions.joomla.org/category/official-extensions/ Official Extensions].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Legacy Routing ==== &amp;lt;!--T:64--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; Legacy routing will not be available in Joomla 4.x. Only Modern will be available. When you do the migration, if you are using Legacy routing, the system will automatically change them to Modern routing. You will want to run a broken link checker on your site after migrating to Joomla 4.x and &#039;&#039;before you go live&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Going to Joomla! 4.x === &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
Once you have either updated or uninstalled your third-party extensions so that only those compatible with Joomla! 4 remain in your installation, continue with the following steps:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
# Go to {{rarr|System,Global Configuration,Server tab}} and turn Error Reporting from System Default to Maximum. Make sure to Save &amp;amp; Close.&amp;lt;/translate&amp;gt;{{-}} [[File:J310-system-global-config-server-tab-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|500px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
# Take another backup.&lt;br /&gt;
# Go to {{rarr|Components,Joomla Update}}. (It should say no updates found. If it doesn’t, update Joomla to the latest version and test. Then do another backup.) Click on the Options button at the top right corner.&lt;br /&gt;
# Select &#039;&#039;Joomla Next&#039;&#039; from the drop-down for Update Channel.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-component-joomla-update-select-support-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|500px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
# Click Save &amp;amp; Close.&lt;br /&gt;
# You will then see your Installed Joomla Version, the Latest Joomla! version and the URL for the update package. Joomla will show you the requirements again for Joomla 4. If it flags that you have either an incompatible system or extensions it will tell you here. Take a moment to review this page.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-to-j4-dev-update-found-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
# If the update is not showing up, go to {{rarr|Extensions,Update}} and select Clear Cache from the toolbar. Now the update to Joomla! 4 should show up.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt; # Cross your fingers, and make sure you have that backup available in case.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt; # Click the Install the Update button.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt; # Make tea whilst the status bar loads to fully green. The amount of time this takes is dependent on your site, Internet connection and server speed. The process takes about two minutes. When the update is finished, you will probably be logged out of the Administrator. Sign in again. Twice.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; # If all goes well, you will get to a totally new look to the Backend panel.&amp;lt;/translate&amp;gt;{{-}}[[File:j4-administrator-overview-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt; # Go to {{rarr|System,Maintenance,Database}} and click &#039;&#039;Fix&#039;&#039; if any errors show.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; # In {{rarr|System,Install,Discover}} see if there are any extensions to install. (There shouldn&#039;t be any!)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt; # Go to the Frontend of your site and see if it shows up even if it’s not the right template. If so, continue. If not, see [[S:MyLanguage/Joomla 3.10 to 4.x Common Migration Errors|common errors during migration]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt; # Take a backup.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; # Install your new template or other extensions if you have them to install. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt; # Configure them. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt; # Run a broken link checker and fix any broken links.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; # Test everything. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
# If everything works as expected, turn Error Reporting back to System Default ({{rarr|System,Global Configuration,Server tab}}). Make sure to Save &amp;amp; Close.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Going Live with Your Joomla! 4.x Site === &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
# When you’re ready to go live, back up your 3.10 site for the last time. Restore it in a subdirectory or subdomain if you would like to.&lt;br /&gt;
# Back up your Joomla! 4.x site and move or restore your Joomla! 4.x site to the root (or change nameservers if you were building on a temporary domain at a new hosting account root).&lt;br /&gt;
# Test again.&lt;br /&gt;
# &#039;&#039;&#039;If&#039;&#039;&#039; you have made security changes to &#039;&#039;.htaccess&#039;&#039; file in the past, you may need to change a line (or lines) in it to update to Joomla 4. Please go to [https://docs.joomla.org/Htaccess_changes_after_joomla4.0.4 Htaccess changes after joomla4.0.4] to determine if you need to change your file. &lt;br /&gt;
# Remove the Joomla! 3.10 site from the server within a couple of days unless you have edited your &#039;&#039;robots.txt&#039;&#039; file to block the search engine spiders and disabled the Frontend of the site.&lt;br /&gt;
# Remove all development sites you have been working with or keep them up-to-date if they are running a current version in order to ward off hack attempts on your server. &amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
If you had data change on the 3.10 site while you were migrating to 4.x, you will want to get that data moved over to the 4.x site before going live. You can do this manually (make sure you keep the same user IDs - go in order) or by using a [https://extensions.joomla.org/category/migration-a-conversion/data-import-a-export%20transfer%20tool/third-party%20extension/ third party extension].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Suggested Tools == &amp;lt;!--T:28--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
* [http://extensions.joomla.org/extensions/access-a-security/site-security/backup/1606 Akeeba Backup] is popular for backup and restore. See more [https://extensions.joomla.org/tags/backup/ backup tools].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Related information== &amp;lt;!--T:62--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/:Pre-Update_Check|&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt; Pre-Update_Check&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
[[Category:Migration{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J3.x:Access_Control_List_Tutorial&amp;diff=1009666</id>
		<title>J3.x:Access Control List Tutorial</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J3.x:Access_Control_List_Tutorial&amp;diff=1009666"/>
		<updated>2023-07-15T21:04:14Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{Joomla version|version=3.x|comment=&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
series &amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Separate ACL for Viewing and Doing== &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
The Joomla ACL system can be thought of as being divided into two completely separate systems. One system controls what things on the site Users can &#039;&#039;view&#039;&#039;. The other controls what things Users can &#039;&#039;do&#039;&#039; (what actions a User can take). The ACL for each is set up differently.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Controlling What Users Can See=== &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
The setup for controlling what Users can see is done as follows:&lt;br /&gt;
* Create a set of Access Levels according to the Categories and/or the combination of categories you wish only logged in Users to see. N.B. Do not assign any User groups to the new Access Levels at this point.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
* Create a User Group, with &#039;Registered&#039; as parent, for each Access Level. Using the same names for the User Groups as the Access Levels will prevent confusion later.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
* Edit your new Access Levels and assign the correct (new) User Group to each one. You may also wish to assign the Super User Group (and/or the other default User Groups but not &#039;Guest&#039; User Group) to all your new Access Levels&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
* Assign each item to be viewed to one Access Level. Items include content items (articles, contacts, and so on), menu items, and modules.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
Any time a User is about to view an item on a Joomla page, the program checks whether the User has access to the item, as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
# Creates a list of all the Access Levels that the User has access to, based on all Groups that the User belongs to. Also, if a group has a parent group, access levels for the parent group are also included in the list.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
# Checks whether the Access Level for the item (article, module, menu item, and so on) is on that list. If yes, then the item is displayed to the User. If no, then the item is not displayed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
Note that Access Levels are set separately for each Group and are not inherited from a group&#039;s parent group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Controlling What Users Can Do=== &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
The system for setting up what Users in a User Group can do -- what actions they can take on a given item -- is set up with the Permissions tab of Global Configuration and the Permissions tab of the Options screen of each component. Permissions can also be set up at the Category level for core components and at the Article level for articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
* If you wish logged in Users to Create, Delete, Edit State or Edit Own for specific Categories then:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
** Create a User Group with the Parent as one of your User Groups that has Access to the Category(or Categories) you wish this new User Group to modify.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
**Assign your new User Group to the appropriate Access Level(s). Then change the required permissions for your new User Group either Globally or per Category/Article.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
***When creating a User Group it is good practice to select a parent group that has less permissions than needed for the new group. This is because it is easier to elevate permissions per Component/Category/Article that the extra permissions are needed for than it is to remove permissions from the other Components/Categories/Articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
****&#039;&#039;(Example: You have ten Categories but you want Create permissions for just one. If you set Global permissions to Allow Create for that group you would need to remove Create permission for all those categories. And you would need to remove the Create permission for that group with any new Category that you add at a later date.)&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
**Only create a User Group with one of the default User Groups as parent if none of them have the exact permissions that you need and you wish all Categories&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
Note that this set up is independent of the setup for viewing but a User Group needs to be assigned to the appropriate Access Level(s) in order for the User in that Group to use those Permissions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
When a User wants to initiate a specific action against a component item (for example, edit an article), the system (after checking the Group the User is in has access) checks the permission for this combination of User, item, and action. If it is allowed, then the User can proceed. Otherwise, the action is not allowed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
The remainder of this tutorial discusses how we control what Users can do -- what action permissions they have.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Actions, Groups, and Inheritance== &amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
The other side of ACL is granting permissions to Users to take actions on objects.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
!style=&amp;quot;width:20%;&amp;quot;|&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
3.x series&amp;lt;/translate&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
Groups and Actions&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
Actions allowed for each group are defined by site administrator.&amp;lt;/translate&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
Permission Scope&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
Permissions can be set at multiple levels in hierarchy: Site, Component, Category, Object.&amp;lt;/translate&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
!&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
Permission Inheritance&amp;lt;/translate&amp;gt;&lt;br /&gt;
|&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Permissions can be inherited from parent Groups and parent Categories&amp;lt;/translate&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===How Permissions Work=== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
There are four possible permissions for actions, as outlined below:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Not set&#039;&#039;&#039;: Defaults to &amp;quot;deny&amp;quot; but, unlike the Deny permission, this permission can be overridden by setting a child group or a lower level in the permission hierarchy to &amp;quot;Allow.&amp;quot; This permission only applies to the Global Configuration permissions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Inherit&#039;&#039;&#039;: Inherits the value from a parent Group or from a higher level in the permission hierarchy. This permission applies to all levels except the Global Configuration level.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Deny&#039;&#039;&#039;: Denies this action for this level and group. &#039;&#039;&#039;IMPORTANT&#039;&#039;&#039; This also denies this action for all child groups and all lower levels in the permission hierarchy. Putting in Allow for a child group or a lower level will not have any effect. The action will always be denied for any child group member and for any lower level in the permission hierarchy.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Allow&#039;&#039;&#039;: Allows this action for this level and group and for lower levels and child groups. This does not have any effect if a higher group or level is set to Deny or Allow. If a higher group or level is set to Deny, then this permission will always be denied. If a higher group or level is set to Allow, then this permission will already be allowed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{anchor|hierarchylevels}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Permission Hierarchy Levels=== &amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
Action permissions in version 2.5+ can be defined at up to four levels, as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Global Configuration&#039;&#039;&#039;: determines the default permissions for each action and group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
# {{rarr|Component Options,Permissions}}: can override the default permissions for this component (for example, Articles, Menus, Users, Banners, and so on).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Category&#039;&#039;&#039;: can override the default permissions for objects in one or more categories. Applies to all components with categories, including Articles, Banners, Contacts, News Feeds, and Web Links.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
# &#039;&#039;&#039;Article&#039;&#039;&#039;: Can override the permissions for a specific article. This level only applies to articles. Other components only allow the first three levels.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
====Global Configuration==== &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:279--&amp;gt;&lt;br /&gt;
This is accessed from {{rarr|System,Global Configuration,Permissions}}. This screen allows you set the top-level permission for each group for each action, as shown in the screenshot below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Screenshot_global_acl_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
The options for each value are Inherited, Allowed, or Denied. The Calculated Setting column shows you the setting in effect. It is either Not Allowed (the default), Allowed, or Denied.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
You work on one Group at a time by opening the slider for that group. You change the permissions in the Select New Settings drop-down list boxes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
Note that the Calculated Setting column is not updated until you press the Save button in the toolbar. To check that the settings are what you want, press the Save button and check the Calculated Settings column.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
====Component Options and Permissions==== &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
This is accessed for each component by clicking the Options icon in the toolbar. This screen is similar to the Global Configuration screen above. For example, clicking the Options toolbar icon in the Menu Manager shows the Menus Configuration below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:Screenshot_menu_acl_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
Access to Options is only available to members of groups who have permission for the Configure action in for each component. In the example above, the Administrator group has Allowed permission for the Configure option, so members of this group can access this screen.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
====Category==== &amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:280--&amp;gt;&lt;br /&gt;
Category permissions are accessed in the Category Manager: Edit Category screen, in a tab at the top of the screen. This screen has five permissions, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Screenshot_category_acl_j3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
In these screens, you work on the permissions for one User Group at a time. In the example above, we are editing the permissions for the Administrator group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
Note that the Configure and Access Component actions do not apply at the category level, so those actions are not included.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
Note also that Categories can be arranged in a hierarchy. If so, then action permissions in a parent category are inherited automatically by a child category. For example, if you had a category hierarchy of {{rarr|Animals,Pets,Dogs}}, then the full permission level hierarchy for an article in the Dogs category would be as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt;&lt;br /&gt;
* Global Configuration&lt;br /&gt;
* {{rarr|Article Manager,Options,Permission}}&lt;br /&gt;
* Animals Category&lt;br /&gt;
* Pets Category&lt;br /&gt;
* Dogs Category&lt;br /&gt;
* specific article&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
====Article==== &amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
Permissions for a single article are accessed in the {{rarr|Article Manager,Edit Article}} screen, again in a slider at the bottom of the screen. This screen has three actions:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:j3x_acl_tutorial_article_manager_article_permissions-&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
Again, you edit each group by clicking on it to open the slider for that group. You can then change the permissions under the Select New Setting column. To see the effect of any changes, press the Save button to update the Calculated Setting column.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt;&lt;br /&gt;
Note that the Configure, Access Component, and Create actions do not apply at the article level, so these actions are not included. Permission to create an article is set at one of the higher levels in the hierarchy.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Access Levels=== &amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
Access Levels in 3.x series are simple and flexible. The screen below shows the Special Access Level.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:j3x_acl_tutorial_viewing_levels-&amp;lt;translate&amp;gt;&amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
Simply check the box for each group you want included in that level. The Special Access Level includes the Manager, Author, and Super Users groups. It also includes child groups of those groups. So, Administrator group is included, since it is a child group of the Manager group. The Editor, Publisher, and Shop Suppliers groups are included, since they are child groups of Author. (Note that we could check all of the child groups if we wanted and it wouldn&#039;t hurt anything).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
Once Access Levels are created, they are used in the same way as in version 1.5. Each object in the Frontend is assigned an Access Level. If the level is Public, then anyone may access that object. Otherwise, only members of groups assigned to that access level may access that object. Access levels are assigned to Menu Items and to Modules. Each one can only be assigned to one access level.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
For example, the screen below shows the Edit Menu Item screen with the list of available access levels.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:j3x_acl_tutorial_edit_menu_item_level_dropdown-&amp;lt;translate&amp;gt;&amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Default ACL Setup== &amp;lt;!--T:73--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:74--&amp;gt;&lt;br /&gt;
When Joomla! is installed, these are set to their initial default settings. We will discuss these initial settings as a way to understand how the ACL works.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Default Groups=== &amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
Version 3.x allows you to define your own Groups. When you install version 3.x, it includes a set of default groups, shown below are the basic default User groups. (Additional default User groups are installed with sample data.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Screenshot_usergroupsl_acl_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:77--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
The arrows indicate the child-parent relationships. As discussed above, when you set a permission for a parent group, this permission is automatically inherited by all child groups. The Inherited, and Allowed permissions can be overridden for a child group. The Denied permission cannot be overridden and will always deny an action for all child groups.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Global Configuration=== &amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:80--&amp;gt;&lt;br /&gt;
Joomla! version 2.5 will install with the same familiar Backend permissions as that of version 1.5. However, with 2.5, you can easily change these to suit the needs of your site.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:81--&amp;gt;&lt;br /&gt;
As discussed earlier, the permissions for each action are inherited from the level above in the permission hierarchy and from a group&#039;s parent group. Let&#039;s see how this works. The top level for this is the entire site. This is set up in the {{rarr|Site,Global Configuration,Permissions}}, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Screenshot_global_acl_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:82--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:83--&amp;gt;&lt;br /&gt;
The first thing to notice are the ten Actions: Site Login, Admin Login, Offline Access, Super User, Access Administration Interface, Create, Delete, Edit, Edit State. and Edit Own. These are the actions that a User can perform on an object in Joomla. The specific meaning of each action depends on the context. For the Global Configuration screen, they are defined as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:84--&amp;gt;&lt;br /&gt;
;Site Login : Login to the Frontend of the site&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:85--&amp;gt;&lt;br /&gt;
;Admin Login : Login to the Backend of the site&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:278--&amp;gt;&lt;br /&gt;
;Offline Access : Login to the Frontend of the site when the website site is offline (when Global Configuration setting &amp;quot;Site Offline&amp;quot; is set to Yes)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:86--&amp;gt;&lt;br /&gt;
; Super User : Grants the User &amp;quot;Super User&amp;quot; status. Users with this permission can do anything on the site. Only Users with this permission can change Global Configuration settings (this screen). These permissions cannot be restricted. It is important to understand that, if a User is a member of a Super User group, any other permissions assigned to this User are irrelevant. The User can do any action on the site. However, Access Levels can still be assigned to control what this group sees on the site. (Obviously, a Super User can change Access Levels if they want to, so Access Levels do not totally restrict what a Super User can see.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:87--&amp;gt;&lt;br /&gt;
;Access Component: Open the component manager screens (User Manager, Menu Manager, Article Manager, and so on)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:88--&amp;gt;&lt;br /&gt;
;Create : Create new objects (for example, Users, Menu Items, Articles, Web Links, and so on)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:89--&amp;gt;&lt;br /&gt;
;Delete : Delete existing objects&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:90--&amp;gt;&lt;br /&gt;
;Edit : Edit existing objects&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:91--&amp;gt;&lt;br /&gt;
;Edit State : Change object state (Publish, Unpublish, Archive, and Trash)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:92--&amp;gt;&lt;br /&gt;
;Edit Own : Edit objects that you have created.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:93--&amp;gt;&lt;br /&gt;
Each Group for the site has its own slider which is opened by clicking on the group name. In this case (with the sample data installed), we have the standard 7 groups that we had in version 1.5 plus two additional groups called &amp;quot;Shop Suppliers&amp;quot; and &amp;quot;Customer Group.&amp;quot; Notice that our groups are set up with the same permissions as they had in version 1.5. Keep in mind that we can change any of these permissions to make the security work the way we want. Let&#039;s go through this to see how it works.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:94--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Public&#039;&#039;&#039; has everything set to &amp;quot;Not set&amp;quot;, as shown below.&amp;lt;/translate&amp;gt;{{-}}[[Image:Screenshot_global_acl_public_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:95--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:96--&amp;gt;&lt;br /&gt;
**This can be a bit confusing. Basically, &amp;quot;Not Set&amp;quot; is the same as &amp;quot;Inherited.&amp;quot; Because Public is our top-level group, and because Global Configuration is the top level of the component hierarchy, there is nothing to inherit from. So &amp;quot;Not Set&amp;quot; is used instead of &amp;quot;Inherit.&amp;quot;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:97--&amp;gt;&lt;br /&gt;
**The default in this case is for no permissions. As you would expect, the Public group has no special permissions. Also, it is important to note that, since nothing is set to Denied, all of these permissions may be overridden by child groups or by lower levels in the permission hierarchy.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:98--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Guest&#039;&#039;&#039; is a &#039;child&#039; group of the Public group has everything set to &#039;Inherited&#039;&amp;lt;/translate&amp;gt; {{-}}[[Image:Screenshot_global_acl_guest_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:99--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:100--&amp;gt;&lt;br /&gt;
** This is the default &#039;Guest User Group&#039; in the User Manager options and the Group that (non logged in) visitors to your site are placed in.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:101--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Manager&#039;&#039;&#039; is a &amp;quot;child&amp;quot; group of the Public group. It has Allowed permissions for everything except Access Component and Super User. So a member of this group can do everything in the front and Backend of the site except change Global Permissions and Component Options.&amp;lt;/translate&amp;gt; {{-}}[[Image:Screenshot_global_acl_manager_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:102--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:103--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Administrator&#039;&#039;&#039; group members inherit all of the Manager permissions and also have Allowed for Access Component. So members of this group by default can access the Options screens for each component.&amp;lt;/translate&amp;gt; {{-}}[[Image:Screenshot_global_acl_administrator_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:104--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:105--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Registered&#039;&#039;&#039; is the same a Public except for the Allow permission for the Site Login action. This means that members of the Registered group can login to the site. Since default permissions are inherited, this means that, unless a child group overrides this permission, all child groups of the Registered group will be able to login as well.&amp;lt;/translate&amp;gt; {{-}}[[Image:Screenshot_global_acl_registered_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:106--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:107--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Author&#039;&#039;&#039; is a child of the Registered group and inherits its permissions and also adds Create and Edit Own. Since Author, Editor, and Publisher have no Backend permissions, we will discuss them below, when we discuss Frontend permissions.&amp;lt;/translate&amp;gt;{{-}}[[Image:Screenshot_global_acl_author_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:108--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:109--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Editor&#039;&#039;&#039; is a child of the Authors group and adds the Edit permission.&amp;lt;/translate&amp;gt; {{-}}[[Image:Screenshot_global_acl_editor_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:110--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:111--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Publisher&#039;&#039;&#039; is a child of Editor and adds the Edit State permission.&amp;lt;/translate&amp;gt;{{-}}[[Image:Screenshot_global_acl_publisher_J3_tutorial-&amp;lt;translate&amp;gt;&amp;lt;!--T:112--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:113--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Shop Suppliers&#039;&#039;&#039; is an example group that is installed if you install the sample data. It is a child group of Author.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Customer Group&#039;&#039;&#039; is an example group that is installed if you install the sample data. It is a child group of Registered.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:115--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Super Users&#039;&#039;&#039; group has the Allow permission for the Super User action. Because of this, members of this group have Super User permissions throughout the site. They are the only Users who can access and edit values on the Global Configuration screen. Users with permission for the Super User action have some special characteristics:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:116--&amp;gt;&lt;br /&gt;
:* If a User has Super User permissions, no other permissions for this User matter. The User can perform any action on the site.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt;&lt;br /&gt;
:* Only Super Users can create, edit, or delete other Super Users or groups.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:118--&amp;gt;&lt;br /&gt;
There are two important points to understand from this screen. The first is to see how the permissions can be inherited from the parent Group. The second is to see how you can control the default permissions by Group and by Action.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt;&lt;br /&gt;
This provides a lot of flexibility. For example, if you wanted Shop Suppliers to be able to have the ability to login to the Backend, you could just change their Admin Login value to &amp;quot;Allowed.&amp;quot; If you wanted to not allow members of Administrator group to delete objects or change their state, you would change their permissions in these columns to Inherited (or Denied).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:120--&amp;gt;&lt;br /&gt;
It is also important to understand that the ability to have child groups is completely optional. It allows you to save some time when setting up new groups. However, if you like, you can set up all groups to have Public as the parent and not inherit any permissions from a parent group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Component Options and Permissions=== &amp;lt;!--T:121--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:123--&amp;gt;&lt;br /&gt;
Just looking at the Global Configuration screen above, it would appear that the Administrator group and the Manager group have identical permissions. However, in version 1.5 Administrators can do everything except Global Configuration, whereas Managers are not permitted to add Users or work with menu items. That is also true in the default version 2.5 configuration. Let&#039;s see how this is accomplished.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:124--&amp;gt;&lt;br /&gt;
If we navigate to {{rarr|Users,User Manager}} and click the Options button in the toolbar, we see the screen below:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110111-09-&amp;lt;translate&amp;gt;&amp;lt;!--T:125--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|]]&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110111-10-&amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:127--&amp;gt;&lt;br /&gt;
This screen is the same as the Global Configuration Permissions screen, except that these values only affect working with Users. Let&#039;s look at how this works.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:128--&amp;gt;&lt;br /&gt;
First, notice that the Administrator group has Allow permission for the Admin action and the Manager group has Deny permission for this action. Remember that the Admin action in the Global Configuration screen gives the group &amp;quot;Super User&amp;quot; permissions. In this screen, the Admin action allows you to edit the Options values. So, the Administrator group can do this but the Manager group cannot.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:129--&amp;gt;&lt;br /&gt;
Next, notice that the Administrator has Inherit for the Manage action and the Manager group has Deny permission. In this screen, the Manage action gives a group access to the User Manager. Since the Administrator has Allow for the Manage action by default, then the Inherit permission here means they inherit the Allow permission for the Manage action. Since the Manager group has Deny permission for the Manage action, members of the Manager group cannot access the User Manager and therefore cannot do any of the other User-related actions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt;&lt;br /&gt;
If you look at the Options for {{rarr|Menus,Menu Manager}}, you will see the same default settings as for the User Manager. Again, the Administrator group can manage and set default permissions for Menu Manager objects whereas the Manager group cannot.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:131--&amp;gt;&lt;br /&gt;
In short, we can see that the different permissions for the Administrator and Manager groups are set using the {{rarr|Options,Permissions}} forms on the User Manager and Menu Manager screens.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:132--&amp;gt;&lt;br /&gt;
It is also important to understand that this same {{rarr|Options,Permissions}} form for setting default permissions is available for all Joomla! objects, including Media Manager, Banners, Contacts, News Feeds, Redirect, Search Statistics, Web Links, Extensions, Modules, Plugins, Templates, and Language. So you now have the option to create User groups with fine-tuned sets of Backend permissions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Frontend Permissions=== &amp;lt;!--T:133--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:134--&amp;gt;&lt;br /&gt;
Default permissions for the Frontend are also set using the Options form. Let&#039;s look at {{rarr|Content,Article Manager,Options,Permissions}}. First, let&#039;s look at the permissions for Manager, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110111-11a-&amp;lt;translate&amp;gt;&amp;lt;!--T:135--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt;&lt;br /&gt;
Manager has allowed permission for all actions except Configure. So members of the Manager group can do everything with Articles except open the Options screen.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:137--&amp;gt;&lt;br /&gt;
Now let&#039;s look at Administrator, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110111-12a-&amp;lt;translate&amp;gt;&amp;lt;!--T:138--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:139--&amp;gt;&lt;br /&gt;
Administrator has Allowed for Configure, so Administrators can edit this Options screen.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:140--&amp;gt;&lt;br /&gt;
Both groups can create, delete, edit, and change the state of articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:141--&amp;gt;&lt;br /&gt;
Now, let&#039;s look at the groups Publisher, Editor, and Author and see how their permissions are set.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:142--&amp;gt;&lt;br /&gt;
Authors only have Create and Edit Own permissions, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110112-07-&amp;lt;translate&amp;gt;&amp;lt;!--T:143--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:144--&amp;gt;&lt;br /&gt;
This means that Authors can create articles and can edit articles they have created. They may not delete articles, change the published state of articles, or edit articles created by others.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:145--&amp;gt;&lt;br /&gt;
Editors have the same permissions as Authors with the addition of permission for the Edit action, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110112-08-&amp;lt;translate&amp;gt;&amp;lt;!--T:146--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:147--&amp;gt;&lt;br /&gt;
So Editors can edit articles written by anyone.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:148--&amp;gt;&lt;br /&gt;
Publishers can do everything Editors can do plus they have permission for the Edit State action, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110112-09-&amp;lt;translate&amp;gt;&amp;lt;!--T:149--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:150--&amp;gt;&lt;br /&gt;
So Publishers can change the published state of an article. The possible states include Published, Unpublished, Archived, and Trashed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:151--&amp;gt;&lt;br /&gt;
All of these groups have Inherit permission for Configure and Access Component. Remember that Author is a child of the Registered group, and Registered does not have any default permissions except for Login. Since Registered does not have permission for Configure and Access Component, and since Author&#039;s permission for these actions is &amp;quot;Inherited&amp;quot;, then Author does not have these permissions either. This same permission is passed from Author to Editor and from Editor to Publisher. So, by default, none of these groups are allowed to work with articles in the Backend.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt;&lt;br /&gt;
It is important to remember that these permissions are only default settings for categories and articles and for any child groups that are created. So they can be overridden for child groups, for categories, and for specific articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:153--&amp;gt;&lt;br /&gt;
Also, note that there are no Denied permissions for any actions in the default settings. This allows you to add Allowed permissions at any level. Remember, once you have an action set for Denied, this action will be denied at all lower levels in the hierarchy. For example, if you set the Admin Login for Registered to Denied (instead of Allowed), you could not grant Publishers Allowed permissions for this action.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Article Manager and Actions Diagram === &amp;lt;!--T:154--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:155--&amp;gt;&lt;br /&gt;
The diagram below shows how each action in the permissions form relates to the various options on the Article Manager screen.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110111-16-&amp;lt;translate&amp;gt;&amp;lt;!--T:156--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:157--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Configure&#039;&#039;&#039; allows you to view and change the Options for the component.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:158--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Access Component&#039;&#039;&#039; allows you to navigate to the Article Manager. Without this permission, no other actions are possible.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:159--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Create&#039;&#039;&#039; allows you to add new articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:160--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Delete&#039;&#039;&#039; allows you to delete trashed articles. Note that the Delete icon only shows in the toolbar when you have the &amp;quot;Select State&amp;quot; filter set to &amp;quot;Trash.&amp;quot;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:161--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Edit&#039;&#039;&#039; allows you to edit existing articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:162--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Edit State&#039;&#039;&#039; allows to you Publish, Unpublish, Archive, or Trash articles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:163--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Edit Own&#039;&#039;&#039; is the same as Edit except that it only applies to articles written by you.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Allowing Guest-Only Access to Menu Items and Modules== &amp;lt;!--T:164--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:165--&amp;gt;&lt;br /&gt;
Version 1.6 introduced the ability to create a View Access Level that is only for guests of the site (meaning a User who is not logged in). The example below shows how you can set up this new feature.&lt;br /&gt;
&#039;&#039;(N.B. Steps 1 to 3 are not needed for Joomla! 3.x as they exist in the default install.)&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:166--&amp;gt;&lt;br /&gt;
#Create a new User group called Guest. Make it a child of the Public group as shown below.&amp;lt;/translate&amp;gt; [[Image:screenshot_acl_tutorial_20110112-01-&amp;lt;translate&amp;gt;&amp;lt;!--T:167--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:168--&amp;gt;&lt;br /&gt;
# Create a new access level called Guest and grant only the Guest group access to this level, as shown below.&amp;lt;/translate&amp;gt;[[Image:screenshot_acl_tutorial_20110112-02-&amp;lt;translate&amp;gt;&amp;lt;!--T:169--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:170--&amp;gt;&lt;br /&gt;
# Navigate to {{rarr|User Manager,Options,Component}} and change the Guest User Group from the default value of &amp;quot;Public&amp;quot; to &amp;quot;Guest&amp;quot;, as shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110112-04-&amp;lt;translate&amp;gt;&amp;lt;!--T:171--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:172--&amp;gt;&lt;br /&gt;
Now, if we assign a menu item, module, or other object to the Guest access level, only non-logged in Users will have access. For example, if we create a new menu item with access level of Guest, as shown below,&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:screenshot_acl_tutorial_20110112-05-&amp;lt;translate&amp;gt;&amp;lt;!--T:173--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:174--&amp;gt;&lt;br /&gt;
This menu item will only be visible to non-logged-in visitors to the site.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:175--&amp;gt;&lt;br /&gt;
If required other User groups like Author can be granted access in the Guest access level, this would allow Authors to view articles in the Frontend for editing.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:176--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;N.B. Login/logout in Frontend (&#039;&#039;for changing data in session&#039;&#039;) to see the change.&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Using Permission and Group Levels Together== &amp;lt;!--T:177--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:178--&amp;gt;&lt;br /&gt;
As discussed above, it is possible to define groups in a hierarchy, where each child group inherits action permissions (for example, the create permission) from its parent group. Action permissions are also be inherited from the permission level above. For example, a permission in the Article Manager is inherited from the same permission in the Global Configuration, and a permission in a child Category is inherited from the parent Category permission.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:179--&amp;gt;&lt;br /&gt;
This dual inheritance can be confusing, but it can also be useful. Let&#039;s consider an example as follows. We have a school with a group hierarchy of {{rarr|Teachers,History Teachers,Assistant History Teachers}}. We also have a category hierarchy of {{rarr|Assignments,History Assignments}}. We want History Teachers and Assistant History Teachers to have the following permissions:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:180--&amp;gt;&lt;br /&gt;
* both groups can create new articles only in the History Assignments category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:181--&amp;gt;&lt;br /&gt;
* only History Teachers (not Assistant History Teachers) can Publish or otherwise have Edit State permission.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:182--&amp;gt;&lt;br /&gt;
This ACL scheme is easy to implement. The diagram below shows how this would be set up for the Create Action.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Acl example diagram1 20091018-&amp;lt;translate&amp;gt;&amp;lt;!--T:183--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:184--&amp;gt;&lt;br /&gt;
In the diagram, the Permission Hierarchy is shown down the left side and the Group hierarchy is shown across the top. Permissions are inherited down and to the right, as shown by the arrows. To implement the desired permissions, we leave the Global Configuration blank (Not Set) for all three groups. Similarly, in the Article Manager and Assignments Category, we leave the Create permission to Inherit for all the groups. As shown in the diagram, this means that these groups do not have Create permission for articles in general or for articles in the Assignments group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:185--&amp;gt;&lt;br /&gt;
To sum up so far, we have not set any special permissions to get to this point. Now, in the History Assignments category permissions screen, we set the Create permission to Allow for the History Teachers group. This setting overrides the Soft (Implicit) Deny that we had by default and gives members of this group permission to create content (articles and child categories) for this category. This Allow setting also is inherited by the Assistant History Teachers group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:186--&amp;gt;&lt;br /&gt;
Next, we need to grant History Teachers the Edit State permission while denying this permission to Assistant History Teachers. This is done as shown in the diagram below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:Acl example diagram2 20091018-&amp;lt;translate&amp;gt;&amp;lt;!--T:187--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:188--&amp;gt;&lt;br /&gt;
This configuration is the same as the one above except that this time we set the Edit State permission in the History Assignments category to Deny for the Assistant History Teachers group. This means that Assistant History Teachers will not be able to Publish or Unpublish articles in this category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:189--&amp;gt;&lt;br /&gt;
Note that this was accomplished by setting just two permissions in the History Assignments category: Allow for the History Teachers group and Deny for the Assistant History Teachers group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==ACL Action Permission Examples== &amp;lt;!--T:190--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:281--&amp;gt;&lt;br /&gt;
Here are some examples of how you might set up the ACL for some specific situations.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Backend Article Administrator=== &amp;lt;!--T:191--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:192--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Problem&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:193--&amp;gt;&lt;br /&gt;
We want to create a group called &amp;quot;Article Administrator&amp;quot; with Backend permissions only for articles and not for any other Backend menu options. Members of this group should be able to use all of the features of the article manager, including setting article permissions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:194--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Solution&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:195--&amp;gt;&lt;br /&gt;
# Create a new group called Article Administrator and make its parent group Public, as shown below.&amp;lt;/translate&amp;gt;[[Image:screenshot_acl_tutorial_20110112-10-&amp;lt;translate&amp;gt;&amp;lt;!--T:196--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]] &amp;lt;translate&amp;gt;&amp;lt;!--T:197--&amp;gt;&lt;br /&gt;
Because its parent group is Public, it won&#039;t have any permissions by default.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:198--&amp;gt;&lt;br /&gt;
# In {{rarr|Users,Access Levels}}, edit the Special Access level to add the new group. That way they can get access to the Backend menu items and modules (This assumes that the modules for the admin menu and quick icons have the Special Access level assigned to them, which is the default.)&amp;lt;/translate&amp;gt; [[Image:screenshot_acl_tutorial_20110112-11-&amp;lt;translate&amp;gt;&amp;lt;!--T:199--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]] &amp;lt;translate&amp;gt;&amp;lt;!--T:200--&amp;gt;&lt;br /&gt;
By default, the Backend menu items and modules are set to Special access, so if you forget to add the new group to the Special access level, you won&#039;t see any modules or menu items when you log in as a User of the new group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:201--&amp;gt;&lt;br /&gt;
# In {{rarr|Site,Global Configuration,Permissions}}, click on the Article Administrator group and change the permissions to Allowed for the following actions: Admin Login, Create, Delete, Edit, Edit State, and Edit Own. The screen below shows what will show before you press Save.&amp;lt;/translate&amp;gt; [[Image:screenshot_acl_tutorial_20110112-12-&amp;lt;translate&amp;gt;&amp;lt;!--T:202--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&amp;lt;translate&amp;gt;&amp;lt;!--T:203--&amp;gt;&lt;br /&gt;
After you save, the Calculated Permissions should show as shown below.&amp;lt;/translate&amp;gt;[[Image:screenshot_acl_tutorial_20110112-13-&amp;lt;translate&amp;gt;&amp;lt;!--T:204--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&amp;lt;translate&amp;gt;&amp;lt;!--T:205--&amp;gt;&lt;br /&gt;
Note that the permission for the Access Component is Inherited, which translates to Not Allowed. This is important. This means that this group will only be able to access components if we give the group &amp;quot;Allowed&amp;quot; permission for Access Component. So we only have to change the one component we want to give them access to and don&#039;t have to change any settings for the components where we don&#039;t want them to have access. If we had a case where we wanted to give a group access to everything except for one component, we could set the default to Allowed and then set the one component to Denied. Also note that we did not give the group Site Login permission, so Users in this group will not be able to log into the Frontend. (If we wanted to allow that, we would just change the permission to Allowed for Site Login.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:206--&amp;gt;&lt;br /&gt;
# In {{rarr|Article Manager,Options,Permissions}}, change permissions to Allowed for this group for the Access Component action, as shown below.&amp;lt;/translate&amp;gt;[[Image:screenshot_acl_tutorial_20110112-14-&amp;lt;translate&amp;gt;&amp;lt;!--T:207--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&amp;lt;translate&amp;gt;&amp;lt;!--T:208--&amp;gt;&lt;br /&gt;
All of the other desired permissions are inherited.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:209--&amp;gt;&lt;br /&gt;
That&#039;s all you need to do. Members of this group can login to the Backend and do everything in Article Manager but can&#039;t do anything else in the Backend. For example, the screen below shows what a User in the Article Manager will see when they login to the Backend.&amp;lt;/translate&amp;gt;[[Image:screenshot_acl_tutorial_20110112-15-&amp;lt;translate&amp;gt;&amp;lt;!--T:210--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|center|frame]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==ACL View Access Levels Examples== &amp;lt;!--T:211--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:212--&amp;gt;&lt;br /&gt;
A basic concept of using Access Levels is that all items with the same Access will be viewable by the same group of Users. In other words, if two items have the same Access, you can&#039;t have one viewable by one User and not viewable by another User. On the other hand, it is easy to have one Group view any number of items with different Access levels.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:213--&amp;gt;&lt;br /&gt;
Similarly, each Group has exactly the same combination of Access levels, but one User can be a member of more than one group. Depending on the situation, you may want to have Users only in one Group or you may need to have a User in more than one Group.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:214--&amp;gt;&lt;br /&gt;
This means that we may need to group our items so that items so that all items in a group have the same level of sensitivity. Here are some examples.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Hierarchical Example=== &amp;lt;!--T:215--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:216--&amp;gt;&lt;br /&gt;
In this example, Access levels are hierarchical, for example, like government security clearance codes. Say for example we have the following sets of classified documents: Classified, Secret, and Top Secret. Users have corresponding clearance codes. Users with Classified clearance can only see Classified documents and cannot see Secret or Top Secret. Users with Secret clearance can see Classified and Secret documents but not Top Secret. Users with Top Secret can see all documents.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:217--&amp;gt;&lt;br /&gt;
In this case, you would create three Access levels: Classified, Secret, and Top Secret and the same three Groups. Users would only be members of one group, as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-spacing:0;&amp;quot;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:218--&amp;gt;&lt;br /&gt;
User&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:219--&amp;gt;&lt;br /&gt;
Group&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:220--&amp;gt;&lt;br /&gt;
Access Levels&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| C1, C2, C3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:221--&amp;gt;&lt;br /&gt;
Classified&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:222--&amp;gt;&lt;br /&gt;
Classified&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| S1, S2, S3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:223--&amp;gt;&lt;br /&gt;
Secret&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:224--&amp;gt;&lt;br /&gt;
Classified, Secret&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| TS1, TS2, TS3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:225--&amp;gt;&lt;br /&gt;
Top Secret&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:226--&amp;gt;&lt;br /&gt;
Classified, Secret, Top Secret&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:227--&amp;gt;&lt;br /&gt;
In this case, all Users are in exactly one group, but some groups have access to more than one Access Level of items. In other words, we have a one-to-one relationship between Users and groups, but a one-to-many relationship between Groups and Access Levels.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Team Security Example=== &amp;lt;!--T:228--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:229--&amp;gt;&lt;br /&gt;
Another possible use case is a set of non-hierarchical teams. Let&#039;s say we have three teams, T1, T2, and T3. Some Users are only on one team, but others might be on two or more teams. In this case, we could set up our Access Levels and Groups by team. Documents for each team have the access level for that team, and the Group for the team has only the one access level. When a User is on more than one team, they get added to the group for each team, as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-spacing:0;&amp;quot;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:230--&amp;gt;&lt;br /&gt;
User&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:231--&amp;gt;&lt;br /&gt;
Description&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:232--&amp;gt;&lt;br /&gt;
Group&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:233--&amp;gt;&lt;br /&gt;
Access Levels&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| U1&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:234--&amp;gt;&lt;br /&gt;
Team 1 member&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| T1&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| T1&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| U2&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:235--&amp;gt;&lt;br /&gt;
Team 2 member&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| T2&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| T2&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| U3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:236--&amp;gt;&lt;br /&gt;
Team 3 member&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| T3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| T3&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| U1-2&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:237--&amp;gt;&lt;br /&gt;
Member of teams 1 and 2&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| T1, T2&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| T1, T2&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| U1-3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:238--&amp;gt;&lt;br /&gt;
Member of teams 1 and 3&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| T1, T3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| T1, T3&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| U1-2-3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:239--&amp;gt;&lt;br /&gt;
Member of teams 1,2, and 3&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| T1,T2, T3&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| T1, T2, T3&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Hybrid Example=== &amp;lt;!--T:240--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:241--&amp;gt;&lt;br /&gt;
In a real-world situation, you might have a combination of these two arrangements. Say for example we have Managers and Staff. Staff can only see Staff documents and Managers can see Manager and Staff documents. Both types of Users can be assigned to teams as well, in which case they can see all of the documents for that team. In addition, say that Managers can access some, but not all, team documents. Staff can only access team documents if they are members of that team.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:242--&amp;gt;&lt;br /&gt;
In this example, we could set up the following Access Levels:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-spacing:0;&amp;quot;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:243--&amp;gt;&lt;br /&gt;
Access Level&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:244--&amp;gt;&lt;br /&gt;
Description&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:245--&amp;gt;&lt;br /&gt;
Groups&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:246--&amp;gt;&lt;br /&gt;
Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:247--&amp;gt;&lt;br /&gt;
Non-team manager documents&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:248--&amp;gt;&lt;br /&gt;
Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:249--&amp;gt;&lt;br /&gt;
Staff&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:250--&amp;gt;&lt;br /&gt;
Non-team staff documents&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:251--&amp;gt;&lt;br /&gt;
Manager, Staff&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:252--&amp;gt;&lt;br /&gt;
Team1&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:253--&amp;gt;&lt;br /&gt;
Sensitive Team1 documents (no access outside team)&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:254--&amp;gt;&lt;br /&gt;
Team1&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:255--&amp;gt;&lt;br /&gt;
Team1-Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:256--&amp;gt;&lt;br /&gt;
Team1 documents that can be accessed by all managers&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:257--&amp;gt;&lt;br /&gt;
Team1, Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:258--&amp;gt;&lt;br /&gt;
Team2&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:259--&amp;gt;&lt;br /&gt;
Sensitive Team2 documents (no access outside team)&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:260--&amp;gt;&lt;br /&gt;
Team2&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:261--&amp;gt;&lt;br /&gt;
Team2-Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:262--&amp;gt;&lt;br /&gt;
Team2 documents that can be accessed by all managers&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:263--&amp;gt;&lt;br /&gt;
Team2, Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:264--&amp;gt;&lt;br /&gt;
Then, Users could be assigned to groups as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| style=&amp;quot;border-spacing:0;&amp;quot;&lt;br /&gt;
| style=&amp;quot;border-top:0.0007in solid #000000;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:265--&amp;gt;&lt;br /&gt;
User Type&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:266--&amp;gt;&lt;br /&gt;
Group&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:267--&amp;gt;&lt;br /&gt;
Manager on no teams&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:268--&amp;gt;&lt;br /&gt;
Manager&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| Staff on no teams&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| Staff&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:269--&amp;gt;&lt;br /&gt;
Manager on team 1&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:270--&amp;gt;&lt;br /&gt;
Manager, Team1&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:271--&amp;gt;&lt;br /&gt;
Staff on team 1&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:272--&amp;gt;&lt;br /&gt;
Staff, Team1&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:273--&amp;gt;&lt;br /&gt;
Manager on teams 1 and 2&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:274--&amp;gt;&lt;br /&gt;
Manager, Team1, Team2&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:none;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:275--&amp;gt;&lt;br /&gt;
Staff on teams 1 and 2&amp;lt;/translate&amp;gt;&lt;br /&gt;
| style=&amp;quot;border-top:none;border-bottom:0.0007in solid #000000;border-left:0.0007in solid #000000;border-right:0.0007in solid #000000;padding:0.0382in;&amp;quot;| &amp;lt;translate&amp;gt;&amp;lt;!--T:276--&amp;gt;&lt;br /&gt;
Staff, Team1, Team2&amp;lt;/translate&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:277--&amp;gt;&lt;br /&gt;
[[Category:Joomla! 1.6]]&lt;br /&gt;
[[Category:Joomla! 2.5]]&lt;br /&gt;
[[Category:Joomla! 3.x]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
[[Category:Access Control]]&lt;br /&gt;
[[Category:Access Management]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Git_for_Coders&amp;diff=1009426</id>
		<title>Git for Coders</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Git_for_Coders&amp;diff=1009426"/>
		<updated>2023-07-10T15:01:05Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup changes. URL changes. Capitalization and spelling corrections.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Overview=&lt;br /&gt;
This article shows you how to use Git and GitHub to code and submit changes to the Joomla CMS. If you are not familiar with Git, you may wish to read the tutorial [[Git_for_Testers_and_Trackers | Git for Testers and Trackers]] first. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;IMPORTANT NOTE: Git is a very powerful system and there is usually more than one way to accomplish the same thing in Git. This tutorial does not try to cover all of the different ways you could do these tasks. Instead, it covers one (hopefully simple) way to do it. As you become more familiar with Git, you may find other ways that work better for you.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The first step is to set up the remote and local Git repositories. You do this once. Once it is set up, the normal workflow is:&lt;br /&gt;
# Update your local and remote repositories with changes others have committed to the main Joomla CMS repository.&lt;br /&gt;
# Create a branch for each issue or feature you are working on and commit your changes to the branch in your local repository.&lt;br /&gt;
# Update your remote repository on GitHub with your branches.&lt;br /&gt;
# Create a pull request from your GitHub branch. Alternatively, you can create a patch or diff file from your local branch and post that to the tracker.&lt;br /&gt;
# Update the Joomla Issue tracker or Joomla Feature tracker so that others can test your code.&lt;br /&gt;
&lt;br /&gt;
Each of these steps is explained below. Note that you can use Git from the command line, from an IDE such as Eclipse (with the eGit plugin), or from a stand-alone tool, such as TortoiseGit. Here we will use the command line and, where applicable, show the equivalent command in Eclipse eGit.&lt;br /&gt;
&lt;br /&gt;
NOTE: If you want to propose a simple code change, you can do it directly from GitHub.com, without setting up anything on your local PC. See [[Using_the_Github_UI_to_Make_Pull_Requests|Using the GitHub UI to Make Pull Requests]].&lt;br /&gt;
&lt;br /&gt;
=Setup=&lt;br /&gt;
== GitHub Work Flow for Joomla! ==&lt;br /&gt;
&lt;br /&gt;
[[File:Github work flow joomla.png]]&lt;br /&gt;
&lt;br /&gt;
== Create Your Forked Repository on GitHub==&lt;br /&gt;
GitHub allows you to create your own copy of any public repository, including the Joomla CMS. This is your personal copy of the repository and is called a &amp;quot;fork&amp;quot;. To create a fork of the Joomla CMS:&lt;br /&gt;
# If you haven&#039;t already, register on GitHub.com and log in.&lt;br /&gt;
# Navigate to [https://github.com/joomla/joomla-cms https://github.com/joomla/joomla-cms]&lt;br /&gt;
# Click on the Fork button in the upper right part of the screen.&lt;br /&gt;
&lt;br /&gt;
Note that you can only create one fork of any given repository. However, as we will see, you can create as many branches (versions) of your repository as you like.&lt;br /&gt;
&lt;br /&gt;
== Clone Your GitHub Repository To Your PC ==&lt;br /&gt;
At this point, you have your own repository on GitHub.com. Now you need to create a local repository that is a copy (called a &amp;quot;clone&amp;quot;) of the GitHub repository. To do this:&lt;br /&gt;
===CLI (command line) Commands===&lt;br /&gt;
# Change directory to the directory where you want the Joomla files to be stored (for example, &amp;lt;code&amp;gt;C:\xampp\htdocs\joomla\my-project&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;/opt/lampp/htdocs/joomla/my-project&amp;lt;/code&amp;gt;).&lt;br /&gt;
# Enter the command: &amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/&amp;lt;your GitHub user name&amp;gt;/joomla-cms.git&amp;lt;/nowiki&amp;gt; .&amp;lt;/code&amp;gt; For example, if your GitHub user name is &amp;quot;joomla-coder&amp;quot;, the command would be: &amp;lt;code&amp;gt;git clone &amp;lt;nowiki&amp;gt;https://github.com/joomla-coder/joomla-cms.git&amp;lt;/nowiki&amp;gt;  .&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
You can get the URL for the command above from your repository at GitHub.com as shown below. [[File:git-coders-tutorial-20121009-03.png|frame|none]]&lt;br /&gt;
&lt;br /&gt;
Note that the &amp;quot;.&amp;quot; dot just tells Git to put the new repository in the current directory. The system will work for a few minutes while it downloads all of the files. When it is finished, you will have a complete set of Joomla files under version control in the current directory.&lt;br /&gt;
&lt;br /&gt;
=== Eclipse Commands ===&lt;br /&gt;
# If you like, you can get the URL from GitHub as shown below. [[File:git-coders-tutorial-20121009-03.png|frame|none]] You will use this later on.&lt;br /&gt;
# In Eclipse, open the Git Repositories view and click the button called &amp;quot;Clone a Git Repository and add the clone to this view&amp;quot; as shown below. [[File:git-coders-tutorial-20121009-01.png|frame|none]]&lt;br /&gt;
# The window below will show. [[File:git-coders-tutorial-20121009-02.png|frame|none]] Select URI and click Next.&lt;br /&gt;
# The window below will show. [[File:git-coders-tutorial-20121009-04.png|frame|none]] Enter the GitHub URL for your repository (from step (1) above). Enter your GitHub user name and password and check the box called &amp;quot;Store in Secure Store&amp;quot;. &lt;br /&gt;
# Click Next and the window below will show. [[File:git-coders-tutorial-20121009-05.png|frame|none]]&lt;br /&gt;
# Click Next to select all branches. The window below will show. [[File:git-coders-tutorial-20121009-06.png|frame|none]]&lt;br /&gt;
# In Directory, enter the folder where you want the Joomla files to be copied. Keep the default values for Initial branch (&amp;quot;master&amp;quot;) and Remote name (&amp;quot;origin&amp;quot;) as shown.&lt;br /&gt;
# Click Finish. The system will work for a few minutes. When it finishes you will have a clone of the remote repository.&lt;br /&gt;
&lt;br /&gt;
== Create an Upstream Remote==&lt;br /&gt;
Now we have our local repository. This has a remote called &amp;quot;origin&amp;quot; that points to our personal fork of Joomla on GitHub. &lt;br /&gt;
&lt;br /&gt;
In a project like Joomla, many users are submitting bug fixes and features. These changes are committed to the main Joomla CMS repository frequently. It is up to each coder to keep their personal repositories up to date with these changes. Fortunately, as we will see, this is easy to do.&lt;br /&gt;
&lt;br /&gt;
The last step in the setup is to create a second remote called &amp;quot;upstream&amp;quot; that points to the main Joomla CMS repository. We will use this remote to pull changes that others make to the main Joomla repository so we can keep our personal repositories up to date.&lt;br /&gt;
&lt;br /&gt;
===CLI Command ===&lt;br /&gt;
To create a remote called &amp;quot;upstream&amp;quot; that points to the main CMS repository, enter this command: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git remote add upstream &amp;lt;nowiki&amp;gt;https://github.com/joomla/joomla-cms.git&amp;lt;/nowiki&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note, if you get a error like &amp;quot;fatal: Not a git repository (or any of the parent directories): .git&amp;quot;, then make sure you&#039;ve changed directory to the new repository that&#039;s been created within the current directory (so one level lower).&lt;br /&gt;
&lt;br /&gt;
===Eclipse Command===&lt;br /&gt;
&#039;&#039;Unknown at this time.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
At this point, you have your personal remote repository (created by &amp;quot;forking&amp;quot; the Joomla CMS project) and your personal local repository (created with CLI or Eclipse). Now you are ready to code patches and features.&lt;br /&gt;
&lt;br /&gt;
=Normal Workflow=&lt;br /&gt;
Now that we have done our one-time setup, we are ready to start our normal workflow. This is outlined below.&lt;br /&gt;
&lt;br /&gt;
== Create a New Feature or Bug Fix Change==&lt;br /&gt;
Let&#039;s say you are ready to start working on a new bug fix or a new feature. Here are the steps you would normally follow.&lt;br /&gt;
# Update your master branches. Update the master branch of your local and GitHub repositories with the latest CMS changes.&lt;br /&gt;
# Create a branch for writing the new code&lt;br /&gt;
# In the new branch, code the changes and commit them. Depending on the length of time, you can make multiple commits to the branch.&lt;br /&gt;
# When you are ready to propose your code for testing (or when you want others to be able to see it), push the branch to your GitHub repository.&lt;br /&gt;
# When you are ready to submit the code, either:&lt;br /&gt;
## Create a pull request on GitHub, or&lt;br /&gt;
## Create a patch or diff file and post to the Joomlacode tracker.&lt;br /&gt;
&lt;br /&gt;
Each of these steps is explained in more detail below.&lt;br /&gt;
&lt;br /&gt;
=== Update Your Master Branches ===&lt;br /&gt;
You need to keep your repositories up to date with changes made by others in the main CMS repository. It&#039;s easy to do, and here are the steps. These are done more easily with the CLI than with Eclipse.&lt;br /&gt;
&lt;br /&gt;
IMPORTANT NOTE: Make sure you never commit your own code changes to the master branch. If you do, you won&#039;t be able to keep it synchronized with the master branch on the main CMS repository.&lt;br /&gt;
&lt;br /&gt;
====CLI Commands====&lt;br /&gt;
* Make sure you are in your master branch of your local repository (&amp;lt;code&amp;gt;git checkout master&amp;lt;/code&amp;gt;). If you aren&#039;t sure, you can use the command &amp;lt;code&amp;gt;git status&amp;lt;/code&amp;gt; to see what branch you are on.&lt;br /&gt;
* Enter the command: &amp;lt;code&amp;gt;git pull upstream master&amp;lt;/code&amp;gt;. You should get a message showing the changes, similar to this:&lt;br /&gt;
 $ git pull upstream master&lt;br /&gt;
 From &amp;lt;nowiki&amp;gt;https://github.com/joomla/joomla-cms&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  * branch            master     -&amp;gt; FETCH_HEAD&lt;br /&gt;
 Updating 76feee8..294c62c&lt;br /&gt;
 Fast-forward&lt;br /&gt;
  installation/CHANGELOG                |    3 +++&lt;br /&gt;
  installation/language/fr-FR/fr-FR.ini |    2 +-&lt;br /&gt;
  2 files changed, 4 insertions(+), 1 deletion(-)&lt;br /&gt;
 Mark@MARK2009 /c/xampp/htdocs/joomla-coder/joomla-cms (master)&lt;br /&gt;
:If your local repository was already up to date, you will get a message like this:&lt;br /&gt;
 $ git pull upstream master&lt;br /&gt;
 From &amp;lt;nowiki&amp;gt;https://github.com/joomla/joomla-cms&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
  * branch            master     -&amp;gt; FETCH_HEAD&lt;br /&gt;
 Already up-to-date.&lt;br /&gt;
&lt;br /&gt;
* At this point, your local master branch is up to date with the main CMS repository. Now you need to update the master branch of your GitHub repository. Enter the command: &amp;lt;code&amp;gt;git push origin master&amp;lt;/code&amp;gt;. You should see a message like this:&lt;br /&gt;
 $ git push origin master&lt;br /&gt;
 To &amp;lt;nowiki&amp;gt;https://github.com/joomla-coder/joomla-cms.git&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
    76feee8..294c62c  master -&amp;gt; master&lt;br /&gt;
&lt;br /&gt;
NOTE: If you haven&#039;t stored your user name and password, you will be prompted for them after you enter the push command. See below for how to store your credentials so you don&#039;t have to type them each time.&lt;br /&gt;
&lt;br /&gt;
At this point, your master branches on your local and GitHub repositories are up to date with the main CMS repository. Now, when you create a new branch, it will start at this point and be based on the latest code.&lt;br /&gt;
&lt;br /&gt;
===Create a Branch for the Code===&lt;br /&gt;
In Git, the best practice is to use a branch for each bug fix or feature. (In fact, experienced Git users will often create more than one branch for an individual project, perhaps trying different approaches to the problem.) It is super easy to create, delete, and even combine branches. Use a naming convention that allows you to keep track. For example, you could incorporate the tracker issue number into the branch name (for example, &amp;quot;php-notice-12345&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
When you create a new branch, it starts from the branch you are currently on. For this reason, you will normally want to make sure you are in your master branch when creating a new one.&lt;br /&gt;
&lt;br /&gt;
====CLI Commands====&lt;br /&gt;
&amp;lt;code&amp;gt;git branch xxx&amp;lt;/code&amp;gt; where &amp;quot;xxx&amp;quot; is the new branch name. Note: If you already have a branch you are working on, use the command: &amp;lt;code&amp;gt;git checkout xxx&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
====Eclipse Commands====&lt;br /&gt;
#Left-click on the PHP project and select Team&amp;amp;rarr;Switch To&amp;amp;rarr;New Branch as shown below. [[File:Git-coders-tutorial-20121009-07.png|frame|none]]. The screen below will show. [[File:Git-coders-tutorial-20121009-08.png|frame|none]]&lt;br /&gt;
#Fill in the name of the new branch and click finish. &lt;br /&gt;
&lt;br /&gt;
===Code and Commit to the Branch===&lt;br /&gt;
Finally, we are to the fun part! Here we are actually coding and testing our feature or bug fix. The normal workflow is as follows:&lt;br /&gt;
# Do some coding.&lt;br /&gt;
# Commit your work to your branch.&lt;br /&gt;
# Repeat until you are done.&lt;br /&gt;
&lt;br /&gt;
Here are the commands to commit your work to your branch. Make sure you are in the right branch before committing! (Use &amp;lt;code&amp;gt;git status&amp;lt;/code&amp;gt; to check.)&lt;br /&gt;
&lt;br /&gt;
====CLI Commands====&lt;br /&gt;
* To commit all of the changes since the last commit: &amp;lt;code&amp;gt;git commit -m &amp;quot;My commit message&amp;quot; -a&amp;lt;/code&amp;gt;&lt;br /&gt;
* To undo any file changes since the last commit: &amp;lt;code&amp;gt;git reset --hard&amp;lt;/code&amp;gt;&lt;br /&gt;
* To remove any added files and folder since the last commit: &amp;lt;code&amp;gt;git clean -d -f&amp;lt;/code&amp;gt;&lt;br /&gt;
* To change the last commit: &amp;lt;code&amp;gt;git commit --amend&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Eclipse Commands====&lt;br /&gt;
* To commit all changes, right-click on project, select Team&amp;amp;rarr;Commit to show this window. [[File:Git-coders-tutorial-20121009-09.png|frame|none]]&lt;br /&gt;
* To undo any file changes since the last commit, select Team&amp;amp;rarr;Reset and check the Hard Reset Type as shown below. [[File:Git-coders-tutorial-20121009-10.png|frame|none]]&lt;br /&gt;
* To change the last commit, select Team&amp;amp;rarr;Commit and check the Amend Previous Commit button (as shown in the Commit Changes screenshot above).&lt;br /&gt;
&lt;br /&gt;
===Push Branch to GitHub===&lt;br /&gt;
In the previous workflow, we created the branch and committed changes to our local repository. If we want others to be able to see the branch or to create a pull request, we need to push the branch to our personal repository on GitHub.&lt;br /&gt;
&lt;br /&gt;
====CLI Command====&lt;br /&gt;
To push a branch to your personal GitHub repository: &amp;lt;code&amp;gt;git push origin xxx&amp;lt;/code&amp;gt; (where &amp;quot;xxx&amp;quot; is the name of your branch).&lt;br /&gt;
&lt;br /&gt;
===Submit Pull Request or Patch File===&lt;br /&gt;
There are two ways you can submit a proposed code change to the Joomla CMS project. One is to submit a pull request via GitHub, the other is to create a patch or diff file. In general, pull requests are preferred for very large changes, whereas both work fine for smaller changes.&lt;br /&gt;
&lt;br /&gt;
====Create a Pull Request====&lt;br /&gt;
# Navigate to your personal GitHub repository.&lt;br /&gt;
# Select the branch that has the changes for the pull request as shown below. [[File:Git-coders-tutorial-20121009-11.png|frame|none]]&lt;br /&gt;
# Click the Pull Request button on the top of the screen. The screen will show as below. [[File:Git-coders-tutorial-20121009-12.png|frame|none]]&lt;br /&gt;
# The left side shows the base repository and base branch. This will normally be the master branch of the &amp;quot;joomla/joomla-cms&amp;quot; repository. The right side shows the head repository and branch. This will normally be your repository and the branch that has the desired code changes. If you like you can change the commit message and enter in a comment describing this pull request.&lt;br /&gt;
# You can review the pull request using the tabs across the top. Clicking the Commits tab shows the commit history for the branch, as shown below.[[File:Git-coders-tutorial-20121009-13.png|frame|none]]&lt;br /&gt;
# Clicking the Files Changed tab shows all of the changes made in this branch, as shown here. [[File:Git-coders-tutorial-20121009-14.png|frame|none]]&lt;br /&gt;
# When you are ready to submit the pull request, click the Send Pull Request button at the bottom right of the screen. GitHub will process the request and then display it as shown below. [[File:Git-coders-tutorial-20121009-15.png|frame|none]]&lt;br /&gt;
# At this point, you should update the Joomlacode tracker. For example, if this code is a fix for a Confirmed issue, you should change the issue status to Pending and add a comment with a link to the pull request (for example, &amp;lt;nowiki&amp;gt;https://github.com/joomla/joomla-cms/pull/494&amp;lt;/nowiki&amp;gt;). Also, make sure there are good test instructions so people can test the proposed code.&lt;br /&gt;
&lt;br /&gt;
====Create a Patch File====&lt;br /&gt;
It is not necessary to create a pull request to submit code changes to Joomla. Another alternative is to create a patch file. This can be done on your local system from the command line as follows:&lt;br /&gt;
# In your local system, change to the desired branch.&lt;br /&gt;
# Enter the command: &amp;lt;code&amp;gt;git diff master &amp;gt; my-new-patch.patch&amp;lt;/code&amp;gt;&lt;br /&gt;
This will create a patch file in that same folder. (Note that you may want to have Git automatically ignore all patch files. See the section called Git Tips below.) Upload that file to the Joomlacode tracker and add a comment and change the issue status as needed. &lt;br /&gt;
To include changes to binary files in the diff add the &amp;lt;code&amp;gt;--binary&amp;lt;/code&amp;gt; option to the command line as follows:&lt;br /&gt;
# Enter the command: &amp;lt;code&amp;gt;git diff --binary master &amp;gt; my-new-patch.patch&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that this method does not require you to push your local branches to GitHub.&lt;br /&gt;
&lt;br /&gt;
== Keep Your Repositories Up to Date==&lt;br /&gt;
As discussed earlier, the main CMS repository on GitHub is being changed frequently. It is possible that one or more of these changes could conflict with (or otherwise affect) our work. For this reason, it is very important that we keep our repositories up to date. Otherwise, our patch files and pull requests may not work. As discussed earlier, the way we will do this is by keeping our master branch synchronized with the main CMS repository and then using that to update our working branches.&lt;br /&gt;
&lt;br /&gt;
In this tutorial we are using the git merge command. The merge command merges the changes from a different branch into the current branch. Here we use the merge to merge changes from the master branch into our working branch. For example, say we created a branch (my-branch) on day 1. On day 2, someone does 5 commits to the master branch in the main CMS repository. Now, on day 3 we want to update our branch to be current with these 5 commits. The merge command tries to do this automatically. It looks to see what was changed in the master branch since our last merge and applies those same changes to our current branch (&amp;quot;my-branch&amp;quot;). This will work automatically unless we have made changes that conflict with changes made in the same files in the main repository. In that case, we need to resolve these conflicts before we can finish updating our branch.&lt;br /&gt;
&lt;br /&gt;
To update a working branch with changes to the main CMS repository, follow these steps.&lt;br /&gt;
# Update your local master branch.&lt;br /&gt;
#* Make sure you are on the master branch in your local repository: &amp;lt;code&amp;gt;git checkout master&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Pull changes from the main CMS repository: &amp;lt;code&amp;gt;git pull upstream master&amp;lt;/code&amp;gt;&lt;br /&gt;
#* Push those changes to your Github repository: &amp;lt;code&amp;gt;git push origin master&amp;lt;/code&amp;gt;&lt;br /&gt;
# Now your local master branch is up to date. Next, change to your working branch: &amp;lt;code&amp;gt;git checkout my-branch&amp;lt;/code&amp;gt;&lt;br /&gt;
# Make sure your remote repository &amp;quot;my-branch&amp;quot; is up to date with your local repository. Use the command: &amp;lt;code&amp;gt;git push origin my-branch&amp;lt;/code&amp;gt;. If the remote repository was already up to date, no harm is done. You will just get a message saying it was already up to date.&lt;br /&gt;
# Finally, merge the new changes to the master branch with your working branch. The command is as follows: &amp;lt;code&amp;gt;git merge master&amp;lt;/code&amp;gt;&lt;br /&gt;
# The system will work for a short time and then indicate whether or not the merge was successful. If you don&#039;t have any changes that conflict with changes from the main CMS repository, the merge will be successful. If one or more of your changes conflicts with the changes that were made in the main repository, any affected files will be flagged as being in conflict. See the Fixing Conflicts section below for more information about this.&lt;br /&gt;
&lt;br /&gt;
You can also use Eclipse for the merge by changing to the working branch and selecting Team&amp;amp;rarr;Merge&amp;amp;rarr;. This will show the following screen. [[File:Git-coders-tutorial-20121027-01.png|frame|none]] Select Local-&amp;gt;master as shown above and click Merge.&lt;br /&gt;
&lt;br /&gt;
== Fixing Conflicts ==&lt;br /&gt;
A conflict occurs during a merge (or rebase) if the same file has been changed in the local branch and in the master branch in a way that conflicts. If this happens, the file is flagged as being in conflict and the merge process is suspended. To complete the process, you need to:&lt;br /&gt;
# Manually edit each of the flagged. You will see the changes from your branch and the changes from the main repository highlighted in the file. You need to figure out what should be in the file.&lt;br /&gt;
# Once you have edited each flagged file, enter the command &amp;lt;code&amp;gt;git add xxx&amp;lt;/code&amp;gt; where &amp;quot;xxx&amp;quot; is the name of the flagged file.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s look at a simple example. Here we have added a line of code to a file in our branch and someone has added a different line to the same file in the master branch. When we do the merge command, we get the following message.&lt;br /&gt;
&lt;br /&gt;
 $ git merge master&lt;br /&gt;
 Removing administrator/templates/hathor/html/mod_submenu/default.php&lt;br /&gt;
 Auto-merging administrator/components/com_admin/script.php&lt;br /&gt;
 CONFLICT (content): Merge conflict in administrator/components/com_admin/script&lt;br /&gt;
 php&lt;br /&gt;
 Automatic merge failed; fix conflicts and then commit the result.&lt;br /&gt;
&lt;br /&gt;
So this tells us we have a conflict in the file &amp;lt;code&amp;gt;administrator/components/com_admin/script.php&amp;lt;/code&amp;gt;. If we look at this file in our text editor, we see the following: [[File:Git-coders-tutorial-20121009-17.png|frame|none]] The line under &amp;quot;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; HEAD&amp;quot; is from the master branch of the main repository. The line after the &amp;quot;=======&amp;quot; is from our working branch.&lt;br /&gt;
&lt;br /&gt;
At this point, we need to correct the file and remove the &amp;quot;marker&amp;quot; lines. Then we do the command &amp;lt;code&amp;gt;git add administrator/components/com_admin/script.php&amp;lt;/code&amp;gt; to tell Git that the conflict is resolved.&lt;br /&gt;
&lt;br /&gt;
Finally, we do the command &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git commit -a&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
to finish the merge. This commits all of the changes that were applied automatically by the merge as well as the changes we have done manually in fixing the conflicts.&lt;br /&gt;
&lt;br /&gt;
If we want to abandon the merge instead of fixing the conflicts, we can use the following commands to reset our branch back to its state before the merge:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git reset --hard&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;git clean -f -d&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Using Eclipse For Conflicts===&lt;br /&gt;
Eclipse is very handy for resolving commits. When you do the command Team&amp;amp;rarr;Merge and there is a conflict, you get the following window. [[File:Git-coders-tutorial-20121027-02.png|frame|none]] You will also see a red square annotation in the PHP Explorer window next to each file with a conflict.&lt;br /&gt;
&lt;br /&gt;
To see all of the files in conflict you can use the Merge Tool. Right click on the PHP project and select {{rarr|Team,Merge Tool}}. You will see the following option. [[File:Git-coders-tutorial-20121009-20.png|frame|none]]&lt;br /&gt;
&lt;br /&gt;
This gives you the option of having Git put in the changes from both sources in the file or letting you compare the changes side by side. If you select Use HEAD version you get a file compare similar to the following. [[File:Git-coders-tutorial-20121009-21.png|frame|none]]&lt;br /&gt;
&lt;br /&gt;
The left shows the change from the master branch, and the right shows the change from your working branch. At this point, you can either edit the file in the left side (for example, by pulling in the change from the right side) or you can just manually edit the file in conflict. &lt;br /&gt;
&lt;br /&gt;
Once the file has been fixed, select the file (either by right-clicking in the PHP Explorer view or in the editor) and select {{rarr|Team,Add}} to Index as shown below. [[File:Git-coders-tutorial-20121009-22.png|frame|none]]When you do this, the red square annotation will disappear. &lt;br /&gt;
&lt;br /&gt;
Once all the conflicts are resolved, you can finish the merge by right-clicking on the project and selecting {{rarr|Team,Commit}}. The normal commit screen will show as follows. [[File:Git-coders-tutorial-20121027-03.png|frame|none]] Notice that the files that were in conflict are automatically added to the commit message. Edit the commit message as desired and click the Commit button. At this point, the merge is complete.&lt;br /&gt;
&lt;br /&gt;
== Saving Your User Name and Password ==&lt;br /&gt;
When you push changes to GitHub, it must authenticate you based on your GitHub user name and password. Normally, the system will simply prompt you for your user name and password each time you do a push. &lt;br /&gt;
&lt;br /&gt;
There are a number of ways you can save your credentials so you don&#039;t have to enter them each time. One very simple method is to use the git &amp;quot;store&amp;quot; feature. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;IMPORTANT NOTE: This feature stores your password in plain text on your local computer. If this is not acceptable, do not use this method.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
If it is OK to store your credentials on your PC, at the command line enter the command: &amp;lt;code&amp;gt;git config --global credential.helper store&amp;lt;/code&amp;gt; This tells Git to store your credentials in a file called .git-credentials in your home folder (&amp;quot;for example, C:\users\user-name&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
The next time you do a push and enter your credentials, they will be stored in that file. After that, you will not need to enter them. Git will use them automatically.&lt;br /&gt;
&lt;br /&gt;
If you want to change your password, simple delete the file and then change your password on GitHub. The next time you enter your credentials, the new password will be saved.&lt;br /&gt;
&lt;br /&gt;
== Git Tips ==&lt;br /&gt;
&lt;br /&gt;
=== Ignoring Files ===&lt;br /&gt;
Sometimes you don&#039;t want to track all the files in a folder, specially some system files that the operating system generates. One way to have Git ignore files is to use the &#039;&#039;.gitignore&#039;&#039; file. &lt;br /&gt;
&lt;br /&gt;
If you create a file in your repository named &#039;&#039;.gitignore&#039;&#039;, Git uses it to determine which files and directories to ignore, before you make a commit.&lt;br /&gt;
&lt;br /&gt;
A &#039;&#039;.gitignore&#039;&#039; file should be committed into your repository, in order to share the ignore rules with any other users that clone the repository.&lt;br /&gt;
&lt;br /&gt;
Read more about &#039;&#039;.gitignore&#039;&#039; at:&lt;br /&gt;
* https://git-scm.com/docs/gitignore&lt;br /&gt;
* https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files&lt;br /&gt;
&lt;br /&gt;
Here is an example of a file.&lt;br /&gt;
&lt;br /&gt;
 # OSX&lt;br /&gt;
 .DS_Store&lt;br /&gt;
 ._*&lt;br /&gt;
 .Spotlight-V100&lt;br /&gt;
 .Trashes&lt;br /&gt;
  &lt;br /&gt;
 # Windows&lt;br /&gt;
 Thumbs.db&lt;br /&gt;
 Desktop.ini&lt;br /&gt;
  &lt;br /&gt;
 # PHPStorm&lt;br /&gt;
 .idea/&lt;br /&gt;
 &lt;br /&gt;
 # Sublime Text&lt;br /&gt;
 *.sublime*&lt;br /&gt;
 sftp-config.json&lt;br /&gt;
  &lt;br /&gt;
 # Eclipse&lt;br /&gt;
 .buildpath&lt;br /&gt;
 .project&lt;br /&gt;
 .settings&lt;br /&gt;
  &lt;br /&gt;
 # Netbeans (custom)&lt;br /&gt;
 .netbeans/*&lt;br /&gt;
 /nbproject/*&lt;br /&gt;
  &lt;br /&gt;
 # Temp files&lt;br /&gt;
 *.tmp&lt;br /&gt;
 *.bak&lt;br /&gt;
 *.swp&lt;br /&gt;
 *~.nib&lt;br /&gt;
 *~&lt;br /&gt;
  &lt;br /&gt;
 # Phing build script&lt;br /&gt;
 build.properties&lt;br /&gt;
  &lt;br /&gt;
 # Packages #&lt;br /&gt;
 *.zip&lt;br /&gt;
 *.tar.*&lt;br /&gt;
  &lt;br /&gt;
 # Composer&lt;br /&gt;
 composer.lock&lt;br /&gt;
 /vendor&lt;br /&gt;
  &lt;br /&gt;
 # Test related files&lt;br /&gt;
 /tests/system/servers/configdef.php&lt;br /&gt;
 /tests/system/webdriver/tests/logs/&lt;br /&gt;
 /tests/acceptance.suite.yml&lt;br /&gt;
 codecept.phar&lt;br /&gt;
  &lt;br /&gt;
 # Never ignore&lt;br /&gt;
 !.gitignore&lt;br /&gt;
 !index.html&lt;br /&gt;
 !index.php &lt;br /&gt;
&lt;br /&gt;
As you can see from the example, we can exclude specific folders and file names.&lt;br /&gt;
&lt;br /&gt;
Once you have this file created, Git will ignore any of these files.&lt;br /&gt;
&lt;br /&gt;
[[Category:Bug Squad]]&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:GitHub]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla!_patches_QuickReferenceGuide&amp;diff=1009425</id>
		<title>Testing Joomla! patches QuickReferenceGuide</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Joomla!_patches_QuickReferenceGuide&amp;diff=1009425"/>
		<updated>2023-07-10T14:40:38Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected a URL. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
The [[S:MyLanguage/Testing Joomla! patches|Testing Joomla! patches]] page describes the patch testing procedure. This document is a Quick Reference Guide with all necessary steps.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Joomla Issue Tracker === &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
* https://issues.joomla.org/&lt;br /&gt;
* Login with Github account -&amp;gt; no account? https://github.com/&lt;br /&gt;
* Status: {{rarr|New,Confirmed,Pending,Ready to Commit (RTC),Closed}}&lt;br /&gt;
** &#039;&#039;&#039;New&#039;&#039;&#039; - Just reported&lt;br /&gt;
** &#039;&#039;&#039;Confirmed&#039;&#039;&#039; - Someone reproduced and confirmed error&lt;br /&gt;
** &#039;&#039;&#039;Pending&#039;&#039;&#039; - Patch available (“PR” - pull request); needs two successful tests&lt;br /&gt;
** &#039;&#039;&#039;Ready To Commit&#039;&#039;&#039; - To be added to Joomla source code&lt;br /&gt;
** Needs Review - Need experienced developer to review the issue&lt;br /&gt;
** Information Required - Need more info from the person who reported the issue&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Testing Bugs, Reports, Patches=== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
* Have working local web server environment (XAMPP, MAMP ect)&lt;br /&gt;
* Get Joomla “staging” from: https://github.com/joomla/joomla-cms  &lt;br /&gt;
** Download, unzip to folder&lt;br /&gt;
** or: git clone https://github.com/joomla/joomla-cms.git &lt;br /&gt;
* Install Joomla at local web server&lt;br /&gt;
** Install with: Test English (GB) sample data&lt;br /&gt;
** Do &#039;&#039;&#039;not remove&#039;&#039;&#039; /installation/ folder!&lt;br /&gt;
* Joomla Patch Tester Component &lt;br /&gt;
** Download from: https://github.com/joomla-extensions/patchtester/releases &lt;br /&gt;
** Installation via Extensions &amp;gt; Install &lt;br /&gt;
** Add your own Github account details under Options (Username + Password)&lt;br /&gt;
* Testing found issues&lt;br /&gt;
** Find issue in Joomla Issue Tracker (useful filters: status, category, tests, easy)&lt;br /&gt;
** Reproduce bug (can&#039;t reproduce bug? → report)&lt;br /&gt;
** Install Patch in Joomla Patch Tester Component. patch: [#ID of patch – Some descriptive title for problem/patch]&lt;br /&gt;
** Test if bug is solved &amp;amp; report findings (use @test for successful test)&lt;br /&gt;
** Remove Patch (“revert patch”)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Report Bug=== &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
* Search in Issue Tracker if issue has been reported already&lt;br /&gt;
* Create new item [New Item]&lt;br /&gt;
** Title: use descriptive title!&lt;br /&gt;
** Description:&lt;br /&gt;
*** Steps to reproduce the issue &lt;br /&gt;
*** Expected result &amp;amp; actual result&lt;br /&gt;
*** System information (as much as possible). e.g. your PHP information, browser + version&lt;br /&gt;
*** Additional comments &lt;br /&gt;
** Priority: default: Medium&lt;br /&gt;
** Build: 3.4.x-dev (at this moment)&lt;br /&gt;
** Categories: select the most appropriate categories&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Create Patch=== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
Patch = text file that describes changes in source code.&lt;br /&gt;
&amp;lt;/translate&amp;gt;	&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Methods:&lt;br /&gt;
* Use IDE (like Netbeans, PHPStorm)&lt;br /&gt;
** Improve Joomla code in editor &amp;amp; create &#039;&#039;.diff&#039;&#039; patch&lt;br /&gt;
* Use Github: https://github.com/joomla/joomla-cms &lt;br /&gt;
** Navigate to page with code&lt;br /&gt;
** Click “pencil” icon: “Clicking this button will fork this project so you can edit the file”&lt;br /&gt;
** Add improvements:&lt;br /&gt;
*** Make changes in code under “Edit file”&lt;br /&gt;
*** Add Commit Summary under Propose file change (50 characters or less)&lt;br /&gt;
*** Use optional extended description (in case 50 characters was not enough)&lt;br /&gt;
** Save &amp;amp; choose Pull Request&lt;br /&gt;
* Use Command line “git” (for experienced users)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===More information=== &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
* Component Patchtester: [[S:MyLanguage/Component Patchtester for Testers|Component Patchtester for Testers]]&lt;br /&gt;
* Testing Joomla! patches: [[S:MyLanguage/Testing Joomla! patches|Testing Joomla! patches]]&lt;br /&gt;
* Testing Checklist: [[S:MyLanguage/Testing Checklists|Testing Checklists]]&lt;br /&gt;
* Filing bugs and issues: [[S:MyLanguage/Filing bugs and issues|Filing bugs and issues]]&lt;br /&gt;
* Bug Squad: [[S:MyLanguage/Bug Squad|Bug Squad]] &lt;br /&gt;
* Bug Tracking Process: [[S:MyLanguage/Bug Tracking Process|Bug Tracking Process]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Bug Tracker{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_to_use_JDate&amp;diff=1009258</id>
		<title>How to use JDate</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_to_use_JDate&amp;diff=1009258"/>
		<updated>2023-07-09T20:08:02Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Introduction == &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
Joomla&#039;s Date class is a helper class, extended from PHP&#039;s DateTime class, which allows developers to handle date formatting more efficiently. The class allows developers to format dates for readable strings, MySQL interaction, UNIX timestamp calculation, and also provides helper methods for working in different time zones.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
===Regarding the &#039;&#039;JDate&#039;&#039; Class Name===&lt;br /&gt;
This page has been updated to utilise namespaced class names. &#039;&#039;JDate&#039;&#039;, &#039;&#039;JApplication&#039;&#039; and other similarly-named classes you will see throughout the Joomla documentation are actually class aliases, maintained for legacy reasons. It is recommended to use namespaced access to Joomla classes, which will improve your development experience by providing better code hints and checks in your editor, leading to fewer errors. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
You can view the full list of aliased classes [https://github.com/joomla/joomla-cms/blob/3.10-dev/libraries/classmap.php in this file inside the Joomla code base].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Creating a Date Instance == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
All of the date helper methods require an instance of the Date class. To begin, you must create one. A Date object may be created in two ways. One is the typical native method of simply creating a new instance:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Date\Date;&lt;br /&gt;
&lt;br /&gt;
$date = new Date(); // Creates a new Date object equal to the current time.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
You may also create an instance using the static method defined in Date:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Date\Date;&lt;br /&gt;
&lt;br /&gt;
$date = Date::getInstance(); // Alias of &#039;new Date();&#039;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
There is no difference between these methods, as Date::getInstance simply creates a new instance of Date exactly like the first method shown.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
Alternatively, you may also retrieve the current date (as a Date object) from the Application object, by using:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
&lt;br /&gt;
$date = Factory::getDate();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Arguments == &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
The Date constructor (and &#039;&#039;getInstance&#039;&#039; static method) accepts two optional parameters: A date string to format and a timezone. Not passing a date string will create a Date object with the current date and time, while not passing a timezone will allow the Date object to use the default timezone set.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
The first argument, if used, should be a string that can be parsed using PHP&#039;s native DateTime constructor. For example:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Date\Date;&lt;br /&gt;
&lt;br /&gt;
$currentTime = new Date(&#039;now&#039;); // Current date and time&lt;br /&gt;
$tomorrowTime = new Date(&#039;now +1 day&#039;); // Current date and time, + 1 day.&lt;br /&gt;
$plus1MonthTime = new Date(&#039;now +1 month&#039;); // Current date and time, + 1 month.&lt;br /&gt;
$plus1YearTime = new Date(&#039;now +1 year&#039;); // Current date and time, + 1 year.&lt;br /&gt;
$plus1YearAnd1MonthTime = new Date(&#039;now +1 year +1 month&#039;); // Current date and time, + 1 year and 1 month.&lt;br /&gt;
$plusTimeToTime = new Date(&#039;now +1 hour +30 minutes +3 seconds&#039;); // Current date and time, + 1 hour, 30 minutes and 3 seconds&lt;br /&gt;
$plusTimeToTime = new Date(&#039;now -1 hour +30 minutes +3 seconds&#039;); // Current date and time, + 1 hour, 30 minutes and 3 seconds&lt;br /&gt;
$combinedTimeToTime = new Date(&#039;now -1 hour -30 minutes 23 seconds&#039;); // Current date and time, - 1 hour, +30 minutes and +23 seconds&lt;br /&gt;
&lt;br /&gt;
$date = new Date(&#039;2012-12-1 15:20:00&#039;); // 3:20 PM, December 1st, 2012&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
A Unix timestamp (in seconds) can also be passed as the first argument, in which case it will be internally uplifted into a date. If a timezone has been specified as the second argument to the constructor, it will be converted to that timezone.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Outputting Dates == &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
One note of caution when outputting Date objects in a user context: do not simply print them to the screen. The Date object&#039;s toString() method simply calls its parent&#039;s format() method, without consideration for time zones or localized date formatting. This will not result in a good user experience, and will lead to inconsistencies between the formatting in your extension, and elsewhere in Joomla. Instead, you should always output Dates using the methods shown below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Common Date Formats === &amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
A number of date formats are predefined in Joomla as part of the base language packs. This is beneficial because it means date formats can be easily internationalised. A sample of the available format strings is below, from the en-GB language pack. It is highly recommended to utilise these formatting strings when outputting dates, so that your dates will be automatically re-formatted according to a user&#039;s locale. They can be retrieved in the same way as any language string. (See below for examples.)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
DATE_FORMAT_LC=&amp;quot;l, d F Y&amp;quot;&lt;br /&gt;
DATE_FORMAT_LC1=&amp;quot;l, d F Y&amp;quot;&lt;br /&gt;
DATE_FORMAT_LC2=&amp;quot;l, d F Y H:i&amp;quot;&lt;br /&gt;
DATE_FORMAT_LC3=&amp;quot;d F Y&amp;quot;&lt;br /&gt;
DATE_FORMAT_LC4=&amp;quot;Y-m-d&amp;quot;&lt;br /&gt;
DATE_FORMAT_LC5=&amp;quot;Y-m-d H:i&amp;quot;&lt;br /&gt;
DATE_FORMAT_LC6=&amp;quot;Y-m-d H:i:s&amp;quot;&lt;br /&gt;
DATE_FORMAT_JS1=&amp;quot;y-m-d&amp;quot;&lt;br /&gt;
DATE_FORMAT_CALENDAR_DATE=&amp;quot;%Y-%m-%d&amp;quot;&lt;br /&gt;
DATE_FORMAT_CALENDAR_DATETIME=&amp;quot;%Y-%m-%d %H:%M:%S&amp;quot;&lt;br /&gt;
DATE_FORMAT_FILTER_DATE=&amp;quot;Y-m-d&amp;quot;&lt;br /&gt;
DATE_FORMAT_FILTER_DATETIME=&amp;quot;Y-m-d H:i:s&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== The HtmlHelper Method (Recommended) === &amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
As with many common output items, the HtmlHelper class is here to... help! HtmlHelper&#039;s date() method will take any date-time string that the Date constructor would accept, along with a formatting string, and output the date appropriate for the current user&#039;s timezone settings. As such, this is the recommended method for outputting dates for the user.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\HTML\HTMLHelper;&lt;br /&gt;
use Joomla\CMS\Language\Text;&lt;br /&gt;
&lt;br /&gt;
$myDateString = &#039;2012-12-1 15:20:00&#039;;&lt;br /&gt;
echo HtmlHelper::date($myDateString, Text::_(&#039;DATE_FORMAT_FILTER_DATETIME&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== The Date Object&#039;s format() Method === &amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
Another option is to format the Date manually. If this method is used, you will have to also manually retrieve and set the user&#039;s timezone. This method is more useful for formatting dates outside of the user interface, such as in system logs or API calls.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Language\Text;&lt;br /&gt;
use Joomla\CMS\Date\Date;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
&lt;br /&gt;
$myDateString = &#039;2012-12-1 15:20:00&#039;;&lt;br /&gt;
$timezone = Factory::getUser()-&amp;gt;getTimezone();&lt;br /&gt;
&lt;br /&gt;
$date = new Date($myDateString);&lt;br /&gt;
$date-&amp;gt;setTimezone($timezone);&lt;br /&gt;
echo $date-&amp;gt;format(Text::_(&#039;DATE_FORMAT_FILTER_DATETIME&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Other Useful Code Examples == &amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Quickly Outputting the Current Time === &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
There are two easy ways of doing this.&lt;br /&gt;
# The HtmlHelper&#039;s date() method, if no date value is provided, will default to the current time. &lt;br /&gt;
# Factory::getDate() gets the current date as a Date object, which we can then format.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
use Joomla\CMS\HTML\HTMLHelper;&lt;br /&gt;
use Joomla\CMS\Language\Text;&lt;br /&gt;
&lt;br /&gt;
// These two are functionally equivalent&lt;br /&gt;
echo HtmlHelper::date(&#039;now&#039;, Text::_(&#039;DATE_FORMAT_FILTER_DATETIME&#039;));&lt;br /&gt;
&lt;br /&gt;
$timezone = Factory::getUser()-&amp;gt;getTimezone();&lt;br /&gt;
echo Factory::getDate()-&amp;gt;setTimezone($timezone)-&amp;gt;format(Text::_(&#039;DATE_FORMAT_FILTER_DATETIME&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Adding and Subtracting from Dates === &amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Because the Joomla Date object extends the PHP DateTime object, it provides methods for adding and subtracting from dates. The easiest of these methods to use is the modify() method, which accepts any relative modification string that the PHP [https://www.php.net/manual/en/function.strtotime.php strtotime()] method would accept. For example:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Date\Date;&lt;br /&gt;
&lt;br /&gt;
$date = new Date(&#039;2012-12-1 15:20:00&#039;);&lt;br /&gt;
$date-&amp;gt;modify(&#039;+1 year&#039;);&lt;br /&gt;
echo $date-&amp;gt;toSQL(); // 2013-12-01 15:20:00&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
There are also separate add() and sub() methods, for adding or subtracting time from a date object respectively. These accept PHP-standard [https://www.php.net/manual/en/class.dateinterval.php DateInterval] objects:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Date\Date;&lt;br /&gt;
&lt;br /&gt;
$interval = new \DateInterval(&#039;P1Y1D&#039;); // Interval represents 1 year and 1 day&lt;br /&gt;
&lt;br /&gt;
$date1 = new Date(&#039;2012-12-1 15:20:00&#039;);&lt;br /&gt;
$date1-&amp;gt;add($interval);&lt;br /&gt;
echo $date1-&amp;gt;toSQL(); // 2013-12-02 15:20:00&lt;br /&gt;
&lt;br /&gt;
$date2 = new Date(&#039;2012-12-1 15:20:00&#039;);&lt;br /&gt;
$date2-&amp;gt;sub($interval);&lt;br /&gt;
echo $date2-&amp;gt;toSQL(); // 2011-11-30 15:20:00&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Outputting Dates in ISO 8601 Format === &amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$date = new Date(&#039;2012-12-1 15:20:00&#039;);&lt;br /&gt;
$date-&amp;gt;toISO8601(); // 20121201T152000Z&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Outputting Dates in RFC 822 Format === &amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$date = new Date(&#039;2012-12-1 15:20:00&#039;);&lt;br /&gt;
$date-&amp;gt;toRFC822(); // Sat, 01 Dec 2012 15:20:00 +0000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Outputting Dates in SQL Date-Time Format === &amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$date = new Date(&#039;20121201T152000Z&#039;);&lt;br /&gt;
$date-&amp;gt;toSQL(); // 2012-12-01 15:20:00&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Outputting Dates as Unix Timestamps === &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
A Unix timestamp is expressed as the number of seconds that have passed since the Unix Epoch (the first second of Jan 1st 1970).&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$date = new Date(&#039;20121201T152000Z&#039;);&lt;br /&gt;
$date-&amp;gt;toUnix(); // 1354375200&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Chunk:Configuring_Eclipse_IDE_for_PHP_development_-_Configuration&amp;diff=1005951</id>
		<title>Chunk:Configuring Eclipse IDE for PHP development - Configuration</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Chunk:Configuring_Eclipse_IDE_for_PHP_development_-_Configuration&amp;diff=1005951"/>
		<updated>2023-07-05T22:31:14Z</updated>

		<summary type="html">&lt;p&gt;Cmb: /* Installing More Extensions */ Corrected list markup.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuration ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Installing More Extensions ===&lt;br /&gt;
&lt;br /&gt;
For your Eclipse IDE you will need to install more extensions for PHP development and other tools to help you in your project development journey. Follow these steps and instructions:&lt;br /&gt;
&lt;br /&gt;
* In Eclipse, go to: &#039;&#039;Toolbar → Help → install new software&#039;&#039;.&lt;br /&gt;
* You are now on the &#039;&#039;Install&#039;&#039; window. Click the drop-down list &#039;&#039;Work with&#039;&#039; and set it to &#039;&#039;--All Available Sites--&#039;&#039;.&lt;br /&gt;
* In the list, expand the nodes and find the following packages to install:&lt;br /&gt;
** Go to &#039;&#039;Web, XML, and Java EE Development&#039;&#039; and select&lt;br /&gt;
*** PHP Development Tools (PDT) SDK Feature&lt;br /&gt;
*** JavaScript Development Tools&lt;br /&gt;
*** Eclipse Web Developer Tools&lt;br /&gt;
** Go to &#039;&#039;General Purpose Tools&#039;&#039; and select&lt;br /&gt;
*** Remote System Explorer End-User Runtime&lt;br /&gt;
&lt;br /&gt;
* Press &#039;&#039;Next →&#039;&#039; and follow the installation wizard. Restart Eclipse when prompted.&lt;br /&gt;
* In Eclipse, go to: &#039;&#039;Toolbar → Help → Install new software&#039;&#039;.&lt;br /&gt;
* Press the &#039;&#039;Add&#039;&#039; button and add this new repository, name it &#039;&#039;xtext plugin&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 https://download.eclipse.org/modeling/tmf/xtext/updates/composite/releases/&lt;br /&gt;
&lt;br /&gt;
* Press the &#039;&#039;Add&#039;&#039; button and add this new repository. Name it &#039;&#039;LESS plugin&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
 http://www.normalesup.org/~simonet/soft/ow/update/&lt;br /&gt;
&lt;br /&gt;
* Press &#039;&#039;OK&#039;&#039; and wait until Eclipse fetches all the new elements.&lt;br /&gt;
* In the selection box next to the &#039;&#039;Add&#039;&#039; button, select the &#039;&#039;LESS plugin...&#039;&#039; repository.&lt;br /&gt;
* On the list below find the &#039;&#039;LESS&#039;&#039; option and check it.&lt;br /&gt;
&lt;br /&gt;
* Press &#039;&#039;Next →&#039;&#039; and follow the installation wizard. Restart Eclipse when prompted.&lt;br /&gt;
&lt;br /&gt;
Those are all the extensions to install for now. They should be enough to do local and remote PHP development. Nonetheless you can experiment and try all the extensions you want.&lt;br /&gt;
&lt;br /&gt;
=== Configuring the Perspectives and Views ===&lt;br /&gt;
&lt;br /&gt;
In this case we need to configure Eclipse for PHP development. Add the following perspectives:&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Perspective → Open Perspective → Other → Debug&#039;&#039;&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Perspective → Open Perspective → Other → PHP&#039;&#039;&lt;br /&gt;
* Switch to the &#039;&#039;PHP perspective&#039;&#039;.&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Show View → Other → Remote Systems&#039;&#039;&lt;br /&gt;
* Drag the view from the tab and drop it next to the &#039;&#039;PHP Explorer&#039;&#039; view.&lt;br /&gt;
&lt;br /&gt;
Now you can explore local and remote PHP projects. The configuration of these tools are explained in [[Setting_up_your_workstation_for_PHP_development | this]] series of articles.&lt;br /&gt;
&lt;br /&gt;
=== Configuring the editors ===&lt;br /&gt;
&lt;br /&gt;
These are some of the configuration you can do to your editors to improve the user experience:&lt;br /&gt;
&lt;br /&gt;
==== Display Whitespace ====&lt;br /&gt;
&lt;br /&gt;
Some people like to see the whitespace represented in the editor. To do so:&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → General → Editors → Text Editors&#039;&#039;&lt;br /&gt;
* Check the &#039;&#039;Show whitespace characters&#039;&#039; box.&lt;br /&gt;
* Select the &#039;&#039;Apply and Close&#039;&#039; button.&lt;br /&gt;
&lt;br /&gt;
==== Colors ====&lt;br /&gt;
&lt;br /&gt;
To highlight some the parts of the code with stronger colors, follow these steps:&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → General → Editors → Text editors → Annotations&#039;&#039;&lt;br /&gt;
** On the list find &#039;&#039;JavaScript Occurrences&#039;&#039; and set the color value to &#039;&#039;#FFFF5A&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Matching Tags&#039;&#039; and set the color value to &#039;&#039;#FFFF5A&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;PHP elements &#039;read&#039; occurrences&#039;&#039; and set the color value to &#039;&#039;#FFFF5A&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → General → Editors → Structured Text Editor&#039;&#039;&lt;br /&gt;
** Find the list &#039;&#039;Appearance color options&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Matching brackets highlight&#039;&#039; and set the color value to &#039;&#039;#0000FF&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → JavaScript → Editor&#039;&#039;&lt;br /&gt;
** Find the list &#039;&#039;Appearance color option&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Matching brackets highlight&#039;&#039; and set the color value to &#039;&#039;#0000FF&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → JavaScript → Editor → Syntax Coloring&#039;&#039;&lt;br /&gt;
** Find the list &#039;&#039;Element&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;JavaScript → Functions&#039;&#039;. Enable the option and set the color value to &amp;quot;#1E90FF&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;JavaScript → Function declarations&#039;&#039; Enable the option and set the color value to &#039;&#039;#1E90FF&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;JavaScript → Local variable declaration&#039;&#039;. Enable the option and set the color value to &#039;&#039;#A52A2A&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;JavaScript → Local variable references&#039;&#039;. Enable the option and set the color value to &#039;&#039;#A52A2A&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;JavaScript → Parameter variables&#039;&#039;. Enable the option and set the color value to &#039;&#039;#A52A2A&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → PHP → Editor → Syntax Coloring&#039;&#039;&lt;br /&gt;
** Find the list &#039;&#039;Syntax Element&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Classes&#039;&#039; and set the color value to &#039;&#039;#1E90FF&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Functions&#039;&#039; and set the color value to &#039;&#039;#1E90FF&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Methods&#039;&#039; and set the color value to &#039;&#039;#1E90FF&#039;&#039;.&lt;br /&gt;
** On the list find &#039;&#039;Variable&#039;&#039; and set the color value to &#039;&#039;#A52A2A&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Spell Checking ====&lt;br /&gt;
&lt;br /&gt;
If you want Eclipse to check the grammar of your text, enable this option.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → General → Editors → Text Editors → Spelling&#039;&#039;&lt;br /&gt;
** Find and enable &#039;&#039;Enable spell checking&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Code Folding ====&lt;br /&gt;
&lt;br /&gt;
Code folding is a nice feature of some editors. It allow you to fold the code in certain data structures such as functions, classes, conditionals and iterators. We are going to fold all except PHP classes to be able to check and study PHP files quickly.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → General → Editors → Structured Text Editors&#039;&#039;&lt;br /&gt;
** Select the &#039;&#039;Appearance&#039;&#039; tab.&lt;br /&gt;
** Find and enable &#039;&#039;Enable folding&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → JavaScript → Editor → Folding&#039;&#039;&lt;br /&gt;
** Find and enable &#039;&#039;Enable folding&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Comments&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Header Comments&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Members&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → PHP → Editor → Code Folding&#039;&#039;&lt;br /&gt;
** Find and enable &#039;&#039;Enable folding&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Functions&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;PHPDoc&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Header PHPDoc&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Code Cleaning ====&lt;br /&gt;
&lt;br /&gt;
Eclipse provides some nice utilities to automatically remove empty lines, delete unnecessary trailing spaces, format the code and more. To activate these features:&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → PHP → Editor → Save Actions&#039;&#039;&lt;br /&gt;
** Find and enable &#039;&#039;Remove trailing whitespace&#039;&#039; and also select &#039;&#039;All lines&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* In the Toolbar, go to: &#039;&#039;Window → Preferences → JavaScript → Editor → Save Actions&#039;&#039;&lt;br /&gt;
** Find and enable &#039;&#039;Perform the selected actions on save&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Additional actions&#039;&#039;.&lt;br /&gt;
** Press the &#039;&#039;Configure...&#039;&#039; button.&lt;br /&gt;
** Select the tab &#039;&#039;Code Organizing&#039;&#039;.&lt;br /&gt;
** Find and enable &#039;&#039;Remove trailing whitespace&#039;&#039;.&lt;br /&gt;
** Find and select &#039;&#039;All lines&#039;&#039;.&lt;br /&gt;
** Press &#039;&#039;OK&#039;&#039; to continue.&lt;br /&gt;
&lt;br /&gt;
* When you are done, press &#039;&#039;Apply and Close&#039;&#039; to save and close the Preferences window.&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Configuring_Eclipse_IDE_for_PHP_development/Linux&amp;diff=1005950</id>
		<title>Configuring Eclipse IDE for PHP development/Linux</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Configuring_Eclipse_IDE_for_PHP_development/Linux&amp;diff=1005950"/>
		<updated>2023-07-05T22:26:05Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{RightTOC}}&lt;br /&gt;
&lt;br /&gt;
These instructions should work fine on any Debian-based distribution such as Debian, Ubuntu, Linux Mint, Xubuntu and Kubuntu.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
There are several ways to download and install the Eclipse IDE to your Linux box. You can do it automatically from the comfort of your software center or using the Linux terminal with few commands or manually downloading and installing the Eclipse IDE from the Eclipse project website or other alternative download sites.&lt;br /&gt;
&lt;br /&gt;
=== Method 1: From a Linux Repository  ===&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; This method is recommended because you will automate the installation process and get automatic security patches and bug fix updates when the software is installed from the repositories.&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Terminal  ====&lt;br /&gt;
*Open your terminal and type&lt;br /&gt;
 &#039;&#039;sudo apt-get install eclipse&#039;&#039;&lt;br /&gt;
*Wait for the installation process to finish.&lt;br /&gt;
*If everything went fine, the Eclipse IDE will be available in the software menu.&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Software Center ====&lt;br /&gt;
*Open the software center that comes with your distribution.&lt;br /&gt;
*Type in the search box &#039;&#039;Eclipse IDE&#039;&#039;.&lt;br /&gt;
*Select &#039;&#039;Eclipse IDE&#039;&#039; in the search result list.&lt;br /&gt;
*Click on the &#039;&#039;install&#039;&#039; button.&lt;br /&gt;
*Wait for the installation process to finish.&lt;br /&gt;
*If everything went fine, the Eclipse IDE will be available in the software menu.&lt;br /&gt;
&lt;br /&gt;
=== Method 2: From a Downloaded Copy  ===&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; For manual download and installation, you must have Java runtime previously installed or Eclipse IDE will not run.&lt;br /&gt;
&lt;br /&gt;
To install Java runtime on your Linux box, open a terminal and type following command and wait until the installation finishes:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;sudo apt-get install sun-java6&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
You can also install Java from your software center. Just type &#039;&#039;openjdk java 6&#039;&#039; and install the package.&lt;br /&gt;
&lt;br /&gt;
To get a copy of Eclipse IDE, follow these steps:&lt;br /&gt;
&lt;br /&gt;
*Go to: [https://www.eclipse.org/downloads/ Eclipse download page].&lt;br /&gt;
*Download &#039;&#039;Eclipse Classic&#039;&#039; 32 or 64 bits according to your current OS version.&lt;br /&gt;
*Unpack the downloaded file to any location that you want. For example: the Downloads folder or the Desktop folder.&lt;br /&gt;
*Open the Eclipse folder an find an executable file called &#039;&#039;eclipse&#039;&#039;.&lt;br /&gt;
*Do a right click on the file then: &#039;&#039;properties → permissions&#039;&#039; and check &#039;&#039;Allow executing file as a program&#039;&#039;.&lt;br /&gt;
*To execute the Eclipse IDE, you can do a double click on the executable file or run it from terminal. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
cd ~/Downloads/eclipse/&lt;br /&gt;
eclipse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; At the [https://www.eclipse.org/downloads/ Eclipse download page] you can see many versions of Eclipse IDE. All of them are basically the same Eclipse with several extensions pre-installed to do specific tasks. By default, Eclipse IDE comes with all the tools needed to develop Java projects but you can install more extensions to develop in other languages. Go to [https://www.eclipse.org/downloads/packages/compare Compare Eclipse Packages] to see a complete list of all the extensions included on each Eclipse Package build. You can try one of these pre-build packages specifically created for PHP development. Some of them are official releases from the Eclipse Website and others are independent projects.&lt;br /&gt;
&lt;br /&gt;
*[https://www.eclipse.org/pdt/#download Eclipse PDT (PHP Development Tools)]&lt;br /&gt;
*[http://www.easyeclipse.org/site/distributions/php.html EasyEclipse for PHP]&lt;br /&gt;
*[http://www.phpeclipse.com/ PhpEclipse]&lt;br /&gt;
&lt;br /&gt;
{{chunk:Configuring Eclipse IDE for PHP development - Understanding the interface}}&lt;br /&gt;
&lt;br /&gt;
== Understanding the Folder Structure ==&lt;br /&gt;
When you execute Eclipse for the first time, it will ask you to create a &#039;&#039;workspace&#039;&#039;. The workspace is a folder where Eclipse IDE will store two things: all your custom configurations and all or some of your projects.&lt;br /&gt;
&lt;br /&gt;
All your projects will be separated into folders inside the workspace folder like this:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 /home/youruser/workspace/project-a&lt;br /&gt;
 /home/youruser/workspace/project-b&lt;br /&gt;
 /home/youruser/workspace/joomla_component&lt;br /&gt;
 /home/youruser/workspace/joomla-test-site&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can have more than one workspace. Each of them will contain its own custom configurations and will not affect the information of other workspaces. For example, you can have a workspace located at &#039;&#039;/home/youruser/java-workspace/&#039;&#039; dedicated to contain Java projects and a separate workspace such as &#039;&#039;/home/youruser/php-workspace/&#039;&#039; dedicated to PHP development.&lt;br /&gt;
&lt;br /&gt;
As you can see, your workspace folder could be in any valid folder location. For the purposes of PHP development and our convenience, we can set our workspace folder to the same location where our Web server stores its Web files. For example, &#039;&#039;/home/youruser/lamp/public_html/&#039;&#039;. This way the Eclipse IDE and our Web server will use the same location for our Web files.&lt;br /&gt;
&lt;br /&gt;
Is important to note that you have the additional option to place your project files outside the workspace locations if you wish. This way Eclipse gives you an additional flexibility in certain cases. For example, let&#039;s say we have a workspace located at &#039;&#039;/home/youruser/workspace/&#039;&#039; which contains several random projects, but our server stores its files in a different location at &#039;&#039;/home/youruser/lamp/public_html/&#039;&#039;. Of course we want to put our PHP project there so we can edit the files and serve the pages at the same time. Simply create a folder like this: &#039;&#039;/home/youruser/lamp/public_html/my-joomla-project&#039;&#039;. Then create a new PHP project and manually specify the path of your new project.&lt;br /&gt;
&lt;br /&gt;
What is the difference of projects that are inside and outside the workspace folder? The only noticeable difference is at the moment of creating new projects, When you create a project inside the workspace, Eclipse IDE will automatically create a folder for that project with the same name as the project itself. On the other hand, if the project is outside the workspace location, you can set a random name for the project and then you have to set the path of the project manually regardless of the destination folder name.&lt;br /&gt;
&lt;br /&gt;
A final note about the behavior of creating new project is that the Eclipse IDE will not let you link an external project that is actually inside your current workspace location. Also you can manually create any folder inside your Eclipse IDE workspace location but that does not mean Eclipse will recognize such folders as a project at all. When you create the new project from the Eclipse IDE that shares the name of an existing folder that already exists in your workspace, Eclipse will automatically link all its contents to your new project.&lt;br /&gt;
&lt;br /&gt;
When you create a new workspace, Eclipse will automatically create a hidden folder called &#039;&#039;.metadata&#039;&#039;. It will contain all your custom global configurations about the editors, perspectives and views. This configuration will be inherited by any new project by default. If you wish, you can override part of the global configuration with custom configurations values specific for each project.&lt;br /&gt;
&lt;br /&gt;
When you create a new project, Eclipse will create these hidden files and folders inside your new project folder:&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 .project&lt;br /&gt;
 .buildpath&lt;br /&gt;
 .settings&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
These files and folders contain information about your custom project configurations and building information that will let Eclipse show tree views of dependencies and classes among many other things.&lt;br /&gt;
&lt;br /&gt;
{{Chunk:Configuring Eclipse IDE for PHP development - Configuration}}&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
&lt;br /&gt;
== Fine Tuning ==&lt;br /&gt;
=== Increase RAM Usage  ===&lt;br /&gt;
By default, Eclipse gets some configuration information to limit the amount of RAM. This configuration works fine for most users but if you have 2 gigabytes or more of RAM, consider setting this value to improve Eclipse performance.&lt;br /&gt;
&lt;br /&gt;
First locate the &#039;&#039;eclipse.ini&#039;&#039; file that contains some Eclipse configurations.&lt;br /&gt;
&lt;br /&gt;
*If you downloaded Eclipse IDE manually from Internet, the &#039;&#039;eclipse.ini&#039;&#039; file is just inside the unpacked folder.&lt;br /&gt;
*If you installed Eclipse via terminal or software center, the location of the file is &#039;&#039;/etc/eclipse.ini&#039;&#039;.&lt;br /&gt;
*In some Linux versions, the file can be found at &#039;&#039;/usr/share/eclipse/eclipse.ini&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;NOTE&#039;&#039;&#039; If you found a config file at &#039;&#039;/etc/eclipse.ini&#039;&#039;, don&#039;t edit the file at &#039;&#039;/usr/share/eclipse/eclipse.ini&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
This is the content of the original &#039;&#039;eclipse.ini&#039;&#039; file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 -startup&lt;br /&gt;
 plugins/org.eclipse.equinox.launcher_1.2.0.dist.jar&lt;br /&gt;
 --launcher.library&lt;br /&gt;
 plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.100.dist&lt;br /&gt;
 -showsplash&lt;br /&gt;
 org.eclipse.platform&lt;br /&gt;
 --launcher.XXMaxPermSize&lt;br /&gt;
 256m&lt;br /&gt;
 --launcher.defaultAction&lt;br /&gt;
 openFile&lt;br /&gt;
 -vmargs&lt;br /&gt;
 -Xms40m&lt;br /&gt;
 -Xmx384m&lt;br /&gt;
 -Dorg.eclipse.equinox.p2.reconciler.dropins.directory=/usr/share/eclipse/dropins&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
To see the full reference about these parameters, visit [https://help.eclipse.org/oxygen/index.jsp?topic=%2Forg.eclipse.platform.doc.isv%2Freference%2Fmisc%2Fruntime-options.html].&lt;br /&gt;
&lt;br /&gt;
Change the following values to increase the amount of RAM used by Eclipse.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 -startup&lt;br /&gt;
 plugins/org.eclipse.equinox.launcher_1.2.0.dist.jar&lt;br /&gt;
 --launcher.library&lt;br /&gt;
 plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.100.dist&lt;br /&gt;
 -showsplash&lt;br /&gt;
 org.eclipse.platform&lt;br /&gt;
 --launcher.XXMaxPermSize&lt;br /&gt;
 512m&lt;br /&gt;
 --launcher.defaultAction&lt;br /&gt;
 openFile&lt;br /&gt;
 -vmargs&lt;br /&gt;
 -Xms512m&lt;br /&gt;
 -Xmx512m&lt;br /&gt;
 -Dorg.eclipse.equinox.p2.reconciler.dropins.directory=/usr/share/eclipse/dropins&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have a lot of RAM you can try these other configurations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
 -startup&lt;br /&gt;
 plugins/org.eclipse.equinox.launcher_1.2.0.dist.jar&lt;br /&gt;
 --launcher.library&lt;br /&gt;
 plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.100.dist&lt;br /&gt;
 -showsplash&lt;br /&gt;
 org.eclipse.platform&lt;br /&gt;
 --launcher.XXMaxPermSize&lt;br /&gt;
 1024m&lt;br /&gt;
 --launcher.defaultAction&lt;br /&gt;
 openFile&lt;br /&gt;
 -vmargs&lt;br /&gt;
 -Xms1024m&lt;br /&gt;
 -Xmx1024m&lt;br /&gt;
 -Dorg.eclipse.equinox.p2.reconciler.dropins.directory=/usr/share/eclipse/dropins&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;br /&gt;
[[Category:IDE (Integrated development environment)]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_CodeSniffer&amp;diff=1005949</id>
		<title>Joomla CodeSniffer</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_CodeSniffer&amp;diff=1005949"/>
		<updated>2023-07-05T20:57:40Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Removed dead URLs to screenshots.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== A Nose For Joomla == &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; This is a custom coding standard for the PHP CodeSniffer that attempts to codify and enforce the Joomla coding standards. This article covers how to set the automatic code style checker. It consists of three steps:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
# Install PHP CodeSniffer (phpcs).&lt;br /&gt;
# Clone the Joomla Code Style (for use with for phpcs).&lt;br /&gt;
# Configure your IDE to work with PHP CodeSniffer and Joomla Code Style.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CodeSnifferInAction.jpg|center|thumb|300px|PHP Code Sniffer in action]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Why?== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; *Coherent and consistent coding practice makes the files look more professional. Conflicting styles in the same project (or worse, the same file) not only look sloppy, they encourage further sloppiness.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; *When all code complies with the same standard, bad code is easier for everyone to spot.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; *It makes it easier for someone new to a particular file in the project to find and fix errors or extend functionality.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; *If there is no consistent standard maintained, sometimes developers will reformat the code to suit themselves. This causes a wide range of changes in the code repository. If there is a later problem, a significant change could be lost in the chaff produced by a diff.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Installation of PHP Code Sniffer (phpcs)== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Composer=== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; PHP Code Sniffer is available via Composer. It can be installed system-wide with the following command:&amp;lt;/translate&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;composer global require --dev squizlabs/php_codesniffer &amp;quot;~3.5&amp;quot;&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
On &#039;&#039;&#039;Linux&#039;&#039;&#039; PHP Code Sniffer (phpcs) will be installed under your user folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;~/.composer/vendor/bin/phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;~/.composer/vendor/squizlabs/php_codesniffer/scripts/phpcs&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:76--&amp;gt; To create that symbolic link, use on the command line: &amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;$ sudo ln -s ~/.config/composer/vendor/squizlabs/php_codesniffer/scripts /usr/bin/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt; or (for example OpenSuse)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;~/.config/composer/vendor/bin/phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;~/.config/composer/vendor/squizlabs/php_codesniffer/scripts/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt; On &#039;&#039;&#039;Windows&#039;&#039;&#039; PHP Code Sniffer (phpcs) will be installed under your user folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\bin\phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\squizlabs\php_codesniffer\scripts\phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add composer bin directory to your $PATH === &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
In order to execute PHP Code sniffer from anywhere on Linux or Mac command line you have to add &#039;&#039;.composer/vendor/bin&#039;&#039; to your $PATH variable.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
To do this persistent edit your shells start file, like your .profile or .bash_profile file depending which shell you are using (echo $SHELL shows you which one you are using).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; Add the following line to the file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;export PATH=$PATH:~/.composer/vendor/bin&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; Alternatively you can also create a symbolic link in the bin folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;ln -s ~/.composer/vendor/bin/phpcs /usr/local/bin/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Install Joomla Coding Standards== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt; In order to have PHP Code Sniffer (phpcs) sniffing your Joomla projects for the right code style, you have to install the Joomla Coding Standards.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; Using composer we can execute:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;composer global require --dev joomla/coding-standards &amp;quot;~3.0@alpha&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; Notice that it says &#039;&#039;@alpha&#039;&#039;, that is because the coding standard is still in alpha state and we need to allow the installation of alpha status code. If we do not include the @alpha the coding standards will not install and throw this error.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Your requirements could not be resolved to an installable set of packages.&lt;br /&gt;
&lt;br /&gt;
Problem 1&lt;br /&gt;
 - The requested package joomla/coding-standards ~3.0 is satisfiable by joomla/coding-standards[3.0.0-alpha, 3.0.0-alpha2, 3.x-dev] but these conflict with your requirements or minimum-stability.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt; Once the installation is done the coding standard will be installed in the global composer folder. The location of this folder depends on your operating system. Some popular locations are:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac / Linux&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.composer/vendor/joomla/coding-standards/&#039;&#039;&lt;br /&gt;
and&lt;br /&gt;
&#039;&#039;~/.config/composer/vendor/joomla/coding-standards/&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\joomla\coding-standards\&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; This is using Composer on Windows.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; If you can&#039;t find it in any of the above folders, note that the folder you are looking for ends with &#039;&#039;\joomla\coding-standards\&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Finally we need to tell Code Sniffer that the Joomla coding standards exist.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Install Joomla Coding Standards&#039;&#039;&#039;&lt;br /&gt;
# Check if certain paths are already set by running &#039;&#039;phpcs --config-show&#039;&#039;&lt;br /&gt;
# You can get an answer that looks like this: &#039;&#039;installed_paths: /path/to/installation&#039;&#039;&lt;br /&gt;
# In step 2, if you see the &#039;&#039;&#039;installed_paths&#039;&#039;&#039; you need to copy that&lt;br /&gt;
# Set the Joomla Coding Standards path in phpcs by executing &#039;&#039;phpcs --config-set installed_paths /Users/user/.composer/vendor/joomla/coding-standards&#039;&#039;. If you copied any paths in step 2, include them here as well by separating them with a comma. The command looks like &#039;&#039;phpcs --config-set installed_paths [/to/path1],[/to/path2],[/Users/user/.composer/vendor/joomla/coding-standards]&#039;&#039;&lt;br /&gt;
# Verify the path is set correctly by running &#039;&#039;phpcs --config-show&#039;&#039;&lt;br /&gt;
# Verify that phpcs can see the Joomla codestyle by running &#039;&#039;phpcs -i&#039;&#039;&lt;br /&gt;
# The output should look like this: &#039;&#039;The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, Zend and Joomla&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage == &amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; You invoke the custom standard by&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;phpcs --standard=Joomla file/to/sniff&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; To test a platform file using the provided platform coding standards, use&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;phpcs --standard=build/phpcs/Joomla path/to/file/or/folder&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; Further documentation on the use of phpcs can be found at the [https://pear.php.net/package/PHP_CodeSniffer/docs pear.php.net website].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==IDE Integration== &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; Everybody loves the console. It is, with no doubt, the most effective way to do whatever you need to do. Sometimes even Linux gurus need a little bit of comfort.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt; Fortunately there is a plug-in available for PhpStorm, Eclipse and Netbeans that integrates the CodeSniffer into your favourite IDE, so any coding standard violations are shown like &amp;quot;normal&amp;quot; errors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== PhpStorm === &amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; Code Sniffer is supported out of the box in PhpStorm. Go to Settings and under {{rarr|Editor,Inspections}} you will see the list of sniffers you have installed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Set Path to Code Sniffer ==== &amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Languages &amp;amp; Frameworks&lt;br /&gt;
# Click on PHP&lt;br /&gt;
# Click on Quality Tools&lt;br /&gt;
# Click on PHP cs fixer dropdown arrow&lt;br /&gt;
# The configuration is set to Local by default&lt;br /&gt;
# Click on the 3 dots behind it to open the configuration screen&lt;br /&gt;
# The first option is the PHP Code Sniffer (phpcs) path&lt;br /&gt;
# Click on the 3 dots behind the path to select the location of the phpcs file. See above on where phpcs may be installed on your site&lt;br /&gt;
# Click on Validate to make sure the path is correct and phpcs is working&lt;br /&gt;
# Click OK&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Activating the Joomla Code Style ===== &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Editor&lt;br /&gt;
# Click on Inspections&lt;br /&gt;
# In the list, go to PHP&lt;br /&gt;
# Click on PHP Code Sniffer Validation&lt;br /&gt;
# Click on the check box behind it to activate it&lt;br /&gt;
# Click the Reload button (2 arrows) to force a reload of rules from disk&lt;br /&gt;
# Joomla should now be available in the list. See following image:{{-}}[[File:PhpStorm8CodeSniffer.png|PHPStorm CodeSniffer|500px]]&lt;br /&gt;
# Click OK&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== PHP PSR-0, PSR-1 and PSR-2 ==== &amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md&lt;br /&gt;
* https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-1-basic.md&lt;br /&gt;
* https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-2-advanced.md&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Using PHP PSR-1 and PSR-2 Sniff ===== &amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; A CodeSniffer sniff to check against the PSR-x Coding Standard can be used as well. In that case you can select a different standard than Joomla.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Using Joomla Code style ===== &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; It&#039;s nice to be able to check that the standards are respected. It&#039;s even nicer if PhpStorm helps you format properly too as you are coding.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
To use the Joomla code style in PhpStorm&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Editor&lt;br /&gt;
# Click on Code Style&lt;br /&gt;
# Select Joomla from the Scheme select box&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== PhpStorm / Alternative Method ==== &amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; &#039;&#039;&#039;NOTE&#039;&#039;&#039;: This method is &#039;&#039;&#039;outdated&#039;&#039;&#039;, but it might be useful if you are looking for a different integration. It also demonstrates the use of external tools in PhpStorm - so it &#039;&#039;shouldn&#039;t be deleted&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:77--&amp;gt; The Code Sniffer can also be integrated easily as an external tool. PhpStorm will display the output in the console, including click-able links containing line and column numbers to the files that contain errors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
* Click on &amp;quot;Settings&amp;quot; and search for &amp;quot;External tools&amp;quot;&lt;br /&gt;
* Click &amp;quot;Add...&amp;quot;&lt;br /&gt;
* Choose a &amp;quot;Name&amp;quot;, &amp;quot;Group&amp;quot; and &amp;quot;Description&amp;quot;.&lt;br /&gt;
* Click &amp;quot;Output Filters&amp;quot;&lt;br /&gt;
** Click &amp;quot;Add...&amp;quot;, Choose a name and enter under &amp;quot;Regular expression to match output&amp;quot; the value: &#039;&#039;$FILE_PATH$:$LINE$:$COLUMN$&#039;&#039;&lt;br /&gt;
* &amp;quot;Program&amp;quot;: Search for the phpcs executable on your system. You have to set the path to the &#039;&#039;phpcs.bat&#039;&#039; from the installed PHP_CodeSniffer PEAR package&lt;br /&gt;
** For Unix based systems, the path is something like /usr/bin/phpcs&lt;br /&gt;
** In XAMPP (windows), you can find the file in the PHP root folder (e.g. C:\xampp\php\phpcs.bat)&lt;br /&gt;
* &amp;quot;Parameters&amp;quot;:&lt;br /&gt;
** &#039;&#039;--standard=&amp;lt;path/to/joomla-platform&amp;gt;/build/phpcs/Joomla&#039;&#039; The path to the Joomla! coding standards.&lt;br /&gt;
** &#039;&#039;--report=emacs&#039;&#039; The will generate a simple list containing links to the error files&lt;br /&gt;
** Optionally you may want to specify &#039;&#039;-p&#039;&#039; for &amp;quot;progress&amp;quot; or &#039;&#039;-n&#039;&#039; for &amp;quot;errors only&amp;quot;.&lt;br /&gt;
** The last parameter has to be &#039;&#039;$FilePath$&#039;&#039; specifying the file or folder you want to sniff.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; A typical &amp;quot;Parameters&amp;quot; line on a Linux system might look like this:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;-np --standard=/home/elkuku/libs/joomla/build/phpcs/Joomla --report=emacs $FilePath$&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt; You may now right click any file or folder and choose the sniffer from the context menu or add a new tool bar button with a nice Joomla! logo&amp;lt;/translate&amp;gt; [[File:icon-16-joomla.png]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Netbeans === &amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; Netbeans has the sniffer functionality integrated into the core system.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
# Start your Netbeans IDE&lt;br /&gt;
# Open {{rarr|Tools,Options,PHP,Code Analysis,Code Sniffer}}&lt;br /&gt;
# You have to set the path to &#039;&#039;phpcs.bat&#039;&#039; from the installed PHP_CodeSniffer PEAR package&lt;br /&gt;
#* For Unix based systems the path is something like /usr/bin/phpcs&lt;br /&gt;
#* In XAMPP (windows) you can find the file in the PHP root folder (e.g. C:\xampp\php\phpcs.bat)&lt;br /&gt;
# As &amp;quot;Default Standard,&amp;quot; choose &amp;quot;Joomla&amp;quot; to use the Joomla! standard&lt;br /&gt;
# Now you can click &#039;&#039;OK&#039;&#039; to start sniffing&lt;br /&gt;
# Open from the top menu {{rarr|Source,Inspect}}&lt;br /&gt;
# Enjoy&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Eclipse === &amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:eclipse_pti.png|left|thumb|200px|1) Eclipse PTI]]&lt;br /&gt;
{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
Installation is a breeze and follows the usual pattern:&lt;br /&gt;
# {{rarr|Help,Install New Software}}&lt;br /&gt;
# &#039;&#039;Work with:&#039;&#039; Fill in one of the update site URLs found here: http://www.phpsrc.org/eclipse/pti/&lt;br /&gt;
# Select the desired tools&lt;br /&gt;
# Restart Eclipse.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:eclipse_pti_settings.png|right|thumb|150px|2) &amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt; Eclipse PTI settings&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; You are now able to sniff for code violations against common standards like PEAR or Zend etc.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt; To sniff against your own standards, specify their location and activate them:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
# {{rarr|Window,Preferences}}&lt;br /&gt;
# {{rarr|PHP Tools,PHP CodeSniffer}}&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:68--&amp;gt; Happy sniffing.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Geany === &amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
* Open a PHP file. (Otherwise the build menu is not accessible.)&lt;br /&gt;
* On the top menu, select Build-&amp;gt;Set Build Commands.&lt;br /&gt;
* Select the second field and name it as you wish. Enter this code in the Command: &#039;&#039;phpcs --standard=Joomla &amp;quot;%f&amp;quot; | sed -e &#039;s/^/%f |/&#039; | egrep &#039;WARNING|ERROR&#039;&#039;&#039;&lt;br /&gt;
* Enter this code in the Error Regular Expression field: &#039;&#039;(.+) [|]\s+([0-9]+)&#039;&#039;&lt;br /&gt;
* Select &#039;&#039;OK&#039;&#039;.&lt;br /&gt;
* If the Message Window is not open, display it by selecting it in the top &#039;&#039;View&#039;&#039; menu.&lt;br /&gt;
* When viewing any PHP file, press F9 to see the errors found.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Atom === &amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
* Install phpcs and the Joomla standards as described above.&lt;br /&gt;
* In {{rarr|Atom,Preferences,Install}} install &#039;&#039;linter-phpcs&#039;&#039; and all its requirements.&lt;br /&gt;
* In {{rarr|Atom,Preferences,Packages,linter-phpcs,Settings}} adjust&lt;br /&gt;
** &#039;&#039;&#039;Executable Path&#039;&#039;&#039; to the path of your phpcs&lt;br /&gt;
** &#039;&#039;&#039;Code Standard Or Config File&#039;&#039;&#039;: Joomla&lt;br /&gt;
** &#039;&#039;&#039;Tab Width&#039;&#039;&#039;: 4&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== References === &amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* [https://github.com/joomla/coding-standards Joomla! Coding Standards]&lt;br /&gt;
* [https://www.phpsrc.org/ PTI - PHP tools integration for Eclipse]&lt;br /&gt;
* [https://sourceforge.net/projects/phpmdnb/ Netbeans plugin]&lt;br /&gt;
* https://hakre.wordpress.com/2010/03/06/php-code-sniffer-eclipse-and-wordpress/ - &amp;lt;translate&amp;gt;&amp;lt;!--T:75--&amp;gt; Excellent article. Just change &#039;&#039;Wordpress&#039;&#039; for &#039;&#039;Joomla&#039;&#039; ;)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:IDE (Integrated development environment){{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_CodeSniffer&amp;diff=1005946</id>
		<title>Joomla CodeSniffer</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_CodeSniffer&amp;diff=1005946"/>
		<updated>2023-07-05T16:54:43Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected a URL. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== A Nose For Joomla == &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; This is a custom coding standard for the PHP CodeSniffer that attempts to codify and enforce the Joomla coding standards. This article covers how to set the automatic code style checker. It consists of three steps:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
# Install PHP CodeSniffer (phpcs).&lt;br /&gt;
# Clone the Joomla Code Style (for use with for phpcs).&lt;br /&gt;
# Configure your IDE to work with PHP CodeSniffer and Joomla Code Style.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CodeSnifferInAction.jpg|center|thumb|300px|PHP Code Sniffer in action]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Why?== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; *Coherent and consistent coding practice makes the files look more professional. Conflicting styles in the same project (or worse, the same file) not only look sloppy, they encourage further sloppiness.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; *When all code complies with the same standard, bad code is easier for everyone to spot.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; *It makes it easier for someone new to a particular file in the project to find and fix errors or extend functionality.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; *If there is no consistent standard maintained, sometimes developers will reformat the code to suit themselves. This causes a wide range of changes in the code repository. If there is a later problem, a significant change could be lost in the chaff produced by a diff.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Installation of PHP Code Sniffer (phpcs)== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Composer=== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; PHP Code Sniffer is available via Composer. It can be installed system-wide with the following command:&amp;lt;/translate&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;composer global require --dev squizlabs/php_codesniffer &amp;quot;~3.5&amp;quot;&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
On &#039;&#039;&#039;Linux&#039;&#039;&#039; PHP Code Sniffer (phpcs) will be installed under your user folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;~/.composer/vendor/bin/phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;~/.composer/vendor/squizlabs/php_codesniffer/scripts/phpcs&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:76--&amp;gt; To create that symbolic link, use on the command line: &amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;$ sudo ln -s ~/.config/composer/vendor/squizlabs/php_codesniffer/scripts /usr/bin/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt; or (for example OpenSuse)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;~/.config/composer/vendor/bin/phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;~/.config/composer/vendor/squizlabs/php_codesniffer/scripts/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt; On &#039;&#039;&#039;Windows&#039;&#039;&#039; PHP Code Sniffer (phpcs) will be installed under your user folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\bin\phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\squizlabs\php_codesniffer\scripts\phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add composer bin directory to your $PATH === &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
In order to execute PHP Code sniffer from anywhere on Linux or Mac command line you have to add &#039;&#039;.composer/vendor/bin&#039;&#039; to your $PATH variable.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
To do this persistent edit your shells start file, like your .profile or .bash_profile file depending which shell you are using (echo $SHELL shows you which one you are using).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; Add the following line to the file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;export PATH=$PATH:~/.composer/vendor/bin&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; Alternatively you can also create a symbolic link in the bin folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;ln -s ~/.composer/vendor/bin/phpcs /usr/local/bin/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Install Joomla Coding Standards== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt; In order to have PHP Code Sniffer (phpcs) sniffing your Joomla projects for the right code style, you have to install the Joomla Coding Standards.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; Using composer we can execute:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;composer global require --dev joomla/coding-standards &amp;quot;~3.0@alpha&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; Notice that it says &#039;&#039;@alpha&#039;&#039;, that is because the coding standard is still in alpha state and we need to allow the installation of alpha status code. If we do not include the @alpha the coding standards will not install and throw this error.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Your requirements could not be resolved to an installable set of packages.&lt;br /&gt;
&lt;br /&gt;
Problem 1&lt;br /&gt;
 - The requested package joomla/coding-standards ~3.0 is satisfiable by joomla/coding-standards[3.0.0-alpha, 3.0.0-alpha2, 3.x-dev] but these conflict with your requirements or minimum-stability.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt; Once the installation is done the coding standard will be installed in the global composer folder. The location of this folder depends on your operating system. Some popular locations are:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac / Linux&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;~/.composer/vendor/joomla/coding-standards/&#039;&#039;&lt;br /&gt;
and&lt;br /&gt;
&#039;&#039;~/.config/composer/vendor/joomla/coding-standards/&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\joomla\coding-standards\&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; This is using Composer on Windows.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; If you can&#039;t find it in any of the above folders, note that the folder you are looking for ends with &#039;&#039;\joomla\coding-standards\&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Finally we need to tell Code Sniffer that the Joomla coding standards exist.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Install Joomla Coding Standards&#039;&#039;&#039;&lt;br /&gt;
# Check if certain paths are already set by running &#039;&#039;phpcs --config-show&#039;&#039;&lt;br /&gt;
# You can get an answer that looks like this: &#039;&#039;installed_paths: /path/to/installation&#039;&#039;&lt;br /&gt;
# In step 2, if you see the &#039;&#039;&#039;installed_paths&#039;&#039;&#039; you need to copy that&lt;br /&gt;
# Set the Joomla Coding Standards path in phpcs by executing &#039;&#039;phpcs --config-set installed_paths /Users/user/.composer/vendor/joomla/coding-standards&#039;&#039;. If you copied any paths in step 2, include them here as well by separating them with a comma. The command looks like &#039;&#039;phpcs --config-set installed_paths [/to/path1],[/to/path2],[/Users/user/.composer/vendor/joomla/coding-standards]&#039;&#039;&lt;br /&gt;
# Verify the path is set correctly by running &#039;&#039;phpcs --config-show&#039;&#039;&lt;br /&gt;
# Verify that phpcs can see the Joomla codestyle by running &#039;&#039;phpcs -i&#039;&#039;&lt;br /&gt;
# The output should look like this: &#039;&#039;The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, Zend and Joomla&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage == &amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; You invoke the custom standard by&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;phpcs --standard=Joomla file/to/sniff&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; To test a platform file using the provided platform coding standards, use&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;phpcs --standard=build/phpcs/Joomla path/to/file/or/folder&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; Further documentation on the use of phpcs can be found at the [https://pear.php.net/package/PHP_CodeSniffer/docs pear.php.net website].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==IDE Integration== &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; Everybody loves the console. It is, with no doubt, the most effective way to do whatever you need to do. Sometimes even Linux gurus need a little bit of comfort.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt; Fortunately there is a plug-in available for PhpStorm, Eclipse and Netbeans that integrates the CodeSniffer into your favourite IDE, so any coding standard violations are shown like &amp;quot;normal&amp;quot; errors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== PhpStorm === &amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; Code Sniffer is supported out of the box in PhpStorm. Go to Settings and under {{rarr|Editor,Inspections}} you will see the list of sniffers you have installed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Set Path to Code Sniffer ==== &amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Languages &amp;amp; Frameworks&lt;br /&gt;
# Click on PHP&lt;br /&gt;
# Click on Quality Tools&lt;br /&gt;
# Click on PHP cs fixer dropdown arrow&lt;br /&gt;
# The configuration is set to Local by default&lt;br /&gt;
# Click on the 3 dots behind it to open the configuration screen&lt;br /&gt;
# The first option is the PHP Code Sniffer (phpcs) path&lt;br /&gt;
# Click on the 3 dots behind the path to select the location of the phpcs file. See above on where phpcs may be installed on your site&lt;br /&gt;
# Click on Validate to make sure the path is correct and phpcs is working&lt;br /&gt;
# Click OK&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Activating the Joomla Code Style ===== &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Editor&lt;br /&gt;
# Click on Inspections&lt;br /&gt;
# In the list, go to PHP&lt;br /&gt;
# Click on PHP Code Sniffer Validation&lt;br /&gt;
# Click on the check box behind it to activate it&lt;br /&gt;
# Click the Reload button (2 arrows) to force a reload of rules from disk&lt;br /&gt;
# Joomla should now be available in the list. See following image:{{-}}[[File:PhpStorm8CodeSniffer.png|PHPStorm CodeSniffer|500px]]&lt;br /&gt;
# Click OK&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== PHP PSR-0, PSR-1 and PSR-2 ==== &amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md&lt;br /&gt;
* https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-1-basic.md&lt;br /&gt;
* https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-2-advanced.md&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Using PHP PSR-1 and PSR-2 Sniff ===== &amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; A CodeSniffer sniff to check against the PSR-x Coding Standard can be used as well. In that case you can select a different standard than Joomla.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Using Joomla Code style ===== &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; It&#039;s nice to be able to check that the standards are respected. It&#039;s even nicer if PhpStorm helps you format properly too as you are coding.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
To use the Joomla code style in PhpStorm&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Editor&lt;br /&gt;
# Click on Code Style&lt;br /&gt;
# Select Joomla from the Scheme select box&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== PhpStorm / Alternative Method ==== &amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; &#039;&#039;&#039;NOTE&#039;&#039;&#039;: This method is &#039;&#039;&#039;outdated&#039;&#039;&#039;, but it might be useful if you are looking for a different integration. It also demonstrates the use of external tools in PhpStorm - so it &#039;&#039;shouldn&#039;t be deleted&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:77--&amp;gt; The Code Sniffer can also be integrated easily as an external tool. PhpStorm will display the output in the console, including click-able links containing line and column numbers to the files that contain errors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
* Click on &amp;quot;Settings&amp;quot; and search for &amp;quot;External tools&amp;quot;&lt;br /&gt;
* Click &amp;quot;Add...&amp;quot;&lt;br /&gt;
* Choose a &amp;quot;Name&amp;quot;, &amp;quot;Group&amp;quot; and &amp;quot;Description&amp;quot;.&lt;br /&gt;
* Click &amp;quot;Output Filters&amp;quot;&lt;br /&gt;
** Click &amp;quot;Add...&amp;quot;, Choose a name and enter under &amp;quot;Regular expression to match output&amp;quot; the value: &#039;&#039;$FILE_PATH$:$LINE$:$COLUMN$&#039;&#039;&lt;br /&gt;
* &amp;quot;Program&amp;quot;: Search for the phpcs executable on your system. You have to set the path to the &#039;&#039;phpcs.bat&#039;&#039; from the installed PHP_CodeSniffer PEAR package&lt;br /&gt;
** For Unix based systems, the path is something like /usr/bin/phpcs&lt;br /&gt;
** In XAMPP (windows), you can find the file in the PHP root folder (e.g. C:\xampp\php\phpcs.bat)&lt;br /&gt;
* &amp;quot;Parameters&amp;quot;:&lt;br /&gt;
** &#039;&#039;--standard=&amp;lt;path/to/joomla-platform&amp;gt;/build/phpcs/Joomla&#039;&#039; The path to the Joomla! coding standards.&lt;br /&gt;
** &#039;&#039;--report=emacs&#039;&#039; The will generate a simple list containing links to the error files&lt;br /&gt;
** Optionally you may want to specify &#039;&#039;-p&#039;&#039; for &amp;quot;progress&amp;quot; or &#039;&#039;-n&#039;&#039; for &amp;quot;errors only&amp;quot;.&lt;br /&gt;
** The last parameter has to be &#039;&#039;$FilePath$&#039;&#039; specifying the file or folder you want to sniff.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; A typical &amp;quot;Parameters&amp;quot; line on a Linux system might look like this:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;-np --standard=/home/elkuku/libs/joomla/build/phpcs/Joomla --report=emacs $FilePath$&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt; You may now right click any file or folder and choose the sniffer from the context menu or add a new tool bar button with a nice Joomla! logo&amp;lt;/translate&amp;gt; [[File:icon-16-joomla.png]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Netbeans === &amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; Netbeans has the sniffer functionality integrated into the core system.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
# Start your Netbeans IDE&lt;br /&gt;
# Open {{rarr|Tools,Options,PHP,Code Analysis,Code Sniffer}}&lt;br /&gt;
# You have to set the path to &#039;&#039;phpcs.bat&#039;&#039; from the installed PHP_CodeSniffer PEAR package&lt;br /&gt;
#* For Unix based systems the path is something like /usr/bin/phpcs&lt;br /&gt;
#* In XAMPP (windows) you can find the file in the PHP root folder (e.g. C:\xampp\php\phpcs.bat)&lt;br /&gt;
# As &amp;quot;Default Standard,&amp;quot; choose &amp;quot;Joomla&amp;quot; to use the Joomla! standard&lt;br /&gt;
# Now you can click &#039;&#039;OK&#039;&#039; to start sniffing&lt;br /&gt;
# Open from the top menu {{rarr|Source,Inspect}}&lt;br /&gt;
# Enjoy&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Eclipse === &amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:eclipse_pti.png|left|thumb|200px|1) Eclipse PTI]]&lt;br /&gt;
{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
Installation is a breeze and follows the usual pattern:&lt;br /&gt;
# {{rarr|Help,Install New Software}}&lt;br /&gt;
# &#039;&#039;Work with:&#039;&#039; Fill in one of the update site URLs found here: http://www.phpsrc.org/eclipse/pti/&lt;br /&gt;
# Select the desired tools&lt;br /&gt;
# Restart Eclipse.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:eclipse_pti_settings.png|right|thumb|150px|2) &amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt; Eclipse PTI settings&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; You are now able to sniff for code violations against common standards like PEAR or Zend etc.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt; To sniff against your own standards, specify their location and activate them (see screen shot 2)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
# {{rarr|Window,Preferences}}&lt;br /&gt;
# {{rarr|PHP Tools,PHP CodeSniffer}}&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:68--&amp;gt; Happy sniffing.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Geany === &amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
* Open a PHP file. (Otherwise the build menu is not accessible.) See this [http://static.xscreenshot.com/2016/07/13/08/screen_6bc0692cf995702a1e379b39643d0c2d Screenshot]&lt;br /&gt;
* On the top menu, select Build-&amp;gt;Set Build Commands.&lt;br /&gt;
* Select the second field and name it as you wish. Enter this code in the Command: &#039;&#039;phpcs --standard=Joomla &amp;quot;%f&amp;quot; | sed -e &#039;s/^/%f |/&#039; | egrep &#039;WARNING|ERROR&#039;&#039;&#039;&lt;br /&gt;
* Enter this code in the Error Regular Expression field: &#039;&#039;(.+) [|]\s+([0-9]+)&#039;&#039; See this  [http://view.xscreenshot.com/ef00820cf7c017ce659c8e9f0b02d3ae Screenshot]&lt;br /&gt;
* Select OK.&lt;br /&gt;
* If the Message Window is not open, display it by selecting it in the top View menu.&lt;br /&gt;
* When viewing any PHP file, press F9 to see the errors found. [http://view.xscreenshot.com/8704b9fd1bda3f841364a0ffa28a54ae Screenshot]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Atom === &amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
* Install phpcs and the Joomla standards as described above.&lt;br /&gt;
* In {{rarr|Atom,Preferences,Install}} install &#039;&#039;linter-phpcs&#039;&#039; and all its requirements.&lt;br /&gt;
* In {{rarr|Atom,Preferences,Packages,linter-phpcs,Settings}} adjust&lt;br /&gt;
** &#039;&#039;&#039;Executable Path&#039;&#039;&#039; to the path of your phpcs&lt;br /&gt;
** &#039;&#039;&#039;Code Standard Or Config File&#039;&#039;&#039;: Joomla&lt;br /&gt;
** &#039;&#039;&#039;Tab Width&#039;&#039;&#039;: 4&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== References === &amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* [https://github.com/joomla/coding-standards Joomla! Coding Standards]&lt;br /&gt;
* [https://www.phpsrc.org/ PTI - PHP tools integration for Eclipse]&lt;br /&gt;
* [https://sourceforge.net/projects/phpmdnb/ Netbeans plugin]&lt;br /&gt;
* https://hakre.wordpress.com/2010/03/06/php-code-sniffer-eclipse-and-wordpress/ - &amp;lt;translate&amp;gt;&amp;lt;!--T:75--&amp;gt; Excellent article. Just change &#039;&#039;Wordpress&#039;&#039; for &#039;&#039;Joomla&#039;&#039; ;)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:IDE (Integrated development environment){{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_CodeSniffer&amp;diff=1005944</id>
		<title>Joomla CodeSniffer</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_CodeSniffer&amp;diff=1005944"/>
		<updated>2023-07-05T01:02:02Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected some URLs. Other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== A Nose For Joomla == &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; This is a custom coding standard for the PHP CodeSniffer that attempts to codify and enforce the Joomla coding standards. This article covers how to set the automatic code style checker. It consists of three steps:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
# Install PHP CodeSniffer (phpcs).&lt;br /&gt;
# Clone the Joomla Code Style (for use with for phpcs).&lt;br /&gt;
# Configure your IDE to work with PHP CodeSniffer and Joomla Code Style.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:CodeSnifferInAction.jpg|center|thumb|300px|PHP Code Sniffer in action]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Why?== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; *Coherent and consistent coding practice makes the files look more professional. Conflicting styles in the same project (or worse, the same file) not only look sloppy, they encourage further sloppiness.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; *When all code complies with the same standard, bad code is easier for everyone to spot.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; *It makes it easier for someone new to a particular file in the project to find and fix errors or extend functionality.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; *If there is no consistent standard maintained, sometimes developers will reformat the code to suit themselves. This causes a wide range of changes in the code repository. If there is a later problem, a significant change could be lost in the chaff produced by a diff.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Installation of PHP Code Sniffer (phpcs)== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Composer=== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; PHP Code Sniffer is available via Composer. It can be installed system-wide with the following command:&amp;lt;/translate&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;composer global require --dev squizlabs/php_codesniffer &amp;quot;~3.5&amp;quot;&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
On &#039;&#039;&#039;Linux&#039;&#039;&#039; PHP Code Sniffer (phpcs) will be installed under your user folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;~/.composer/vendor/bin/phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;~/.composer/vendor/squizlabs/php_codesniffer/scripts/phpcs&#039;&#039;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:76--&amp;gt; To create that symbolic link, use on the command line: &amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;$ sudo ln -s ~/.config/composer/vendor/squizlabs/php_codesniffer/scripts /usr/bin/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt; or (for example OpenSuse)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;~/.config/composer/vendor/bin/phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;~/.config/composer/vendor/squizlabs/php_codesniffer/scripts/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt; On &#039;&#039;&#039;Windows&#039;&#039;&#039; PHP Code Sniffer (phpcs) will be installed under your user folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; Symbolic Link:&amp;lt;/translate&amp;gt; &#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\bin\phpcs&#039;&#039;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; The file:&amp;lt;/translate&amp;gt; &#039;&#039;c:\Users\Username\AppData\Roaming\Composer\vendor\squizlabs\php_codesniffer\scripts\phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add composer bin directory to your $PATH === &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
In order to execute PHP Code sniffer from anywhere on Linux or Mac command line you have to add &#039;&#039;.composer/vendor/bin&#039;&#039; to your $PATH variable.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
To do this persistent edit your shells start file, like your .profile or .bash_profile file depending which shell you are using (echo $SHELL shows you which one you are using).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; Add the following line to the file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;export PATH=$PATH:~/.composer/vendor/bin&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; Alternatively you can also create a symbolic link in the bin folder:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;ln -s ~/.composer/vendor/bin/phpcs /usr/local/bin/phpcs&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Install Joomla Coding Standards== &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt; In order to have PHP Code Sniffer (phpcs) sniffing your Joomla projects for the right code style, you have to install the Joomla Coding Standards.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; Using composer we can execute:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;composer global require --dev joomla/coding-standards &amp;quot;~3.0@alpha&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; Notice that it says &#039;&#039;@alpha&#039;&#039;, that is because the coding standard is still in alpha state and we need to allow the installation of alpha status code. If we do not include the @alpha the coding standards will not install and throw this error.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Your requirements could not be resolved to an installable set of packages.&lt;br /&gt;
&lt;br /&gt;
Problem 1&lt;br /&gt;
 - The requested package joomla/coding-standards ~3.0 is satisfiable by joomla/coding-standards[3.0.0-alpha, 3.0.0-alpha2, 3.x-dev] but these conflict with your requirements or minimum-stability.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt; Once the installation is done the coding standard will be installed in the global composer folder. The location of this folder depends on your operating system. Some popular locations are:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Mac / Linux&#039;&#039;&#039;&lt;br /&gt;
 ~/.composer/vendor/joomla/coding-standards/&lt;br /&gt;
&lt;br /&gt;
 ~/.config/composer/vendor/joomla/coding-standards/&lt;br /&gt;
&#039;&#039;&#039;Windows&#039;&#039;&#039;&lt;br /&gt;
 c:\Users\Username\AppData\Roaming\Composer\vendor\joomla\coding-standards\&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; This is using Composer on Windows.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; If you can&#039;t find it in any of the above folders, note that the folder you are looking for ends with &#039;&#039;&#039;\joomla\coding-standards\&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Finally we need to tell Code Sniffer that the Joomla coding standards exist.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Install Joomla Coding Standards&#039;&#039;&#039;&lt;br /&gt;
# Check if certain paths are already set by running &#039;&#039;phpcs --config-show&#039;&#039;&lt;br /&gt;
# You can get an answer that looks like this: &#039;&#039;installed_paths: /path/to/installation&#039;&#039;&lt;br /&gt;
# In step 2, if you see the &#039;&#039;&#039;installed_paths&#039;&#039;&#039; you need to copy that&lt;br /&gt;
# Set the Joomla Coding Standards path in phpcs by executing &#039;&#039;phpcs --config-set installed_paths /Users/user/.composer/vendor/joomla/coding-standards&#039;&#039;. If you copied any paths in step 2, include them here as well by separating them with a comma. The command looks like &#039;&#039;phpcs --config-set installed_paths [/to/path1],[/to/path2],[/Users/user/.composer/vendor/joomla/coding-standards]&#039;&#039;&lt;br /&gt;
# Verify the path is set correctly by running &#039;&#039;phpcs --config-show&#039;&#039;&lt;br /&gt;
# Verify that phpcs can see the Joomla codestyle by running &#039;&#039;phpcs -i&#039;&#039;&lt;br /&gt;
# The output should look like this: &#039;&#039;The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz, Zend and Joomla&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Usage == &amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; You invoke the custom standard by&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;phpcs --standard=Joomla file/to/sniff&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; To test a platform file using the provided platform coding standards, use&amp;lt;/translate&amp;gt;&lt;br /&gt;
&#039;&#039;phpcs --standard=build/phpcs/Joomla path/to/file/or/folder&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; Further documentation on the use of phpcs can be found at: [http://pear.php.net/package/PHP_CodeSniffer/docs]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==IDE Integration== &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; Everybody loves the console. It is, with no doubt, the most effective way to do whatever you need to do. Sometimes even Linux gurus need a little bit of comfort.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt; Fortunately there is a plug-in available for PhpStorm, Eclipse and Netbeans that integrates the CodeSniffer into your favourite IDE, so any coding standard violations are shown like &amp;quot;normal&amp;quot; errors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== PhpStorm === &amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; Code Sniffer is supported out of the box in PhpStorm. Go to Settings and under {{rarr|Editor,Inspections}} you will see the list of sniffers you have installed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Set Path to Code Sniffer ==== &amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Languages &amp;amp; Frameworks&lt;br /&gt;
# Click on PHP&lt;br /&gt;
# Click on Quality Tools&lt;br /&gt;
# Click on PHP cs fixer dropdown arrow&lt;br /&gt;
# The configuration is set to Local by default&lt;br /&gt;
# Click on the 3 dots behind it to open the configuration screen&lt;br /&gt;
# The first option is the PHP Code Sniffer (phpcs) path&lt;br /&gt;
# Click on the 3 dots behind the path to select the location of the phpcs file. See above on where phpcs may be installed on your site&lt;br /&gt;
# Click on Validate to make sure the path is correct and phpcs is working&lt;br /&gt;
# Click OK&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Activating the Joomla Code Style ===== &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Editor&lt;br /&gt;
# Click on Inspections&lt;br /&gt;
# In the list, go to PHP&lt;br /&gt;
# Click on PHP Code Sniffer Validation&lt;br /&gt;
# Click on the check box behind it to activate it&lt;br /&gt;
# Click the Reload button (2 arrows) to force a reload of rules from disk&lt;br /&gt;
# Joomla should now be available in the list. See following image:{{-}}[[File:PhpStorm8CodeSniffer.png|PHPStorm CodeSniffer|500px]]&lt;br /&gt;
# Click OK&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== PHP PSR-0, PSR-1 and PSR-2 ==== &amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md&lt;br /&gt;
* https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-1-basic.md&lt;br /&gt;
* https://github.com/pmjones/fig-standards/blob/psr-1-style-guide/proposed/PSR-2-advanced.md&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Using PHP PSR-1 and PSR-2 Sniff ===== &amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; A CodeSniffer sniff to check against the PSR-x Coding Standard can be used as well. In that case you can select a different standard than Joomla.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Using Joomla Code style ===== &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; It&#039;s nice to be able to check that the standards are respected. It&#039;s even nicer if PhpStorm helps you format properly too as you are coding.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
To use the Joomla code style in PhpStorm&lt;br /&gt;
# Open Settings (CTRL-ALT-S / CMD-,)&lt;br /&gt;
# Go to Editor&lt;br /&gt;
# Click on Code Style&lt;br /&gt;
# Select Joomla from the Scheme select box&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== PhpStorm / Alternative Method ==== &amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; &#039;&#039;&#039;NOTE&#039;&#039;&#039;: This method is &#039;&#039;&#039;outdated&#039;&#039;&#039;, but it might be useful if you are looking for a different integration. It also demonstrates the use of external tools in PhpStorm - so it &#039;&#039;shouldn&#039;t be deleted&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:77--&amp;gt; The Code Sniffer can also be integrated easily as an external tool. PhpStorm will display the output in the console, including click-able links containing line and column numbers to the files that contain errors.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
* Click on &amp;quot;Settings&amp;quot; and search for &amp;quot;External tools&amp;quot;&lt;br /&gt;
* Click &amp;quot;Add...&amp;quot;&lt;br /&gt;
* Choose a &amp;quot;Name&amp;quot;, &amp;quot;Group&amp;quot; and &amp;quot;Description&amp;quot;.&lt;br /&gt;
* Click &amp;quot;Output Filters&amp;quot;&lt;br /&gt;
** Click &amp;quot;Add...&amp;quot;, Choose a name and enter under &amp;quot;Regular expression to match output&amp;quot; the value: &#039;&#039;$FILE_PATH$:$LINE$:$COLUMN$&#039;&#039;&lt;br /&gt;
* &amp;quot;Program&amp;quot;: Search for the phpcs executable on your system. You have to set the path to the &#039;&#039;phpcs.bat&#039;&#039; from the installed PHP_CodeSniffer PEAR package&lt;br /&gt;
** For Unix based systems, the path is something like /usr/bin/phpcs&lt;br /&gt;
** In XAMPP (windows), you can find the file in the PHP root folder (e.g. C:\xampp\php\phpcs.bat)&lt;br /&gt;
* &amp;quot;Parameters&amp;quot;:&lt;br /&gt;
** &#039;&#039;--standard=&amp;lt;path/to/joomla-platform&amp;gt;/build/phpcs/Joomla&#039;&#039; The path to the Joomla! coding standards.&lt;br /&gt;
** &#039;&#039;--report=emacs&#039;&#039; The will generate a simple list containing links to the error files&lt;br /&gt;
** Optionally you may want to specify &#039;&#039;-p&#039;&#039; for &amp;quot;progress&amp;quot; or &#039;&#039;-n&#039;&#039; for &amp;quot;errors only&amp;quot;.&lt;br /&gt;
** The last parameter has to be &#039;&#039;$FilePath$&#039;&#039; specifying the file or folder you want to sniff.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; A typical &amp;quot;Parameters&amp;quot; line on a Linux system might look like this:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;-np --standard=/home/elkuku/libs/joomla/build/phpcs/Joomla --report=emacs $FilePath$&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt; You may now right click any file or folder and choose the sniffer from the context menu or add a new tool bar button with a nice Joomla! logo&amp;lt;/translate&amp;gt; [[File:icon-16-joomla.png]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Netbeans === &amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; Netbeans has the sniffer functionality integrated into the core system.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
# Start your Netbeans IDE&lt;br /&gt;
# Open {{rarr|Tools,Options,PHP,Code Analysis,Code Sniffer}}&lt;br /&gt;
# You have to set the path to &#039;&#039;phpcs.bat&#039;&#039; from the installed PHP_CodeSniffer PEAR package&lt;br /&gt;
#* For Unix based systems the path is something like /usr/bin/phpcs&lt;br /&gt;
#* In XAMPP (windows) you can find the file in the PHP root folder (e.g. C:\xampp\php\phpcs.bat)&lt;br /&gt;
# As &amp;quot;Default Standard,&amp;quot; choose &amp;quot;Joomla&amp;quot; to use the Joomla! standard&lt;br /&gt;
# Now you can click &#039;&#039;OK&#039;&#039; to start sniffing&lt;br /&gt;
# Open from the top menu Source =&amp;gt; Inspect...&lt;br /&gt;
# Enjoy&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Eclipse === &amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Image:eclipse_pti.png|left|thumb|200px|1) Eclipse PTI]]&lt;br /&gt;
{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
Installation is a breeze and follows the usual pattern:&lt;br /&gt;
# &#039;&#039;Help =&amp;gt; Install New Software...&#039;&#039;&lt;br /&gt;
# &#039;&#039;Work with:&#039;&#039; Fill in one of the update site URLs found here: http://www.phpsrc.org/eclipse/pti/&lt;br /&gt;
# Select the desired tools&lt;br /&gt;
# Restart Eclipse.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Image:eclipse_pti_settings.png|right|thumb|150px|2) &amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt; Eclipse PTI settings&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; You are now able to sniff for code violations against common standards like PEAR or Zend etc.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt; To sniff against your own standards, specify their location and activate them (see screen shot 2)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
# &#039;&#039;Window =&amp;gt; Preferences&#039;&#039;&lt;br /&gt;
# &#039;&#039;PHP Tools =&amp;gt; PHP CodeSniffer&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:68--&amp;gt; Happy sniffing.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Geany === &amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
* Open a PHP file. (Otherwise the build menu is not accessible.) See this [http://static.xscreenshot.com/2016/07/13/08/screen_6bc0692cf995702a1e379b39643d0c2d Screenshot]&lt;br /&gt;
* On the top menu, select Build-&amp;gt;Set Build Commands.&lt;br /&gt;
* Select the second field and name it as you wish. Enter this code in the Command: &amp;lt;code&amp;gt;phpcs --standard=Joomla &amp;quot;%f&amp;quot; | sed -e &#039;s/^/%f |/&#039; | egrep &#039;WARNING|ERROR&#039;&amp;lt;/code&amp;gt;&lt;br /&gt;
* Enter this code in the Error Regular Expression field: &amp;lt;code&amp;gt;(.+) [|]\s+([0-9]+)&amp;lt;/code&amp;gt; See this  [http://view.xscreenshot.com/ef00820cf7c017ce659c8e9f0b02d3ae Screenshot]&lt;br /&gt;
* Select OK.&lt;br /&gt;
* If the Message Window is not open, display it by selecting it in the top View menu.&lt;br /&gt;
* When viewing any PHP file, press F9 to see the errors found. [http://view.xscreenshot.com/8704b9fd1bda3f841364a0ffa28a54ae Screenshot]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Atom === &amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
* Install phpcs and the Joomla standards as described above.&lt;br /&gt;
* In {{rarr|Atom,Preferences,Install}} install &#039;&#039;linter-phpcs&#039;&#039; and all its requirements.&lt;br /&gt;
* In {{rarr|Atom,Preferences,Packages,linter-phpcs,Settings|| adjust&lt;br /&gt;
** &#039;&#039;&#039;Executable Path&#039;&#039;&#039; to the path of your phpcs&lt;br /&gt;
** &#039;&#039;&#039;Code Standard Or Config File&#039;&#039;&#039;: Joomla&lt;br /&gt;
** &#039;&#039;&#039;Tab Width&#039;&#039;&#039;: 4&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== References === &amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla/coding-standards - &amp;lt;translate&amp;gt;&amp;lt;!--T:72--&amp;gt; Joomla! Coding Standards&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://www.phpsrc.org/ &amp;lt;translate&amp;gt;&amp;lt;!--T:73--&amp;gt; PTI - PHP tools integration for Eclipse&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://sourceforge.net/projects/phpmdnb/ &amp;lt;translate&amp;gt;&amp;lt;!--T:74--&amp;gt; Netbeans plugin&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://hakre.wordpress.com/2010/03/06/php-code-sniffer-eclipse-and-wordpress/ - &amp;lt;translate&amp;gt;&amp;lt;!--T:75--&amp;gt; Excellent article. Just change &amp;quot;Wordpress&amp;quot; for &amp;quot;Joomla!&amp;quot; ;)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:IDE (Integrated development environment){{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Visual_Studio_Code&amp;diff=1005833</id>
		<title>Visual Studio Code</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Visual_Studio_Code&amp;diff=1005833"/>
		<updated>2023-07-01T21:37:35Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Xdebug 2 is no longer supported.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
[https://code.visualstudio.com/ Visual Studio Code (VSCode)] is a source code editor developed by Microsoft for Windows, Linux and MacOS (including M1 Macs). It includes support for debugging, embedded Git control and GitHub, syntax highlighting, intelligent code completion, snippets, and code refactoring.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The main characteristic of the editor is that it is extensible and it has a huge collection of extensions maintained by users and by Microsoft itself. See details at the [https://marketplace.visualstudio.com/ VSCode Extensions for Visual Studio Code] website.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
As a general introduction, this is a presentation about the topic [https://www.renekreijveld.nl/slides/juglondon/vscode.pdf Joomla Development with Visual Studio Code], by René Kreijveld, Joomla developer Destiny B.V. Joomla User Group London, 16th march 2021.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
On this page, we detail a list of recommended extensions to configure VSCode to support PHP and Joomla.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
This is a list of extensions to support PHP on VSCode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;PHP Debug&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug felixfbecker.php-debug]. Debug support for PHP with Xdebug.&lt;br /&gt;
* &#039;&#039;&#039;phpcs&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs ikappas.phpcs]. PHP CodeSniffer for Visual Studio Code.&lt;br /&gt;
* &#039;&#039;&#039;PHP Intelephense&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client bmewburn.vscode-intelephense-client]. PHP code intelligence for Visual Studio Code. Alternative: &#039;&#039;PHP IntelliSense&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense felixfbecker.php-intellisense]&lt;br /&gt;
* &#039;&#039;&#039;PHPUnit&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=emallin.phpunit emallin.phpunit]. Run PHPUnit tests from VSCode.&lt;br /&gt;
* &#039;&#039;&#039;phpfmt&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=kokororin.vscode-phpfmt kokororin.vscode-phpfmt]. The missing phpfmt extension for Visual Studio Code. The phpfmt formatter can parse and format even a PHP file version 4 if needed.&lt;br /&gt;
* &#039;&#039;&#039;php cs fixer&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=junstyle.php-cs-fixer junstyle.php-cs-fixer]: In case of opting for the [https://www.php-fig.org/psr/psr-2/ PSR-2: Coding Style Guide]). PHP CS Fixer extension for VS Code, PHP formatter, PHP code beautify tool, format HTML.&lt;br /&gt;
* &#039;&#039;&#039;PHP Namespace Resolver&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=MehediDracula.php-namespace-resolver MehediDracula.php-namespace-resolver]: PHP Namespace Resolver can import and expand your class. You can also sort your imported classes by line length or in alphabetical order.&lt;br /&gt;
* &#039;&#039;&#039;PHP Phan (Analyzer)&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=TysonAndre.php-phan tysonandre.php-phan]. Phan - static analyzer for PHP, minimizing false positives.&lt;br /&gt;
* &#039;&#039;&#039;phpmd&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=linyang95.phpmd linyang95.phpmd]. VS Code extension for PHP, using PHPMD.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
The Git protocol is natively supported on VSCode. However, there are extensions to improve code and repository management. This is a list of featured extensions for this task:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Git History&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory donjayamanne.githistory]: Git History, Search and More (including git log).&lt;br /&gt;
* &#039;&#039;&#039;GitHub&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-github KnisterPeter.vscode-github]: This VSCode extension integrates with GitHubExtensions for Visual Studio Code&lt;br /&gt;
* &#039;&#039;&#039;GitHub Pull Requests and Issues&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github GitHub.vscode-pull-request-github]: Review and manage your GitHub pull requests and issues directly in VS Code&lt;br /&gt;
* &#039;&#039;&#039;gitignore&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=codezombiech.gitignore codezombiech.gitignore]: A extension for Visual Studio Code that assists you in working with &#039;&#039;.gitignore&#039;&#039; files.&lt;br /&gt;
* &#039;&#039;&#039;Visual Studio Code Commitizen Support&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-commitizen KnisterPeter.vscode-commitizen]: This VSCode extension adds &#039;&#039;commitizen&#039;&#039; support.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
This is a list of extensions to support Joomla on VSCode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Joomla Snippets&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=AnibalSanchez.vs-code-joomla-snippets anibalsanchez.vs-code-joomla-snippets]. Snippets for Joomla including Joomla 3.x and Joomla 4 Snippets.&lt;br /&gt;
* &#039;&#039;&#039;PHP Getters &amp;amp; Setters&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=phproberto.vscode-php-getters-setters phproberto.vscode-php-getters-setters]. Create PHP getters and setters from class properties.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
This is a list of extensions to support remote SSH development:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Remote - SSH&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh ms-vscode-remote.remote-ssh]: The Remote - SSH extension lets you use any remote machine with an SSH server as your development environment. This can greatly simplify development and troubleshooting in a wide variety of situations. For more information: [https://code.visualstudio.com/docs/remote/ssh-tutorial Remote development over SSH]&lt;br /&gt;
* &#039;&#039;&#039;Live Share&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare MS-vsliveshare.vsliveshare]: Visual Studio Live Share enables you to collaboratively edit and debug with others in real-time, regardless of what programming languages you&#039;re using or app types you&#039;re building. It allows you to instantly (and securely) share your current project, and then as needed, share debugging sessions, terminal instances, localhost web apps, voice calls, and more!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
This is a list of handy extensions highly recommended to ease the development:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;EditorConfig for VS Code&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig editorconfig.editorconfig] EditorConfig Support for Visual Studio Code.&lt;br /&gt;
* &#039;&#039;&#039;change-case&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=wmaurer.change-case wmaurer.change-case]: Quickly change the case (camelCase, CONSTANT_CASE, snake_case, etc) of the current selection or current word.&lt;br /&gt;
* &#039;&#039;&#039;Project Manager&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager alefragnani.project-manager]: It helps you to easily access your projects, no matter where they are located. Don&#039;t miss those important projects anymore.&lt;br /&gt;
&lt;br /&gt;
== PHP Debug Configuration == &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The extension supports the most common configurations of PHP [https://xdebug.org/ Xdebug]. It fully integrates all VSCode features to debug PHP scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/xdebug/vscode-php-debug#installation official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
As a sample configuration for VSCode debugging, this is a common &#039;&#039;launch.json&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    // Use IntelliSense to learn about possible attributes.&lt;br /&gt;
    // Hover to view descriptions of existing attributes.&lt;br /&gt;
    // For more information, visit: https://code.visualstudio.com/docs/editor/debugging#_launch-configurations&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.2.0&amp;quot;,&lt;br /&gt;
    &amp;quot;configurations&amp;quot;: [&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
            &amp;quot;name&amp;quot;: &amp;quot;Listen for Xdebug&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;php&amp;quot;,&lt;br /&gt;
            &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
// Server Remote Xdebug Port - 9003 is the default Xdebug port&lt;br /&gt;
            &amp;quot;port&amp;quot;: 9003,&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
// Server Remote Path -&amp;gt; Local Project Path&lt;br /&gt;
            &amp;quot;pathMappings&amp;quot;: {&lt;br /&gt;
                &amp;quot;/app/www&amp;quot;: &amp;quot;${workspaceRoot}/www&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;name&amp;quot;: &amp;quot;Launch currently open script&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;php&amp;quot;,&lt;br /&gt;
            &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
            &amp;quot;program&amp;quot;: &amp;quot;${file}&amp;quot;,&lt;br /&gt;
            &amp;quot;cwd&amp;quot;: &amp;quot;${fileDirname}&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
// Local Xdebug Port - 9003 is the default Xdebug port&lt;br /&gt;
            &amp;quot;port&amp;quot;: 9003&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
Related to the &#039;&#039;launch.json&#039;&#039; configuration that &#039;&#039;felixfbecker/vscode-php-debug&#039;&#039; requires, it is the configuration of PHP Xdebug itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
Your development environment should have Xdebug 3. (Xdebug 2 is no longer supported.) To configure PHP Xdebug, these are the most common settings for &#039;&#039;php.ini&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
=== Xdebug 3 Configuration === &amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[Xdebug]&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
; xdebug-3.0.0&lt;br /&gt;
; https://xdebug.org/docs/upgrade_guide&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
xdebug.mode = debug&lt;br /&gt;
xdebug.start_with_request = yes&lt;br /&gt;
xdebug.discover_client_host = true&lt;br /&gt;
; xdebug.client_port = 9003&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:77--&amp;gt;&lt;br /&gt;
To know more about how Xdebug works internally to connect to the Editor, check the [https://xdebug.org/docs/ Xdebug 3 — Documentation].&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;phpcs&#039;&#039; Configuration == &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
The extension supports the most common configurations of [https://pear.php.net/package/PHP_CodeSniffer/ PHP_CodeSniffer].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
By default, PHP_CodeSniffer comes with several coding standards. Once the extension is installed, it works with &#039;&#039;PSR2&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpcs.standard&amp;quot;: &amp;quot;PSR2&amp;quot;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
To configure the extension to apply the &#039;&#039;&#039;Joomla! Coding Standards&#039;&#039;&#039;, install the rules following the [https://developer.joomla.org/coding-standards/html.html official guide].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
Once &#039;&#039;&#039;Joomla! Coding Standards&#039;&#039;&#039; is installed, configure the User Settings following this sample configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpcs.standard&amp;quot;: &amp;quot;/home/YOUR-USER/.../Joomla&amp;quot;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuration of PHP Intelephense == &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/bmewburn/vscode-intelephense#quick-start official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
The extension does not require additional configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
VSCode comes with basic support of the PHP language. It is a good idea to disable the default support to avoid conflicts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    // Disable basic suggestions&lt;br /&gt;
    &amp;quot;php.suggest.basic&amp;quot;: false,&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
// To activate code suggestions in comments&lt;br /&gt;
    &amp;quot;editor.quickSuggestions&amp;quot;: { &amp;quot;comments&amp;quot;: true },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
As an alternative, it is also a popular extension: &#039;&#039;&#039;PHP IntelliSense&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense felixfbecker.php-intellisense] Advanced Autocompletion and Refactoring support for PHP.&lt;br /&gt;
&lt;br /&gt;
== PHPUnit Configuration == &amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/elonmallin/vscode-phpunit#setup official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
The extension integrates [https://phpunit.de/ PHP Unit] with VSCode, so all features of PHP Unit are integrated with VSCode and can also be parameterized for further integration with the user interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
This is a sample configuration of the extension:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpunit.preferRunClassTestOverQuickPickWindow&amp;quot;: true,&lt;br /&gt;
    &amp;quot;phpunit.driverPriority&amp;quot;: [&lt;br /&gt;
        &amp;quot;Path&amp;quot;,&lt;br /&gt;
        &amp;quot;Command&amp;quot;,&lt;br /&gt;
        &amp;quot;Composer&amp;quot;,&lt;br /&gt;
        &amp;quot;Phar&amp;quot;,&lt;br /&gt;
        &amp;quot;Ssh&amp;quot;,&lt;br /&gt;
        &amp;quot;GlobalPhpUnit&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PHP CS Fixer Configuration (Only for PSR2) == &amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/junstyle/vscode-php-cs-fixer#installation official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
The extension integrates [https://github.com/PHP-CS-Fixer/PHP-CS-Fixer PHP CS Fixer] with VSCode, so all features of PHP CS Fixer are integrated with VSCode and can also be parameterized for further integration with the user interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
To automatically apply PHP CS Fixer to PHP files, configure the user settings in this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;[php]&amp;quot;: {&lt;br /&gt;
        &amp;quot;editor.defaultFormatter&amp;quot;: &amp;quot;junstyle.php-cs-fixer&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;php-cs-fixer.onsave&amp;quot;: true,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PHP Phan (Analyzer) Configuration == &amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://marketplace.visualstudio.com/items?itemName=TysonAndre.php-phan official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
This is a sample configuration of the extension:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phan.phpExecutablePath&amp;quot;: &amp;quot;/usr/bin/php&amp;quot;,&lt;br /&gt;
    &amp;quot;phan.analyzedFileExtensions&amp;quot;: [&lt;br /&gt;
        &amp;quot;php&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;phpmd&#039;&#039; Configuration == &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/xdebug/vscode-php-debug#installation official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
The extension does not require additional configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
This is a sample configuration of the extension:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpmd.command&amp;quot;: &amp;quot;php /home/YOUR-USER/.../phpmd/phpmd.phar&amp;quot;,&lt;br /&gt;
    &amp;quot;phpmd.rules&amp;quot;: &amp;quot;/home/YOUR-USER/.../phpmd-rulesets/phpmd_config.xml&amp;quot;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure EditorConfig for VS Code == &amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
EditorConfig is a file format and collection of text editor plugins for maintaining consistent coding styles between different editors and IDEs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
To configure the editor according to your preferences, create a file &#039;&#039;.editorconfig&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
; EditorConfig helps developers define and maintain consistent&lt;br /&gt;
; coding styles between different editors and IDEs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:60--&amp;gt;&lt;br /&gt;
; For more visit https://editorconfig.org/&lt;br /&gt;
root = true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
; Choose between lf or rf on &amp;quot;end_of_line&amp;quot; property&lt;br /&gt;
[*]&lt;br /&gt;
charset = utf-8&lt;br /&gt;
end_of_line = lf&lt;br /&gt;
indent_size = 2&lt;br /&gt;
indent_style = space&lt;br /&gt;
insert_final_newline = true&lt;br /&gt;
trim_trailing_whitespace = true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
# editorconfig-tools is unable to ignore longs strings or URLs&lt;br /&gt;
max_line_length = null&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
[*.html]&lt;br /&gt;
indent_style = tab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
# PSR-2&lt;br /&gt;
# [*.php]&lt;br /&gt;
# indent_size = 4&lt;br /&gt;
# indent_style = space&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:65--&amp;gt;&lt;br /&gt;
# Joomla! Coding Standards&lt;br /&gt;
[*.php]&lt;br /&gt;
indent_size = 4&lt;br /&gt;
indent_style = tab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
[*.md]&lt;br /&gt;
trim_trailing_whitespace = false&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
[*.yml]&lt;br /&gt;
indent_style = space&lt;br /&gt;
indent_size = 2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Beginner_Development{{#translation:}}]]&lt;br /&gt;
[[Category:Server configurations{{#translation:}}]]&lt;br /&gt;
[[Category:Server setup local{{#translation:}}]]&lt;br /&gt;
[[Category:Server configurations{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:IDE (Integrated development environment){{#translation:}}]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Setting_up_your_workstation_for_Joomla_development&amp;diff=1005737</id>
		<title>Setting up your workstation for Joomla development</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Setting_up_your_workstation_for_Joomla_development&amp;diff=1005737"/>
		<updated>2023-06-29T21:16:24Z</updated>

		<summary type="html">&lt;p&gt;Cmb: URL correction. Other text editing.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt; This page is centered around developing on and with Joomla. If you find yourself stuck following any of these tutorials, please visit [[jforum:810|our Installation forums]] for more information.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Installing a Web Server == &amp;lt;!--T:2--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt; Installing a typical web server environment is easy with [[wikipedia:List_of_AMP_packages|AMP packages]] (Apache, MySQL, PHP).&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt; [https://www.apachefriends.org/ XAMPP] at Apache Friends (Multiple operating systems)&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; [[XAMPP]] (for Joomla 1.5 and 2.5 please view [[J2.5:XAMPP|XAMPP for Joomla 2.5]])&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; [[wikipedia:LAMP (software bundle)|LAMP]] (Linux)&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; [[Configuring a LAMPP server for PHP development]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; [[wikipedia:WAMP|WAMP]] (Windows) A good choice for a local server environment for Windows is [https://www.wampserver.com/en/ WampServer].&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt; [[wikipedia: MAMP|MAMP]] (Macintosh / OS X) [https://www.mamp.info/en/windows/ MAMP] may be a good choice.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt; [https://bitnami.com/stack/joomla Bitnami] also offers a Joomla stack that you can install locally or on a remote server.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; If you want use XDebug for debugging, you&#039;ll need to tune the PHP settings&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; [[Edit PHP.INI File for XDebug]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Installing an IDE/Editor (and Debugging)== &amp;lt;!--T:12--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt; [[wikipedia:Visual_Studio_Code|Visual Studio Code]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt; &amp;lt;!--T:43--&amp;gt; [[Visual_Studio_Code|Configuring Visual Studio Code for Joomla development]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; PhpStorm IDE&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt; [https://www.jetbrains.com/help/phpstorm/joomla-specific-coding-assistance.html Joomla! Development with PhpStorm] &amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; [[wikipedia:Eclipse (software)|Eclipse IDE]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; [[Configuring Eclipse for joomla development]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt; [[How to configure Eclipse IDE for PHP development]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; [[Configuring Eclipse IDE for PHP development]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; [https://community.joomla.org/blogs/community/webinar-using-eclipse-for-joomla-development.html Using Eclipse for Joomla! Development] Video webinar demonstrating overview of Eclipse features for Joomla! development&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt; [[wikipedia:ActiveState_Komodo|Komodo Edit]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
** &amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; [[Configuring Komodo Edit for Joomla Code Completion]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; [[wikipedia:NetBeans|NetBeans]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt; UltraEdit, Notepad++...&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt; Sublime Text 2 Editor&amp;lt;/translate&amp;gt;&lt;br /&gt;
**&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; [https://code.tutsplus.com/courses/perfect-workflow-in-sublime-text-2 Perfect Workflow in Sublime Text 2 tutorial]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Debugging Specifics === &amp;lt;!--T:27--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; [[Running Automated Tests for the Joomla CMS]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; [[How to debug your code]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Using Git == &amp;lt;!--T:30--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; The CMS project uses the Git version control system and the CMS repository is stored on [https://github.com/joomla/joomla-cms GitHub]. Bugs are fixed in the master branch of this repository, and normally there are bug fixes and changes in the master branch that are more recent than the latest released Joomla version. For this reason, when we test and code bug fixes, we normally use the latest code from the master branch on GitHub, not the latest released version. Therefore, Bug Squad testers and coders need to understand how to use Git and the GitHub repository.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; For testing and tracking changes, please refer to [[Git for Testers and Trackers]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt; For creating your first code change (called a Pull Request), see [[Working with git and github/My first pull request]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt; For working with Git, please see [[Git for Coders]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Related == &amp;lt;!--T:35--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; [[Setting up your workstation for PHP development]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; [[Joomla Issue shortcut]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; [[Browser Shortcut Issue Tracker]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* [[J4.x:Setting_Up_Your_Local_Environment|&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt; Setting up your local environment for Joomla 4]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; Help is appreciated finding related pages and making these pages less redundant.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Beginner_Development{{#translation:}}]]&lt;br /&gt;
[[Category:Server configurations{{#translation:}}]]&lt;br /&gt;
[[Category:Server setup local{{#translation:}}]]&lt;br /&gt;
[[Category:Server configurations{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:IDE (Integrated development environment){{#translation:}}]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Edit_PHP.INI_File_for_XDebug&amp;diff=1005736</id>
		<title>Edit PHP.INI File for XDebug</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Edit_PHP.INI_File_for_XDebug&amp;diff=1005736"/>
		<updated>2023-06-29T20:57:05Z</updated>

		<summary type="html">&lt;p&gt;Cmb: URL corrections. Other text editing.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==For Windows==&lt;br /&gt;
Starting with version 1.7, XAMPP includes the XDebug PHP debugger, but it needs to be configured for use. To do that, we will edit the &#039;&#039;php.ini&#039;&#039; file to configure XDebug. The &#039;&#039;Loaded Configuration File&#039;&#039; tells you which &#039;&#039;php.ini&#039;&#039; file is being used. For Windows, this is normally &#039;&#039;c:\xampp\apache\bin\php.ini&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Important note for Windows 7 &amp;amp; Vista users: As of August 2013 (XAMPP version 1.8.2), the file &#039;&#039;php_xdebug.dll&#039;&#039; that is included with XAMPP now works with Windows 7 &amp;amp; Vista. In some earlier versions of XAMPP, the distributed version of XDebug did not work correctly. The symptom of this earlier problem was that the Apache server would stop if this version of XDebug is loaded. To check that you are running the correct version of XDebug on your system, [https://xdebug.org/wizard follow these instructions] on the XDebug site.&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
We need to edit this file to configure XDebug as follows:&lt;br /&gt;
# Find the line &#039;&#039;implicit_flush&#039;&#039; and set it as follows: &amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;implicit_flush = On&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Find the section called &#039;&#039;[Zend]&#039;&#039; and comment out all of the lines by putting a semicolon (;) at the start of each line.&lt;br /&gt;
# Find the line: &#039;&#039;zend_extension = &amp;quot;c:\xampp\php\ext\php_xdebug.dll&amp;quot;&#039;&#039; and uncomment it.&lt;br /&gt;
# Find the &#039;&#039;[XDebug]&#039;&#039; section and uncomment all of the lines (except for the first comment line). For Windows, it should look like the example below:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
[XDebug]&lt;br /&gt;
; Only Zend OR (!) XDebug&lt;br /&gt;
zend_extension_ts=&amp;quot;C:\xampp\php\ext\php_xdebug.dll&amp;quot;&lt;br /&gt;
xdebug.remote_enable=true&lt;br /&gt;
xdebug.remote_host=localhost&lt;br /&gt;
xdebug.remote_port=10000&lt;br /&gt;
xdebug.remote_handler=dbgp&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You do not need to enable XDebug profiling to use XDebug to debug Joomla code. Profiling allows you to find performance bottlenecks in your PHP code. However, enabling profiling with XDebug can slow down your system substantially, so it is not recommended unless you need it. To enable XDebug profiling, add these entries to your &#039;&#039;php.ini&#039;&#039; file.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
xdebug.profiler_enable=1&lt;br /&gt;
xdebug.profiler_output_dir=&amp;quot;C:\xampp\tmp&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For Windows 7 &amp;amp; Vista, you will use the file downloaded from the XDebug site. So the first line will be&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
zend_extension_ts=&amp;quot;C:\xampp\php\ext\php_xdebug-2.0.0-5.2.2.dll&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For PHP version 5.3 and later, the &#039;&#039;_ts&#039;&#039; has been dropped, so the first line will read:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
zend_extension=&amp;quot;C:\xampp\php\ext\php_xdebug.dll&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In XAMPP 1.7.3 on Windows 7, XDebug may not work correctly if the path to the DLL file is in quotes. In this case, the line should be&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
zend_extension = C:\xampp\php\ext\php_xdebug-2.1.0-5.3-vc6.dll&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==For Linux==&lt;br /&gt;
We will edit the &#039;&#039;php.ini&#039;&#039; file to configure XDebug. The &#039;&#039;Loaded Configuration File&#039;&#039; in your &#039;&#039;phpinfo&#039;&#039; display tells you what &#039;&#039;php.ini&#039;&#039; file is being used. For Linux, it will be something like &#039;&#039;/etc/php/7.2/apache2/php.ini&#039;&#039;. (The PHP configuration is available in the Administrator of your website: {{rarr|Administrator,System,System Information,PHP Information}} tab&#039;&#039;.)&lt;br /&gt;
&lt;br /&gt;
Edit this file to configure XDebug as follows:&lt;br /&gt;
# Find the line &#039;&#039;implicit_flush&#039;&#039; and set it as follows: &amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;implicit_flush = On&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Add the following lines at the end: &amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
;xDebug Configuration starts&lt;br /&gt;
&lt;br /&gt;
zend_extension = /opt/lampp/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so&lt;br /&gt;
&lt;br /&gt;
xdebug.profiler_output_dir = &amp;quot;/tmp/xdebug/&amp;quot;&lt;br /&gt;
xdebug.profiler_enable = On&lt;br /&gt;
xdebug.remote_enable=On&lt;br /&gt;
xdebug.remote_host=&amp;quot;localhost&amp;quot;&lt;br /&gt;
xdebug.remote_port=10000&lt;br /&gt;
xdebug.remote_handler=&amp;quot;dbgp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;xDebug Configuration ends &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===If Using &#039;&#039;php5-xdebug&#039;&#039; on Ubuntu===&lt;br /&gt;
The xDebug Configuration detailed above can be appended to:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;/etc/php5/apache2/conf.d/xdebug.ini &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
It should already contain the &#039;&#039;zend_extension&#039;&#039; variable and only needs the following variables added:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
xdebug.profiler_enable = On&lt;br /&gt;
xdebug.remote_enable=On&lt;br /&gt;
xdebug.remote_host=&amp;quot;localhost&amp;quot;&lt;br /&gt;
xdebug.remote_port=10000&lt;br /&gt;
xdebug.remote_handler=&amp;quot;dbgp&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Tip for Users with LAN or Remote Servers===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;xdebug.remote_host=&amp;quot;localhost&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Should be set to the IP address of your Eclipse workstation [LAN users] or your public IP. For example:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;xdebug.remote_host=192.168.0.199&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==For Mac OS X==&lt;br /&gt;
XAMPP for Mac OS X includes the XDebug PHP debugger, but it needs to be added to the &#039;&#039;php.ini&#039;&#039; file so that XDebug runs when Apache is started. To do this, open up the &#039;&#039;php.ini&#039;&#039; file, located at &#039;&#039;/Applications/XAMPP/xamppfiles/etc/php.ini&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Edit this file to configure XDebug:&lt;br /&gt;
# Find the line &#039;&#039;implicit_flush&#039;&#039; and set it as follows: &amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;implicit_flush = On&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
# Add the following lines at the end:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
;xDebug Configuration starts&lt;br /&gt;
&lt;br /&gt;
zend_extension=&amp;quot;/Applications/XAMPP/xamppfiles/lib/php/php-5.3.1/extensions/no-debug-non-zts-20090626/xdebug.so&amp;quot;&lt;br /&gt;
&lt;br /&gt;
xdebug.profiler_output_dir = &amp;quot;/tmp/xdebug/&amp;quot;&lt;br /&gt;
xdebug.profiler_enable = On&lt;br /&gt;
xdebug.remote_enable=On&lt;br /&gt;
xdebug.remote_host=&amp;quot;localhost&amp;quot;&lt;br /&gt;
xdebug.remote_port=10000&lt;br /&gt;
xdebug.remote_handler=&amp;quot;dbgp&amp;quot;&lt;br /&gt;
&lt;br /&gt;
;xDebug Configuration ends&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Be sure to navigate to the directory where you targeted the extension and verify that the file path is correct. The folders in your XAMPP installation may be named differently.&lt;br /&gt;
&lt;br /&gt;
The current (as of Sept 2010) version of the XAMPP binary for OS X contains the 2.0.4 version of XDebug which will not let you see the variable data from included files when running XDebug. You can download a newer version from the [https://code.activestate.com/komodo/remotedebugging/ ActiveState website]. Unzip and copy one of the &#039;&#039;xdebug.so&#039;&#039; files to &#039;&#039;/Applications/XAMPP/xamppfiles/lib/php/php-5.3.1/extensions/no-debug-non-zts-20090626&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Test the XDebug Installation==&lt;br /&gt;
Now we need to verify that XDebug is installed correctly. Restart XAMPP. In Windows, we can just browse to the &#039;&#039;c:\xampp&#039;&#039; folder in Windows Explorer and double-click the program &#039;&#039;xampp-control.exe&#039;&#039; to open the application shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:Xampp-control.png]]&lt;br /&gt;
&lt;br /&gt;
Press the &#039;&#039;Stop&#039;&#039; button for &#039;&#039;Apache&#039;&#039;. The button with then read &#039;&#039;Start&#039;&#039;. Press &#039;&#039;Start&#039;&#039; for Apache and wait a few seconds and the green &#039;&#039;Running&#039;&#039; message will again display. Then press &#039;&#039;Exit&#039;&#039; to close the application.&lt;br /&gt;
&lt;br /&gt;
In Windows, if you get &#039;&#039;ERROR: MySQL service not started [-1]&#039;&#039;, you may be able to correct this by going to &#039;&#039;c:\xampp\mysql&#039;&#039; and running &#039;&#039;mysql_uninstallservice.bat&#039;&#039; followed by &#039;&#039;mysql_installservice.bat&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
In Linux, to restart LAMPP execute the command:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;shell&amp;quot;&amp;gt;&lt;br /&gt;
 sudo /opt/lampp/lampp restart&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Mac, open the &#039;&#039;XAMPP Control&#039;&#039; application, stop, and then start the Apache service.&lt;br /&gt;
&lt;br /&gt;
Once XAMPP has been restarted, open a browser and navigate to http://localhost to display the XAMPP welcome message. (If you set XAMPP to listen to another port, you must append the port to the URL. For example: http://localhost:8080/). Press the &#039;&#039;phpinfo()&#039;&#039; link again to display the PHP information screen. Scroll down to the lower part of the screen. You should see a section for &#039;&#039;XDebug&#039;&#039; as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:Phpinfo_xdebug.png]]&lt;br /&gt;
&lt;br /&gt;
Look at the settings you entered in the &#039;&#039;php.ini&#039;&#039; file above. You should see these same settings in the XDebug display, as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:Xdebug settings.png]]&lt;br /&gt;
&lt;br /&gt;
At this point, XDebug is set up correctly.&lt;br /&gt;
&lt;br /&gt;
[[Category:Bug Squad]]&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_to_debug_your_code&amp;diff=1005735</id>
		<title>How to debug your code</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_to_debug_your_code&amp;diff=1005735"/>
		<updated>2023-06-29T20:04:08Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected some URLs.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==The Easy Way 1 (&#039;&#039;echo&#039;&#039;)== &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; The simplest way to see what is going on inside your code is to temporarily add &#039;&#039;echo&#039;&#039; statements for variables to show their values on the screen. For example, say you want to know what the value of some variables are when $i is &amp;quot;5&amp;quot;. You could use code like this:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;for ( $i = 0; $i &amp;lt; 10; $i++ ) {&lt;br /&gt;
	if ( $i == 5 ) {&lt;br /&gt;
		echo &#039;$i=&#039; . $i;&lt;br /&gt;
                // other echo statements&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt; This works for simple situations. However, if you are planning on doing a lot of Joomla! development, it is worth the effort to install and learn an integrated development environment (IDE) that includes a real PHP debugger.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==The Easy Way 2 (Joomla &#039;&#039;message&#039;&#039;)== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; Your code won&#039;t always display simple echo statements. In that case you can try this alternative, still an easy way:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;JFactory::getApplication()-&amp;gt;enqueueMessage(&#039;Some debug string(s)&#039;);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; You can choose different [[Display_error_messages_and_notices|message types]] which correspond to grouping with different styles (colors mainly).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Joomla Logging== &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; Joomla allows you to log messages to a log file, and optionally also display these on the web page (in the same way as &#039;&#039;enqueueMessage&#039;&#039; above) and on the Joomla Debug Console (described below).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt; To log a message in the log file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
JLog::add(&#039;my error message&#039;, JLog::ERROR);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; To log a message and also display it on the screen:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
JLog::add(&#039;my error message&#039;, JLog::ERROR, &#039;jerror&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; Logging to the log file and to the Debug Console is controlled via the settings of the System – Debug plugin. To understand how this works, and the relevant settings of the System-Debug plugin, read the Joomla documentation page on [[S:MyLanguage/Using JLog|Using JLog]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Using an IDE== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt; Check this &amp;lt;/translate&amp;gt;[https://www.youtube.com/watch?v=sP4dHAuq2kc 3 minute video]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; that shows how you can debug your code with a browser and an IDE&amp;lt;/translate&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|sP4dHAuq2kc}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; Many Joomla! developers use the Eclipse IDE. This is free and includes a debugger. Instructions for installing it are available at [[S:Mylanguage/Setting up your workstation for Joomla development|Setting up your workstation for Joomla development]], or you can watch this video on setting up Eclipse and Xdebug.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=MiIEF8-XAkc}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Using the PHP Expert Editor== &amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; Another option is the PHP Expert editor with an installed extension for debugging. Add the following lines to the &#039;&#039;php.ini&#039;&#039; file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 extension=php_dbg.dll&lt;br /&gt;
 [Debugger]&lt;br /&gt;
 debugger.enabled=on&lt;br /&gt;
 debugger.profiler_enabled=off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; It is best to set &#039;&#039;profiler_enable&#039;&#039; to &#039;&#039;off&#039;&#039;. Then you need to set options in the Run/Options menu to use HTTP-server and the directory in which your script is located.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
If all options are correct, you may run your script in debug mode by clicking on the Debug button (F8).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==J!Dump== &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; An often handy extension that can be found in the JED is the J!Dump extension that will allow you to dump variable, stack traces, and system information into a popup window at run time. This extension works like the PHP command &#039;&#039;var_dump&#039;&#039; but formats the output in a more readable fashion.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Joomla Debug Console== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt; The Debug Console can be enabled from the Joomla! Global Configuration, System tab, by setting the Debug System option to Yes. Once enabled, the output of the debug plugin will be displayed at the bottom of each page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[File:Jdebug-module-&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg|&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; The JDebug Plugin output&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; Setting this Debug System option also sets the global variable &#039;&#039;JDEBUG&#039;&#039; to true, so that you can control whether to log messages by testing this variable:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
if(JDEBUG)&lt;br /&gt;
{&lt;br /&gt;
    // whatever debugging code you want to run, e.g.&lt;br /&gt;
    JLog::add(&#039;my debug message&#039;, JLog::DEBUG, &#039;my-debug-category&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
This plugin provides information that can assist in debugging and improving the performance of your component.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Session Information=== &amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; This section displays state variables which are stored in the Session data to enable them to be &#039;remembered&#039; across HTTP requests. Examples include variables defining the current search filters the user has defined, the pagination point in a list of records, etc.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:session-&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Profile Information=== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; The Profile Information tab from the debug plugin provides information about the time and memory taken to render the page based on each of the application events. This can help to identify areas outside of network speed that are contributing to long page load times and high server memory usage.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Jdebug-profile-&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg|&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt; JDEBUG Profile&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Database Queries=== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; One of the most useful tabs is the Database Queries tab. This will provide a log of all queries that have been executed while loading the page and identify both the time taken to execute the query and whether duplicate queries have occurred. This is particularly useful when debugging performance problems on larger components as duplicate queries are often a contributing factor.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Jdebug-query-&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Komodo IDE== &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[S:MyLanguage/Debugging Joomla with Komodo IDE|Debugging Joomla with Komodo IDE]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Video{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development/Mac&amp;diff=1005734</id>
		<title>Configuring Xdebug for PHP development/Mac</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development/Mac&amp;diff=1005734"/>
		<updated>2023-06-29T17:36:55Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup and phrasing changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Configuring XDebug with MAMP ==&lt;br /&gt;
&lt;br /&gt;
=== Prerequisites ===&lt;br /&gt;
These instructions are for Mac OS X (actually tested on version 10.9.2 Mavericks) with installed MAMP Application (actually tested on MAMP version 3.0.4).&lt;br /&gt;
&lt;br /&gt;
=== Configuration Instructions ===&lt;br /&gt;
*Open finder and navigate to&lt;br /&gt;
 &amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt; /Applications/MAMP/conf/&amp;lt;selected php version&amp;gt;/ &amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
(NOTE: &amp;lt;selected php version&amp;gt; is the PHP version that you have selected in the MAMP configuration)&lt;br /&gt;
*Open the file &#039;&#039;php.ini&#039;&#039; with a text editor such as TextWrangler&lt;br /&gt;
*Find the section [xdebug]&lt;br /&gt;
*Uncomment the line&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt; &lt;br /&gt;
 [xdebug]&lt;br /&gt;
 ;zend_extension=&amp;quot;/Applications/MAMP/bin/php/&amp;lt;selected php version&amp;gt;/lib/php/extensions/no-debug-non-zts-20121212/xdebug.so&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
by removing the semicolon character at the beginning of the line.&lt;br /&gt;
*Add after the line the following text, if not already existing&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;text&amp;quot;&amp;gt; &lt;br /&gt;
 xdebug.remote_enable=on&lt;br /&gt;
 xdebug.remote_handler=dbgp&lt;br /&gt;
 xdebug.remote_host=localhost&lt;br /&gt;
 xdebug.remote_port=9000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Save changes and close the editor&lt;br /&gt;
*Restart your MAMP Server&lt;br /&gt;
Note: You can set a different port number if you need.&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development&amp;diff=1005733</id>
		<title>Configuring Xdebug for PHP development</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development&amp;diff=1005733"/>
		<updated>2023-06-29T17:28:03Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some capitalization and phrasing changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;XDebug is an extension that provides debugging and profiling capabilities. It runs in the server side and sends the debugging information to any client capable of receiving and reading it. For this article we will install XDebug in our local server and use Eclipse IDE as the client which will receive and interpret the debugging information. With XDebug you will be able to study the behavior of your code step by step and also inspect the value of the any variable at every execution step.&lt;br /&gt;
=Linux OS=&lt;br /&gt;
{{:Configuring Xdebug for PHP development/Linux}}&lt;br /&gt;
=Windows OS=&lt;br /&gt;
{{:Configuring Xdebug for PHP development/Windows}}&lt;br /&gt;
=Mac OS=&lt;br /&gt;
{{:Configuring Xdebug for PHP development/Mac}}&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development/Linux&amp;diff=1005732</id>
		<title>Configuring Xdebug for PHP development/Linux</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development/Linux&amp;diff=1005732"/>
		<updated>2023-06-29T17:23:29Z</updated>

		<summary type="html">&lt;p&gt;Cmb: URL corrections. Other text editing.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Theses instructions should work fine on any Debian based distribution such as Debian, Ubuntu, Linux Mint, Xubuntu, Kubuntu and others.&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
There are several ways to download and install XDebug to your Linux box, you can do it from your software center, terminal or manual download.&lt;br /&gt;
&lt;br /&gt;
=== Method 1: From a Linux Repository  ===&lt;br /&gt;
{{tip|This is the recommended method because you will get updates and security patches automatically.}}&lt;br /&gt;
&lt;br /&gt;
==== Option 1: Terminal  ====&lt;br /&gt;
*Open your terminal and type&lt;br /&gt;
 &amp;lt;tt&amp;gt; sudo apt-get install php5-xdebug &amp;lt;/tt&amp;gt;&lt;br /&gt;
*Wait until the installation process finishes&lt;br /&gt;
&lt;br /&gt;
==== Option 2: Software Center  ====&lt;br /&gt;
*Open the software center that comes with your distribution&lt;br /&gt;
*Type in the search box &amp;quot;Eclipse IDE&amp;quot;&lt;br /&gt;
*Select &amp;quot;Eclipse IDE&amp;quot; in the search result list&lt;br /&gt;
*Click on the &amp;quot;install&amp;quot; button&lt;br /&gt;
*Wait until installation processes finishes&lt;br /&gt;
&lt;br /&gt;
=== Method 2: From a Downloaded Copy  ===&lt;br /&gt;
* Visit this page [https://packages.debian.org/bookworm/php-xdebug here] and download the most recent version available&lt;br /&gt;
* Do a double click on the downloaded file, your package manager should do the rest of the work automatically&lt;br /&gt;
&lt;br /&gt;
== Configuring XDebug ==&lt;br /&gt;
Open your terminal and type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;sudo gedit /etc/php5/mods-available/xdebug.ini&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If the file is empty try this location:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;sudo gedit /etc/php5/conf.d/xdebug.ini&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That command should open the text editor with the XDebug configuration file.&lt;br /&gt;
&lt;br /&gt;
At the end of the file content append the following text:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;xdebug.remote_enable=on&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;xdebug.remote_handler=dbgp&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;xdebug.remote_host=localhost&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;xdebug.remote_port=9000&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Save changes and close the editor.&lt;br /&gt;
&lt;br /&gt;
In your terminal, type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;tt&amp;gt;sudo service apache2 restart&amp;lt;/tt&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note: You can set a different port number if you need to.&lt;br /&gt;
&lt;br /&gt;
== Configuring Eclipse IDE ==&lt;br /&gt;
*Open Eclipse IDE.&lt;br /&gt;
*On Eclipse go to: {{rarr|Toolbar,Window,Preferences,PHP,Debug}}&lt;br /&gt;
*Find the option: &amp;quot;PHP Debugger&amp;quot; and set it to &amp;quot;Xdebug&amp;quot;&lt;br /&gt;
*On Eclipse go to: {{rarr|Toolbar,Window,Preferences,PHP,Debug,Installed Debugger}}&lt;br /&gt;
*In the list make sure the port the &amp;quot;Xdebug&amp;quot; option is set to the value &amp;quot;9000&amp;quot;&lt;br /&gt;
*Save changes.&lt;br /&gt;
Note: You can set a different port number if necessary.&lt;br /&gt;
&lt;br /&gt;
When you debug a PHP project, Xdebug stops the code execution of the current page and Eclipse IDE by default pops out a perspective with 2 views containing the internal Eclipse IDE web browser and a view with the current HTML output. If you don&#039;t like the internal web browser, you can use any other external web browser installed in your computer, such as Google Chrome, Chromium, Firefox and so on.&lt;br /&gt;
&lt;br /&gt;
To set up a different web browser, follow these steps. If you are okay with the Eclipse internal browser, skip this part.&lt;br /&gt;
&lt;br /&gt;
*On Eclipse, go to: {{rarr|Toolbar,Window,Preferences,General,Web Browser}}&lt;br /&gt;
*Make sure the option &amp;quot;Use external browser&amp;quot; is selected.&lt;br /&gt;
*If your preferred browser is on the list, select it and save changes. Skip the rest of this part.&lt;br /&gt;
*If your preferred browser is not on the list, press the button &amp;quot;New&amp;quot;&lt;br /&gt;
*Set a name for your new browser, that is &amp;quot;chrome&amp;quot;.&lt;br /&gt;
*Set the location of your new browser, that is &amp;quot;/usr/bin/google-chrome&amp;quot;&lt;br /&gt;
*If you don&#039;t know the location of the browser, open a terminal and use the command &amp;quot;whereis browsername&amp;quot; to display the browser location. Note: Replace browsername with the name of your preferred browser, that is &amp;quot;whereis google-chrome&amp;quot;. Copy one of the locations if there is more than one.&lt;br /&gt;
*Save all changes.&lt;br /&gt;
&lt;br /&gt;
== Testing XDebug and Eclipse IDE ==&lt;br /&gt;
To test our new debugging tool, we need to create an Eclipse PHP project, set the debug configuration for our project and write a few lines of PHP code. This example assumes 3 things:&lt;br /&gt;
# You understand the Eclipse IDE concepts of &amp;quot;workspace&amp;quot; and &amp;quot;projects&amp;quot;. If not, please read this article: [[Configuring Eclipse IDE for PHP development/Linux#Understanding the folder structure]]&lt;br /&gt;
# You already have a working web server. If not, please read this article: [[Configuring a LAMPP server for PHP development/Linux desktop]]&lt;br /&gt;
# Your Eclipse workspace is located at the server&#039;s web root folder.&lt;br /&gt;
=== Configuring the Workspace ===&lt;br /&gt;
*If your current workspace is located at your server&#039;s web root, skip this part.&lt;br /&gt;
*Open Eclipse IDE.&lt;br /&gt;
*On Eclipse, go to: {{rarr|Toolbar,File,Switch,Workspace,Other}}&lt;br /&gt;
*Press the button &amp;quot;browse&amp;quot; and browse to the location of your server&#039;s web root folder. For example, &amp;quot;/home/youruser/lamp/public_html/&amp;quot;&lt;br /&gt;
*Press &amp;quot;OK&amp;quot; and wait until Eclipse IDE restarts and load the new workspace.&lt;br /&gt;
=== Configuring the Test Project ===&lt;br /&gt;
*On Eclipse go to: {{rarr|Toolbar,File,New,Other,PHP,PHP Project}}&lt;br /&gt;
*Set the project name to &amp;quot;xdebug-test&amp;quot; or anything you like.&lt;br /&gt;
*Press &amp;quot;Ok&amp;quot; to continue.&lt;br /&gt;
*After this Eclipse IDE will automatically create a project folder like this &amp;quot;/home/youruser/lamp/public_html/xdebug-test/&amp;quot;. Also you should be able to visualize the new project at the Eclipse IDE Project Explorer view or Navigation view.&lt;br /&gt;
*On Eclipse go to: {{rarr|Toolbar,File,New,Other,PHP,PHP File}}&lt;br /&gt;
*Set the file name to &amp;quot;index.php&amp;quot;.&lt;br /&gt;
*Press &amp;quot;Ok&amp;quot; to continue.&lt;br /&gt;
*After this Eclipse IDE will automatically create a PHP file like this &amp;quot;/home/youruser/lamp/public_html/xdebug-test/index.php&amp;quot;. Also you should be able to visualize the new file at the Eclipse IDE Project Explorer view or Navigation view.&lt;br /&gt;
*Find the new &amp;quot;index.php&amp;quot; file at the Eclipse IDE project explorer and open it by double clicking on it.&lt;br /&gt;
*Place the following content to that file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
    $X = 5;&lt;br /&gt;
    $X = 8;&lt;br /&gt;
    $Y = 2;&lt;br /&gt;
    $Z = $X + $Y;&lt;br /&gt;
    $Z = $Z + 1;&lt;br /&gt;
    echo &amp;quot;Z value is: &amp;quot; . $Z;&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
*Save the changes.&lt;br /&gt;
*Open your web browser and navigate to &amp;quot;http://localhost/xdebug-test/index.php&amp;quot;&lt;br /&gt;
*It should display a web page and output like this:&lt;br /&gt;
 &amp;lt;tt&amp;gt;Z value is: 11&amp;lt;/tt&amp;gt;&lt;br /&gt;
=== Configuring the Test Project Debug Information ===&lt;br /&gt;
*On Eclipse, go to: {{rarr|Toolbar,Run,Debug configuration...}}&lt;br /&gt;
*On the left list, find &#039;&#039;PHP Web Application&#039;&#039; and do a double click on it to create a new configuration element.&lt;br /&gt;
*Select the new configuration element to display its contents.&lt;br /&gt;
*Set the name to &#039;&#039;xdebug-test&#039;&#039; or anything you like.&lt;br /&gt;
*Make sure the option &amp;quot;Server debugger&amp;quot; is set to &amp;quot;XDebug&amp;quot;.&lt;br /&gt;
*Make sure the option &amp;quot;Break at first Line&amp;quot; is not checked.&lt;br /&gt;
*In the option &amp;quot;File&amp;quot; press the button &amp;quot;Browse&amp;quot;. Find your project &amp;quot;xdebug-test&amp;quot; and expand its contents. Then find and select the file &amp;quot;index.php&amp;quot;.&lt;br /&gt;
*Make sure that option URL looks something like this &amp;quot;http://localhost/xdebug-test/index.php&amp;quot;&lt;br /&gt;
*Press &amp;quot;Apply&amp;quot; and &amp;quot;Close&amp;quot; to save changes and continue.&lt;br /&gt;
=== Debugging the Test Project ===&lt;br /&gt;
As you can see, our &amp;quot;index.php&amp;quot; file has several lines of code. With the debugger, we can study how those lines of code are executed one by one. To stop the execution, we need to set something called &amp;quot;Breakpoint&amp;quot;. A Breakpoint is a &amp;quot;mark&amp;quot; in our lines of code that indicate to the debugger to stop the execution and poll the var values. To set a Breakpoint on our code and test the debugger, follow these simple steps.&lt;br /&gt;
&lt;br /&gt;
*Open the &amp;quot;index.php&amp;quot; of our test project.&lt;br /&gt;
*Locate the line of code &amp;quot;$X = 8;&amp;quot; and do a click on it to place the blinking cursor there.&lt;br /&gt;
*On Eclipse go to: {{rarr|Toolbar,Run,Toggle Breakpoint}}. You can also used the hotkey &amp;quot;shift+ctrl+B&amp;quot; or simply do a double click on the line number of the line of code at the left side of your editor to toggle a Breakpoint.&lt;br /&gt;
*When a Breakpoint is set, you should see it represented as a little circle next to the line number at the left side of your editor.&lt;br /&gt;
&lt;br /&gt;
Now is the time to execute our project to see how the debugger helps us.&lt;br /&gt;
&lt;br /&gt;
*On Eclipse, go to: {{rarr|Toolbar,Run,Debug}}. You can also used the hotkey &amp;quot;F11&amp;quot; or simply do a click in the &amp;quot;little bug icon&amp;quot; located at the second toolbar from the top.&lt;br /&gt;
*Eclipse will open the configured web browser and change to the &amp;quot;Debug perspective&amp;quot;. The debug perspective contains a set of pre-configured views useful to do debugging tasks. Among them we have:&lt;br /&gt;
**Debug view: It displays buttons to control the current running debug session. This view contains the current [[wikipedia:Call_stack | call stack]].&lt;br /&gt;
**Breakpoint view: display all your set breakpoints on any project file.&lt;br /&gt;
**Variables view: It&#039;s basically a &amp;quot;var dump&amp;quot; of all the PHP variables of your actual session. This view lets you easily navigate through any variable and child members of those variables.&lt;br /&gt;
**Expressions view: here you can set custom expressions, for instance, &amp;quot;$X+$Y+$Z&amp;quot; and see the outcome of each expression without changing the code.&lt;br /&gt;
**Internal browser view and output view: optional if you not configured an external browser, Eclipse IDE will display this view with the current page and the current page HTML output.&lt;br /&gt;
*At this point our web page should look stopped and most likely the browser will show a blank page &amp;quot;waiting&amp;quot; to load the rest of it.&lt;br /&gt;
*Note that the current breakpoint has a &amp;quot;little arrow&amp;quot; over the circle and the line of code is highlighted. This indicates the next line of code to be executed, also know as the &amp;quot;current step&amp;quot;.&lt;br /&gt;
*If you take a look at the &amp;quot;variables view&amp;quot;, the current value of &amp;quot;$X&amp;quot; should be &amp;quot;5&amp;quot;.&lt;br /&gt;
*Go to the &amp;quot;Debug view&amp;quot; and press the button &amp;quot;step over&amp;quot; or use the hotkey &amp;quot;F6&amp;quot; to go one [http://www.youtube.com/watch?v=LAUcTGeqvOw step forward] in the code execution.&lt;br /&gt;
*Take another look at the &amp;quot;variables view&amp;quot;. The current value of &amp;quot;$X&amp;quot; should be now &amp;quot;8&amp;quot;.&lt;br /&gt;
*This way you can neatly study how your code and values changes step by step. You can also hover your mouse pointer over the variables names in the editor. Eclipse will pop up the current values.&lt;br /&gt;
*Keep going forward until the end of the lines of code. At that point the web browser should display the final web page output.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development/Windows&amp;diff=1005731</id>
		<title>Configuring Xdebug for PHP development/Windows</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Configuring_Xdebug_for_PHP_development/Windows&amp;diff=1005731"/>
		<updated>2023-06-29T17:13:08Z</updated>

		<summary type="html">&lt;p&gt;Cmb: URL corrections. Other text editing.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{incomplete}}&lt;br /&gt;
Configuring XDebug is split into two parts: Server-side and Client-side.&lt;br /&gt;
&lt;br /&gt;
== Server-side (Extension in PHP) ==&lt;br /&gt;
&lt;br /&gt;
=== Installation ===&lt;br /&gt;
First check if this extension is already installed. Create a new file with the content &#039;&#039;&amp;lt;?php phpinfo(); ?&amp;gt;&#039;&#039;, save it in your web folder (e.g. &#039;&#039;C:\xampp\htdocs\phpinfo.php&#039;&#039;) and call it using your browser (https://localhost/phpinfo.php). The command &#039;&#039;phpinfo&#039;&#039; will show you the information about installed plugins and their configuration. If you see a headline called XDebug, it is already downloaded and enabled.&lt;br /&gt;
&lt;br /&gt;
To get the extension for a Windows system, you have to download the DLL file from https://xdebug.org/download that fits your PHP version, move it into the &#039;&#039;ext&#039;&#039; folder of your PHP installation. If the file &#039;&#039;php_xdebug.dll&#039;&#039; exists, leave it there. It&#039;s most likely the right version, just that it&#039;s not enabled.&lt;br /&gt;
&lt;br /&gt;
=== Enable XDebug ===&lt;br /&gt;
On Windows systems you most likely just have one &#039;&#039;php.ini&#039;&#039; file for all configuration whereas on several Linux distributions you have a directory called &#039;&#039;conf.d&#039;&#039; in addition. If you have installed XDebug on a Linux-based system, you&#039;ll probably find a file &#039;&#039;xdebug.ini&#039;&#039;. Use this file instead if you have it.&lt;br /&gt;
&lt;br /&gt;
Enable the plugin by adding (or uncommenting) the following line in your config file:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
; Example for XAMPP&lt;br /&gt;
zend_extension = &amp;quot;\xampp\php\ext\php_xdebug.dll&amp;quot;&lt;br /&gt;
&lt;br /&gt;
; Example on Mac OS X for XAMPP&lt;br /&gt;
zend_extension=&amp;quot;/Applications/XAMPP/xamppfiles/lib/php/php-5.3.1/extensions/no-debug-non-zts-20090626/xdebug.so&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Make sure you use &#039;&#039;zend_extension&#039;&#039; instead of &#039;&#039;extension&#039;&#039; which requires the full path to the extension-file.&lt;br /&gt;
&lt;br /&gt;
=== Configuration ===&lt;br /&gt;
Also read this introduction for configuration details: https://xdebug.org/docs/step_debug&lt;br /&gt;
&lt;br /&gt;
Here is an example configuration:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;ini&amp;quot;&amp;gt;&lt;br /&gt;
; location of my configuration-file&lt;br /&gt;
zend_extension=/usr/lib/php5/20090626/xdebug.so&lt;br /&gt;
&lt;br /&gt;
; Enables colors if you use XDebug on the console&lt;br /&gt;
xdebug.cli_color=1&lt;br /&gt;
&lt;br /&gt;
; Enable profiler by a trigger (f.e. cookie or GET-param)&lt;br /&gt;
xdebug.profiler_enable_trigger=1&lt;br /&gt;
xdebug.profiler_output_dir=/var/www/log/&lt;br /&gt;
&lt;br /&gt;
; Debugger will try to connect back to the machine sending the HTTP-Request&lt;br /&gt;
xdebug.remote_connect_back=1&lt;br /&gt;
&lt;br /&gt;
; Enables the debugger&lt;br /&gt;
xdebug.remote_enable=1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Client-side (Configure Your IDE) ==&lt;br /&gt;
If your IDE is not listed on https://xdebug.org/docs/step_debug#clients, you&#039;ll probably find a tutorial in the manual of your IDE.&lt;br /&gt;
Feel free to add helpful tutorials here.&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Testing_Checklists&amp;diff=1005340</id>
		<title>Testing Checklists</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Testing_Checklists&amp;diff=1005340"/>
		<updated>2023-06-28T20:05:50Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected a parentheses mismatch.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
This article is designed to help Joomla! Bug Squad members as they test New issues and Pending issues.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Testing New Issues === &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The &#039;&#039;New&#039;&#039; status indicates that no member of the Joomla! Bug Squad has evaluated this issue. The goal is to learn enough about the issue to be able to change the status to one of the following: &#039;&#039;Unconfirmed Report&#039;&#039;, &#039;&#039;Known Issue&#039;&#039;, &#039;&#039;Duplicate Report&#039;&#039;, &#039;&#039;Confirmed&#039;&#039; or &#039;&#039;Information Required&#039;&#039;. See [[S:MyLanguage/Bug Tracking Process#Resolving Issues | Bug Tracking Process]] for details about these status codes.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
Here is a checklist for testing &#039;&#039;New&#039;&#039; issues:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
* Did you carefully read the entire description and any other comments?&lt;br /&gt;
* Is there enough information provided? If not, add a comment and change to &#039;&#039;Information Required&#039;&#039;.&lt;br /&gt;
* Did you search the tracker to see if this issue has already been reported? If so, add a comment and change to &#039;&#039;Duplicate Report&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
* Is the issue a known issue or limitation? If so, add a comment and change to &#039;&#039;Known Issue&#039;&#039;.&lt;br /&gt;
* Is the issue an enhancement request? If so, change status to &#039;&#039;Discussion&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
* Before testing, did you update your local GIT repository to get the latest GIT Joomla! version? (See [[S:MyLanguage/Git for Testers and Trackers|Git for Testers and Trackers]])&lt;br /&gt;
* If you couldn&#039;t duplicate the problem with the latest GIT version, did you test using the latest production version?&lt;br /&gt;
* If the issue is still unconfirmed, try to to reproduce the issue with different cache settings.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
* Try to localize the problem by changing your cache settings.&lt;br /&gt;
* If you changed the issue to &#039;&#039;Confirmed&#039;&#039;, did you make sure there is a detailed test plan in the comments to allow someone who is not familiar with the issue to understand and test the issue?&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Testing Pending Issues === &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
A &#039;&#039;Pending&#039;&#039; issue is one that (a) has been confirmed, (b) has a detailed test plan, and (c) has a proposed patch to be tested. ([[S:MyLanguage/My_first_pull_request_to_Joomla!_on_Github|Learn more about creating your first pull request]]). Here is a checklist for testing &#039;&#039;Pending&#039;&#039; issues:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
* Is there a test plan for the issue shown in the &#039;&#039;Test Instructions&#039;&#039; field? If not, post a comment and change status to &#039;&#039;Information Required&#039;&#039;.&lt;br /&gt;
* Before testing, did you update your local GIT repository to get the latest GIT Joomla! version?&lt;br /&gt;
* Did you test the issue &#039;&#039;&#039;before&#039;&#039;&#039; applying the patch to make sure you can confirm the problem?&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
* Did you test the issue after applying the patch to make sure the problem is fixed?&lt;br /&gt;
* Are there any other test cases that should be considered? Examples might include:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
** template override files (especially Beez template)&lt;br /&gt;
** testing with SEF or &#039;&#039;mod_rewrite&#039;&#039; enabled and disabled&lt;br /&gt;
** language file issues (Test with Debug Language set to Yes.)&lt;br /&gt;
** PHP warnings (Test with &#039;&#039;Error Reporting&#039;&#039; set to &#039;&#039;Maximum&#039;&#039;).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
* If your test is successful and you are the first tester, indicate in your comment that a second test is needed. If you are the second tester, change the status to &#039;&#039;Ready to Commit&#039;&#039;.&lt;br /&gt;
* Remember to revert the changes made by the patch after you are done testing.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Testing Code Snippets === &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
Sometimes to test a patch you will need to test PHP code snippets. One simple way to do this is:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
# Create a new folder called &#039;&#039;com_test&#039;&#039; under the components folder.&lt;br /&gt;
# Create a new file called &#039;&#039;test.php&#039;&#039; under this folder.&lt;br /&gt;
# Put your PHP code snippet in this file.&lt;br /&gt;
# To run the file, just enter the URL &#039;&#039;&amp;lt;your domain&amp;gt;/index.php?option=com_test&#039;&#039;. For example, &#039;&#039;&amp;lt;nowiki&amp;gt;http://localhost/joomla_development/index.php?option=com_test&amp;lt;/nowiki&amp;gt;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
This will run the code snippet inside the Joomla! framework. This way, when you are done, you can just remove the &#039;&#039;com_test&#039;&#039; folder and no other files have been changed. (Sam, thanks for this tip!)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General Tips &amp;amp; Tricks === &amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
* If you have the cache enabled ({{rarr|Global Configuration,System,Cache Settings}}), you will need to clean the cache each time you make a change to the code or parameters. Otherwise, you might be seeing the older cached version of the page. Unless you are specifically testing the cache feature, test with the Cache set to &#039;&#039;No&#039;&#039;.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
* Set Error Reporting to &#039;&#039;Maximum&#039;&#039; and enable all debugging options in Global Configuration.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
[[Category:Bug Squad]]&lt;br /&gt;
[[Category:Testing]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Visual_Studio_Code&amp;diff=1005339</id>
		<title>Visual Studio Code</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Visual_Studio_Code&amp;diff=1005339"/>
		<updated>2023-06-28T17:30:55Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected some URLs.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
[https://code.visualstudio.com/ Visual Studio Code (VSCode)] is a source code editor developed by Microsoft for Windows, Linux and MacOS (including M1 Macs). It includes support for debugging, embedded Git control and GitHub, syntax highlighting, intelligent code completion, snippets, and code refactoring.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The main characteristic of the editor is that it is extensible and it has a huge collection of extensions maintained by users and by Microsoft itself. See details at the [https://marketplace.visualstudio.com/ VSCode Extensions for Visual Studio Code] website.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
As a general introduction, this is a presentation about the topic [https://www.renekreijveld.nl/slides/juglondon/vscode.pdf Joomla Development with Visual Studio Code], by René Kreijveld, Joomla developer Destiny B.V. Joomla User Group London, 16th march 2021.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
On this page, we detail a list of recommended extensions to configure VSCode to support PHP and Joomla.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
This is a list of extensions to support PHP on VSCode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;PHP Debug&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug felixfbecker.php-debug]. Debug support for PHP with XDebug.&lt;br /&gt;
* &#039;&#039;&#039;phpcs&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs ikappas.phpcs]. PHP CodeSniffer for Visual Studio Code.&lt;br /&gt;
* &#039;&#039;&#039;PHP Intelephense&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=bmewburn.vscode-intelephense-client bmewburn.vscode-intelephense-client]. PHP code intelligence for Visual Studio Code. Alternative: &#039;&#039;PHP IntelliSense&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense felixfbecker.php-intellisense]&lt;br /&gt;
* &#039;&#039;&#039;PHPUnit&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=emallin.phpunit emallin.phpunit]. Run PHPUnit tests from VSCode.&lt;br /&gt;
* &#039;&#039;&#039;phpfmt&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=kokororin.vscode-phpfmt kokororin.vscode-phpfmt]. The missing phpfmt extension for Visual Studio Code. The phpfmt formatter can parse and format even a PHP file version 4 if needed.&lt;br /&gt;
* &#039;&#039;&#039;php cs fixer&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=junstyle.php-cs-fixer junstyle.php-cs-fixer]: In case of opting for the [https://www.php-fig.org/psr/psr-2/ PSR-2: Coding Style Guide]). PHP CS Fixer extension for VS Code, PHP formatter, PHP code beautify tool, format HTML.&lt;br /&gt;
* &#039;&#039;&#039;PHP Namespace Resolver&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=MehediDracula.php-namespace-resolver MehediDracula.php-namespace-resolver]: PHP Namespace Resolver can import and expand your class. You can also sort your imported classes by line length or in alphabetical order.&lt;br /&gt;
* &#039;&#039;&#039;PHP Phan (Analyzer)&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=TysonAndre.php-phan tysonandre.php-phan]. Phan - static analyzer for PHP, minimizing false positives.&lt;br /&gt;
* &#039;&#039;&#039;phpmd&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=linyang95.phpmd linyang95.phpmd]. VS Code extension for PHP, using PHPMD.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
The Git protocol is natively supported on VSCode. However, there are extensions to improve code and repository management. This is a list of featured extensions for this task:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Git History&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory donjayamanne.githistory]: Git History, Search and More (including git log).&lt;br /&gt;
* &#039;&#039;&#039;GitHub&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-github KnisterPeter.vscode-github]: This VSCode extension integrates with GitHubExtensions for Visual Studio Code&lt;br /&gt;
* &#039;&#039;&#039;GitHub Pull Requests and Issues&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=GitHub.vscode-pull-request-github GitHub.vscode-pull-request-github]: Review and manage your GitHub pull requests and issues directly in VS Code&lt;br /&gt;
* &#039;&#039;&#039;gitignore&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=codezombiech.gitignore codezombiech.gitignore]: A extension for Visual Studio Code that assists you in working with &#039;&#039;.gitignore&#039;&#039; files.&lt;br /&gt;
* &#039;&#039;&#039;Visual Studio Code Commitizen Support&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=KnisterPeter.vscode-commitizen KnisterPeter.vscode-commitizen]: This VSCode extension adds &#039;&#039;commitizen&#039;&#039; support.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
This is a list of extensions to support Joomla on VSCode:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Joomla Snippets&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=AnibalSanchez.vs-code-joomla-snippets anibalsanchez.vs-code-joomla-snippets]. Snippets for Joomla including Joomla 3.x and Joomla 4 Snippets.&lt;br /&gt;
* &#039;&#039;&#039;PHP Getters &amp;amp; Setters&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=phproberto.vscode-php-getters-setters phproberto.vscode-php-getters-setters]. Create PHP getters and setters from class properties.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
This is a list of extensions to support remote SSH development:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Remote - SSH&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh ms-vscode-remote.remote-ssh]: The Remote - SSH extension lets you use any remote machine with an SSH server as your development environment. This can greatly simplify development and troubleshooting in a wide variety of situations. For more information: [https://code.visualstudio.com/docs/remote/ssh-tutorial Remote development over SSH]&lt;br /&gt;
* &#039;&#039;&#039;Live Share&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare MS-vsliveshare.vsliveshare]: Visual Studio Live Share enables you to collaboratively edit and debug with others in real-time, regardless of what programming languages you&#039;re using or app types you&#039;re building. It allows you to instantly (and securely) share your current project, and then as needed, share debugging sessions, terminal instances, localhost web apps, voice calls, and more!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
This is a list of handy extensions highly recommended to ease the development:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;EditorConfig for VS Code&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig editorconfig.editorconfig] EditorConfig Support for Visual Studio Code.&lt;br /&gt;
* &#039;&#039;&#039;change-case&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=wmaurer.change-case wmaurer.change-case]: Quickly change the case (camelCase, CONSTANT_CASE, snake_case, etc) of the current selection or current word.&lt;br /&gt;
* &#039;&#039;&#039;Project Manager&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager alefragnani.project-manager]: It helps you to easily access your projects, no matter where they are located. Don&#039;t miss those important projects anymore.&lt;br /&gt;
&lt;br /&gt;
== PHP Debug Configuration == &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The extension supports the most common configurations of PHP [https://xdebug.org/ XDebug]. It fully integrates all VSCode features to debug PHP scripts.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/xdebug/vscode-php-debug#installation official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
As a sample configuration for VSCode debugging, this is a common &#039;&#039;launch.json&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
    // Use IntelliSense to learn about possible attributes.&lt;br /&gt;
    // Hover to view descriptions of existing attributes.&lt;br /&gt;
    // For more information, visit: https://code.visualstudio.com/docs/editor/debugging#_launch-configurations&lt;br /&gt;
    &amp;quot;version&amp;quot;: &amp;quot;0.2.0&amp;quot;,&lt;br /&gt;
    &amp;quot;configurations&amp;quot;: [&lt;br /&gt;
&lt;br /&gt;
        &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
            &amp;quot;name&amp;quot;: &amp;quot;Listen for XDebug&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;php&amp;quot;,&lt;br /&gt;
            &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
// Server Remote XDebug Port - 9000 is the default XDebug port&lt;br /&gt;
            &amp;quot;port&amp;quot;: 9000,&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
// Server Remote Path -&amp;gt; Local Project Path&lt;br /&gt;
            &amp;quot;pathMappings&amp;quot;: {&lt;br /&gt;
                &amp;quot;/app/www&amp;quot;: &amp;quot;${workspaceRoot}/www&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
        },&lt;br /&gt;
        {&lt;br /&gt;
            &amp;quot;name&amp;quot;: &amp;quot;Launch currently open script&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;php&amp;quot;,&lt;br /&gt;
            &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
            &amp;quot;program&amp;quot;: &amp;quot;${file}&amp;quot;,&lt;br /&gt;
            &amp;quot;cwd&amp;quot;: &amp;quot;${fileDirname}&amp;quot;,&lt;br /&gt;
&lt;br /&gt;
            &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
// Local XDebug Port - 9000 is the default XDebug port&lt;br /&gt;
            &amp;quot;port&amp;quot;: 9000&lt;br /&gt;
        }&lt;br /&gt;
    ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
Related to the &#039;&#039;launch.json&#039;&#039; configuration that &#039;&#039;felixfbecker/vscode-php-debug&#039;&#039; requires, it is the configuration of PHP XDebug itself.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
At this time, your development environment could have &#039;&#039;xdebug-2&#039;&#039; or &#039;&#039;xdebug-3&#039;&#039;. They differ in the required parameters. To configure PHP XDebug, these are the most common settings for &#039;&#039;php.ini&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
=== XDebug 2 Configuration === &amp;lt;!--T:73--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:74--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[XDebug]&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
; xdebug-2.9.8&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
xdebug.remote_enable = 1&lt;br /&gt;
xdebug.remote_autostart = 1&lt;br /&gt;
; xdebug.remote_port = 9000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== XDebug 3 Configuration === &amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
[XDebug]&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
; xdebug-3.0.0&lt;br /&gt;
; https://xdebug.org/docs/upgrade_guide&lt;br /&gt;
;;;;;;;;;;;;;;;;;;;&lt;br /&gt;
xdebug.mode = debug&lt;br /&gt;
xdebug.start_with_request = yes&lt;br /&gt;
xdebug.discover_client_host = true&lt;br /&gt;
; xdebug.client_port = 9000&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:77--&amp;gt;&lt;br /&gt;
To know more about how XDebug works internally to connect to the Editor, check the [https://xdebug.org/docs/ Xdebug 3 — Documentation].&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;phpcs&#039;&#039; Configuration == &amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://marketplace.visualstudio.com/items?itemName=ikappas.phpcs official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
The extension supports the most common configurations of [https://pear.php.net/package/PHP_CodeSniffer/ PHP_CodeSniffer].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
By default, PHP_CodeSniffer comes with several coding standards. Once the extension is installed, it works with &#039;&#039;PSR2&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpcs.standard&amp;quot;: &amp;quot;PSR2&amp;quot;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
To configure the extension to apply the &#039;&#039;&#039;Joomla! Coding Standards&#039;&#039;&#039;, install the rules following the [https://developer.joomla.org/coding-standards/html.html official guide].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
Once &#039;&#039;&#039;Joomla! Coding Standards&#039;&#039;&#039; is installed, configure the User Settings following this sample configuration:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpcs.standard&amp;quot;: &amp;quot;/home/YOUR-USER/.../Joomla&amp;quot;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configuration of PHP Intelephense == &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/bmewburn/vscode-intelephense#quick-start official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
The extension does not require additional configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
VSCode comes with basic support of the PHP language. It is a good idea to disable the default support to avoid conflicts:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    // Disable basic suggestions&lt;br /&gt;
    &amp;quot;php.suggest.basic&amp;quot;: false,&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
// To activate code suggestions in comments&lt;br /&gt;
    &amp;quot;editor.quickSuggestions&amp;quot;: { &amp;quot;comments&amp;quot;: true },&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
As an alternative, it is also a popular extension: &#039;&#039;&#039;PHP IntelliSense&#039;&#039;&#039; [https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-intellisense felixfbecker.php-intellisense] Advanced Autocompletion and Refactoring support for PHP.&lt;br /&gt;
&lt;br /&gt;
== PHPUnit Configuration == &amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/elonmallin/vscode-phpunit#setup official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
The extension integrates [https://phpunit.de/ PHP Unit] with VSCode, so all features of PHP Unit are integrated with VSCode and can also be parameterized for further integration with the user interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
This is a sample configuration of the extension:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpunit.preferRunClassTestOverQuickPickWindow&amp;quot;: true,&lt;br /&gt;
    &amp;quot;phpunit.driverPriority&amp;quot;: [&lt;br /&gt;
        &amp;quot;Path&amp;quot;,&lt;br /&gt;
        &amp;quot;Command&amp;quot;,&lt;br /&gt;
        &amp;quot;Composer&amp;quot;,&lt;br /&gt;
        &amp;quot;Phar&amp;quot;,&lt;br /&gt;
        &amp;quot;Ssh&amp;quot;,&lt;br /&gt;
        &amp;quot;GlobalPhpUnit&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PHP CS Fixer Configuration (Only for PSR2) == &amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/junstyle/vscode-php-cs-fixer#installation official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
The extension integrates [https://github.com/PHP-CS-Fixer/PHP-CS-Fixer PHP CS Fixer] with VSCode, so all features of PHP CS Fixer are integrated with VSCode and can also be parameterized for further integration with the user interface.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
To automatically apply PHP CS Fixer to PHP files, configure the user settings in this way:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;[php]&amp;quot;: {&lt;br /&gt;
        &amp;quot;editor.defaultFormatter&amp;quot;: &amp;quot;junstyle.php-cs-fixer&amp;quot;,&lt;br /&gt;
    },&lt;br /&gt;
    &amp;quot;php-cs-fixer.onsave&amp;quot;: true,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== PHP Phan (Analyzer) Configuration == &amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://marketplace.visualstudio.com/items?itemName=TysonAndre.php-phan official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
This is a sample configuration of the extension:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phan.phpExecutablePath&amp;quot;: &amp;quot;/usr/bin/php&amp;quot;,&lt;br /&gt;
    &amp;quot;phan.analyzedFileExtensions&amp;quot;: [&lt;br /&gt;
        &amp;quot;php&amp;quot;&lt;br /&gt;
    ],&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== &#039;&#039;phpmd&#039;&#039; Configuration == &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
To configure the extension, visit the [https://github.com/xdebug/vscode-php-debug#installation official documentation].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
The extension does not require additional configuration.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
This is a sample configuration of the extension:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;quot;phpmd.command&amp;quot;: &amp;quot;php /home/YOUR-USER/.../phpmd/phpmd.phar&amp;quot;,&lt;br /&gt;
    &amp;quot;phpmd.rules&amp;quot;: &amp;quot;/home/YOUR-USER/.../phpmd-rulesets/phpmd_config.xml&amp;quot;,&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Configure EditorConfig for VS Code == &amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
EditorConfig is a file format and collection of text editor plugins for maintaining consistent coding styles between different editors and IDEs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
To configure the editor according to your preferences, create a file &#039;&#039;.editorconfig&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br /&gt;
; EditorConfig helps developers define and maintain consistent&lt;br /&gt;
; coding styles between different editors and IDEs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:60--&amp;gt;&lt;br /&gt;
; For more visit https://editorconfig.org/&lt;br /&gt;
root = true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
; Choose between lf or rf on &amp;quot;end_of_line&amp;quot; property&lt;br /&gt;
[*]&lt;br /&gt;
charset = utf-8&lt;br /&gt;
end_of_line = lf&lt;br /&gt;
indent_size = 2&lt;br /&gt;
indent_style = space&lt;br /&gt;
insert_final_newline = true&lt;br /&gt;
trim_trailing_whitespace = true&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
# editorconfig-tools is unable to ignore longs strings or URLs&lt;br /&gt;
max_line_length = null&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
[*.html]&lt;br /&gt;
indent_style = tab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
# PSR-2&lt;br /&gt;
# [*.php]&lt;br /&gt;
# indent_size = 4&lt;br /&gt;
# indent_style = space&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:65--&amp;gt;&lt;br /&gt;
# Joomla! Coding Standards&lt;br /&gt;
[*.php]&lt;br /&gt;
indent_size = 4&lt;br /&gt;
indent_style = tab&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
[*.md]&lt;br /&gt;
trim_trailing_whitespace = false&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
[*.yml]&lt;br /&gt;
indent_style = space&lt;br /&gt;
indent_size = 2&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Beginner_Development{{#translation:}}]]&lt;br /&gt;
[[Category:Server configurations{{#translation:}}]]&lt;br /&gt;
[[Category:Server setup local{{#translation:}}]]&lt;br /&gt;
[[Category:Server configurations{{#translation:}}]]&lt;br /&gt;
[[Category:Bug Squad{{#translation:}}]]&lt;br /&gt;
[[Category:IDE (Integrated development environment){{#translation:}}]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Visual_Studio_Code_Primer&amp;diff=1005156</id>
		<title>Visual Studio Code Primer</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Visual_Studio_Code_Primer&amp;diff=1005156"/>
		<updated>2023-06-27T21:59:28Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Changed &amp;#039;sill&amp;#039; to &amp;#039;still&amp;#039; and a few other changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== VS Code - A Popular Free IDE == &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
From [https://en.wikipedia.org/wiki/Visual_Studio_Code Wikipedia]:&lt;br /&gt;
&amp;lt;blockquote&amp;gt;Visual Studio Code, also commonly referred to as VS Code, is a source-code editor made by Microsoft for Windows, Linux and macOS. Features include support for debugging, syntax highlighting, intelligent code completion, snippets, code refactoring, and embedded Git. Users can change the theme, keyboard shortcuts, preferences, and install extensions that add additional functionality.&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation == &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The [https://code.visualstudio.com/ VS Code] site default page has a drop-down list for each supported platform. The chances are that your platform is pre-selected. So download and install and you are ready to go.&lt;br /&gt;
&lt;br /&gt;
=== Getting Started === &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The VS Code &#039;&#039;Get Started&#039;&#039; page has some &#039;&#039;Start&#039;&#039; items, a list of &#039;&#039;Recent&#039;&#039; items, and a short list of &#039;&#039;Walkthroughs&#039;&#039;. If you are completely new to VS Code these are recommended viewing. They only take a few minutes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
The VS Code Documentation is available from the &#039;&#039;Help / Documentation&#039;&#039; menu. The Introductory Videos are well worth viewing. Each takes 2 to 6 minutes and gives an excellent introduction to VS Code features&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
https://code.visualstudio.com/docs/getstarted/introvideos&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
The official documentation is the place to go to if you want to look up specific information.&lt;br /&gt;
&lt;br /&gt;
=== VS Code Extensions === &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
VS Code can be used for any type of text, including a wide range of programming languages. It works with JavaScript without adding extensions. Other languages are detected by context so if you start creating and saving PHP code you are likely to be prompted to install a PHP Support pack.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
Click on the &#039;&#039;Extensions&#039;&#039; icon in the left &#039;&#039;Activity Bar&#039;&#039; to see what you have installed and what is recommended. You will need the PHP Debug extension!&lt;br /&gt;
&lt;br /&gt;
=== The VS Code Screen Layout === &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
Some terms used in subsequent instructions:&lt;br /&gt;
* &#039;&#039;&#039;Activity Bar:&#039;&#039;&#039; the narrow bar at the left of the screen. Select any icon to open or close the Primary Sidebar.&lt;br /&gt;
* &#039;&#039;&#039;Primary Side Bar:&#039;&#039;&#039; when open shows details of the selected activity.&lt;br /&gt;
* &#039;&#039;&#039;Status Bar:&#039;&#039;&#039; at the bottom of the screen. It shows what is going on.&lt;br /&gt;
* &#039;&#039;&#039;Panel:&#039;&#039;&#039; an area beneath the text editors to display other information.&lt;br /&gt;
Select a layout icon at the top right to open or close any one of these items.&lt;br /&gt;
&lt;br /&gt;
== Coding a Joomla Extension == &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
To create an extension your objective is to create a zip file that you can install in a working Joomla site. So you need a folder to contain your code. This should be within your personal file space on your laptop or desktop computer used for local development. It should not be in your website tree. For example you could use &#039;&#039;~/jextensions&#039;&#039; to contain subfolders for different extensions. I use &#039;&#039;~/git&#039;&#039; because it is short and easy to spell although potentially confusing because each subfolder uses a separate git repository.&lt;br /&gt;
&lt;br /&gt;
=== Sample Code === &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
If you would like some sample code to work on there is an extension available on GitHub named &#039;&#039;mod_debugme&#039;&#039;. As the name implies, it is a module with some bugs. In addition to the module code there is a &#039;&#039;build.xml&#039;&#039; file to illustrate one way to automate building for testing and creating a zip file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
The module is designed to show the next few (3 by default) events (birthdays) from a list stored in a database table. You might imagine this being used in an office or family site in the expectation of cake.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
It may be best to get going by using git commands from the command line. First create a folder for your code and then clone the remote repository:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
mkdir ~/git&lt;br /&gt;
cd ~/git&lt;br /&gt;
git clone https://github.com/ceford/j4xdemos-mod-debugme&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
The response should take just a few seconds:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Cloning into &#039;j4xdemos-mod-debugme&#039;...&lt;br /&gt;
remote: Enumerating objects: 23, done.&lt;br /&gt;
remote: Counting objects: 100% (23/23), done.&lt;br /&gt;
remote: Compressing objects: 100% (16/16), done.&lt;br /&gt;
remote: Total 23 (delta 3), reused 23 (delta 3), pack-reused 0&lt;br /&gt;
Unpacking objects: 100% (23/23), done.&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
You should take a moment to look at the contents of the folder:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
cd j4xdemos-mod-debugme&lt;br /&gt;
ls -al&lt;br /&gt;
total 16&lt;br /&gt;
drwxr-xr-x   6 ceford  staff   192  2 Sep 17:48 .&lt;br /&gt;
drwxr-xr-x   3 ceford  staff    96  2 Sep 17:48 ..&lt;br /&gt;
drwxr-xr-x  12 ceford  staff   384  2 Sep 17:48 .git&lt;br /&gt;
-rw-r--r--   1 ceford  staff  1402  2 Sep 17:48 README.md&lt;br /&gt;
-rw-r--r--   1 ceford  staff   927  2 Sep 17:48 build.xml&lt;br /&gt;
drwxr-xr-x   8 ceford  staff   256  2 Sep 17:48 mod_debugme&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
The &#039;&#039;.git&#039;&#039; folder contains information about the repo. The &#039;&#039;README.md&#039;&#039; file is a markdown document that describes this repo. The &#039;&#039;build.xml&#039;&#039; file is a file used to build the extension with an external tool, Phing - described later. The &#039;&#039;mod_debugme&#039;&#039; folder contains the code of the extension.&lt;br /&gt;
&lt;br /&gt;
=== Install in Joomla === &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
Compress the extension folder to create an installable zip file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
zip -r mod_debugme.zip mod_debugme&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
You can now install the zip file in the Joomla site you use for testing. After installation you need to create a Site module and assign it to a module position. As it is a broken module you could assign it to a position on &#039;&#039;All pages&#039;&#039; while you work on it; or you could assign it to a position on a single page; or you could position it in an article that has its own menu item.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
After installation, delete the zip file.&lt;br /&gt;
&lt;br /&gt;
=== Turn on Debug Mode === &amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
In Joomla&#039;s Global Configuration, set &#039;&#039;Debug System&#039;&#039; to &#039;&#039;Yes&#039;&#039; and &#039;&#039;Error Reporting&#039;&#039; to &#039;&#039;Maximum&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
When you open a page containing the buggy module you will see a stack trace telling you where an error was triggered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
[[File:J4.x-vscode-primer-stack-trace-en.png|border|800px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
Sometimes the coding error is on the first line of the stack trace. Otherwise, if the error is triggered in library code, for example by passing invalid data to a database function, the coding error may be further down the list of function calls.&lt;br /&gt;
&lt;br /&gt;
== Open Extension Folder in VS Code == &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
In VS Code, use the File / Open Folder menu item to locate and open the folder containing your local copy of the &#039;&#039;mod_debugme&#039;&#039; extension code. You should see something similar to the following:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
[[File:J4.x-vscode-primer-screen.png|border|800px]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
You may be able to diagnose the problem just by reading the code. In the case of the &#039;&#039;Class &amp;quot;DebugHelper&amp;quot; not found&#039;&#039; error you will see that a &#039;&#039;use&#039;&#039; statement has been commented out a few lines previously. Forgetting to insert a &#039;&#039;use&#039;&#039; statement is a common error during initial development!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
Fix that problem and then compress and install the module again. That step gets a bit tedious when you have multiple problems. Which is where build tools come in useful.&lt;br /&gt;
&lt;br /&gt;
== Phing == &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
Phing is a command line tool, available for all platforms, used to build software packages using instructions stored in an XML file, named &#039;&#039;build.xml&#039;&#039; by default. For working with extension code it can be used to do two things:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
* copy changed files from your extension source folder to the correct places in your website folder.&lt;br /&gt;
* generate a new zip file for new installations.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Download and install [https://www.phing.info/ Phing]. Other build tools are available! You could install Phing in your own bin folder or in a system &#039;&#039;bin&#039;&#039; folder. You need to note the path to your Phing code. In this example it is &#039;&#039;~/bin/phing-latest.phar&#039;&#039;. You can try it out from the command line after changing into the folder containing your extension code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
cd ~/git/j4xdemos-mod-debugme&lt;br /&gt;
php ~/bin/phing-latest.phar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
Response:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
Buildfile: /Users/ceford/git/j4xdemos-mod-debugme/build.xml&lt;br /&gt;
 &lt;br /&gt;
mod_debugme &amp;gt; main:&lt;br /&gt;
      ... Any copied files will be mentioned here&lt;br /&gt;
      [zip] Building zip: /Users/ceford/zips/mod_debugme.zip&lt;br /&gt;
 &lt;br /&gt;
BUILD FINISHED&lt;br /&gt;
 &lt;br /&gt;
Total time: 0.0863 seconds&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== VS Code Tasks == &amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
To run Phing from within VS Code you need to create a &#039;&#039;tasks.json&#039;&#039; file in the &#039;&#039;.vscode&#039;&#039; folder in the root of the &#039;&#039;j4xdemos-mod-debugme&#039;&#039; folder. If the latter does not exist, create it. Then create the &#039;&#039;tasks.json&#039;&#039; file and enter the following code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	// See https://go.microsoft.com/fwlink/?LinkId=733558&lt;br /&gt;
	// for the documentation about the tasks.json format&lt;br /&gt;
	&amp;quot;version&amp;quot;: &amp;quot;2.0.0&amp;quot;,&lt;br /&gt;
	&amp;quot;tasks&amp;quot;: [&lt;br /&gt;
	  {&lt;br /&gt;
		&amp;quot;label&amp;quot;: &amp;quot;Build mod_debugme&amp;quot;,&lt;br /&gt;
		&amp;quot;type&amp;quot;: &amp;quot;shell&amp;quot;,&lt;br /&gt;
		&amp;quot;command&amp;quot;: &amp;quot;php ~/bin/phing-latest.phar&amp;quot;,&lt;br /&gt;
		&amp;quot;windows&amp;quot;: {&lt;br /&gt;
		  &amp;quot;command&amp;quot;: &amp;quot;php ~/bin/phing-latest.phar&amp;quot;&lt;br /&gt;
		},&lt;br /&gt;
		&amp;quot;group&amp;quot;: &amp;quot;build&amp;quot;,&lt;br /&gt;
		&amp;quot;presentation&amp;quot;: {&lt;br /&gt;
		  &amp;quot;reveal&amp;quot;: &amp;quot;always&amp;quot;,&lt;br /&gt;
		  &amp;quot;panel&amp;quot;: &amp;quot;shared&amp;quot;&lt;br /&gt;
		}&lt;br /&gt;
	  }&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
Windows users need to fix the Windows-specific command. You can now build the extension using the menu &#039;&#039;Terminal / Run Build Task&#039;&#039;. The result of the command should appear in the Terminal Panel beneath the Edit area.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
  *  Executing task: php ~/bin/phing-latest.phar &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
Buildfile: /Users/ceford/git/gitdemo/j4xdemos-mod-debugme/build.xml&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
mod_debugme &amp;gt; main:&lt;br /&gt;
&lt;br /&gt;
      &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
[zip] Nothing to do: /Users/ceford/zips/mod_debugme.zip is up to date.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
BUILD FINISHED&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
Total time: 0.1031 seconds&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
*  Terminal will be reused by tasks, press any key to close it. &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
There may be incomprehensible error messages. The most likely cause is in having invalid paths to folders in the &#039;&#039;build.xml&#039;&#039; file or a folder has not been created. Just another sort of problem to debug!&lt;br /&gt;
&lt;br /&gt;
== Debugging == &amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
You should be able to fix the first bug by code inspection. More complicated problems require stepping though the code with the debugger. That allows you to inspect variables to see if they contain values that you expect, for example when passing arguments to library functions.&lt;br /&gt;
&lt;br /&gt;
=== &#039;&#039;php.ini&#039;&#039; Settings === &amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
To set up debugging with Xdebug you need to make some entries at the top of your &#039;&#039;php.ini&#039;&#039; file.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
zend_extension=&amp;quot;xdebug.so&amp;quot;&lt;br /&gt;
xdebug.mode=&amp;quot;debug&amp;quot;&lt;br /&gt;
xdebug.client_port=9003&lt;br /&gt;
xdebug.start_with_request = yes&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
After saving any changes, restart your Apache server.&lt;br /&gt;
&lt;br /&gt;
=== Add Website Window === &amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
Your extension folder contains just a few files, the &#039;&#039;&#039;&#039;&#039;sources&#039;&#039;&#039;&#039;&#039; of the files installed in your website. Runtime debugging involves setting breakpoints in your &#039;&#039;&#039;&#039;&#039;site&#039;&#039;&#039;&#039;&#039; files so you need access to those files. You could use the &#039;&#039;File / Add Folder to Workspace...&#039;&#039; menu to add the site folder to your Workspace. However, there is a very good chance you will end up making changes to site files instead of source files. So it is probably best to open a separate VS Code window for debugging.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Open new window:&#039;&#039;&#039; From the VS Code menu, select &#039;&#039;File / New Window&#039;&#039; and select the folder containing your Joomla website.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Open folder:&#039;&#039;&#039; In the newly opened window, select &#039;&#039;File / Open Folder...&#039;&#039; from the VS Code menu. Find your website folder and select it. You should see a list of all the files in your Joomla website in the Primary sidebar.&lt;br /&gt;
&lt;br /&gt;
=== Launch Configuration === &amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
For debug to actually work in VS Code you need a launch configuration. In the root of your website create a folder named &#039;&#039;.vscode&#039;&#039; (note the leading stop) containing a file named &#039;&#039;launch.json&#039;&#039; with the following content:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
	&amp;quot;configurations&amp;quot;: [&lt;br /&gt;
		{&lt;br /&gt;
			&amp;quot;name&amp;quot;: &amp;quot;Listen for XDebug&amp;quot;,&lt;br /&gt;
            &amp;quot;type&amp;quot;: &amp;quot;php&amp;quot;,&lt;br /&gt;
            &amp;quot;request&amp;quot;: &amp;quot;launch&amp;quot;,&lt;br /&gt;
            &amp;quot;hostname&amp;quot;: &amp;quot;0.0.0.0&amp;quot;,&lt;br /&gt;
            &amp;quot;port&amp;quot;: 9003,&lt;br /&gt;
			&amp;quot;stopOnEntry&amp;quot;: true,&lt;br /&gt;
            &amp;quot;pathMappings&amp;quot;: {&lt;br /&gt;
                &amp;quot;/Users/ceford/Sites/j421rc2&amp;quot;: &amp;quot;${workspaceFolder}&amp;quot;&lt;br /&gt;
            }&lt;br /&gt;
		}&lt;br /&gt;
	]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Remember to replace the pathMappings item in this example with the actual pathMappings on your own site. The stopOnEntry item will pause execution on the very first line of PHP code executed.&lt;br /&gt;
&lt;br /&gt;
=== Debug &#039;&#039;mod_debugme&#039;&#039; === &amp;lt;!--T:60--&amp;gt;&lt;br /&gt;
Now you are ready to find and fix the bugs in the installed module.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;Find module code:&#039;&#039;&#039; Find the first bug on line 16 of &#039;&#039;JROOT/modules/mod_debugme/mod_debugme.php&#039;&#039;.&lt;br /&gt;
* &#039;&#039;&#039;Set breakpoint:&#039;&#039;&#039; Click in the space to the left of the number 16. A pale red blob will appear as you hover and turn full red after you click to indicate a break point has been set.&lt;br /&gt;
* &#039;&#039;&#039;Start debug:&#039;&#039;&#039; From the VS Code menu select &#039;&#039;Run / Start Debugging&#039;&#039;. In your browser reload your site. Your VS Code window should reappear with the code stopped at the first line of the site &#039;&#039;index.php&#039;&#039; file. At the top of the screen are some icons to control the debug process. They should be self-explanatory. If not, look them up in the VS Code Help / Documentation. &lt;br /&gt;
* &#039;&#039;&#039;Continue:&#039;&#039;&#039; Select the continue button - the code will run on to your first breakpoint. Examine the code to see what the problem is.&lt;br /&gt;
* &#039;&#039;&#039;Hover:&#039;&#039;&#039; If you hover over a variable that has been assigned a value a small Tooltip will appear summarizing that variables attributes. There is no Tooltip for variables that have not been assigned values.&lt;br /&gt;
* &#039;&#039;&#039;Variables:&#039;&#039;&#039; The left column contains more information about the state of the code at the breakpoint. There are too many to cover here. Explore them as required!&lt;br /&gt;
* &#039;&#039;&#039;Stop Debugging:&#039;&#039;&#039; It is probably best to select the Continue icon, otherwise the web page is delivered blank. Otherwise you could use the Stop button or the Run / Stop Debugging menu.&lt;br /&gt;
&lt;br /&gt;
=== Fix a Bug === &amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Remember:&#039;&#039;&#039; Do not fix the bug in the website code! Fix it in the source code!&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
Fix the source code and then use &#039;&#039;Terminal / Run Build Task...&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
Restart debug.&lt;br /&gt;
&lt;br /&gt;
=== Tips === &amp;lt;!--T:65--&amp;gt;&lt;br /&gt;
A few not so obvious problems:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
* You fix the first bug but it still crashes on that line. Look in mod_debugme.xml to see where the source of namespaced classes is defined. When fixed in the source you need to reinstall the zip file or delete &#039;&#039;administrator/cache/autoload_psr4.php&#039;&#039;. When absent, Joomla rebuilds that file from manifest files. But if it has an incorrect or missing entry it does not get fixed until the extension is reinstalled.&lt;br /&gt;
* Sometimes you need to set a breakpoint a few lines before the line where the error occurs, especially if you wish to check values passed to function calls.&lt;br /&gt;
* Table &#039;&#039;xxx.yyy\_debugme&#039;&#039; doesn&#039;t exist. Ah yes, the code to create a table on install and remove on uninstall was never created. You will need to run an SQL query in phpMyAdmin using the content of the &#039;&#039;mod\_debugme.sql&#039;&#039; file. Remember to change &#039;&#039;#\_&#039;&#039; in the table names for your database prefix. And when it still fails check the table name in the code.&lt;br /&gt;
&lt;br /&gt;
== Screenshot == &amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
When all is fixed this is what you might see:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
[[File:J4.x-vscode-primer-debugme-fixed-en.png|border]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
Cake days?&lt;br /&gt;
&lt;br /&gt;
== References == &amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
From Joomla! Documentation: [[Visual Studio Code]] also covers configuration of other tools, for example CodeSniffer and PHPUnit.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Potential_backward_compatibility_issues_in_Joomla_4&amp;diff=1004167</id>
		<title>Potential backward compatibility issues in Joomla 4</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Potential_backward_compatibility_issues_in_Joomla_4&amp;diff=1004167"/>
		<updated>2023-06-23T22:45:13Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup and capitalization changes. Some Words2Watch changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{incomplete}}{{RightTOC}}&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
This document tracks potential backward compatibility issues for Joomla! 4. Listed are issues which potentially break extensions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The base of this comparison is Joomla! 3.10.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Updated System Requirements == &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
The system requirements have been updated as follows:&lt;br /&gt;
*PHP 7.2.5&lt;br /&gt;
*MySQL 5.6&lt;br /&gt;
*PostgreSQL 11.0&lt;br /&gt;
*SQL Server support has been dropped.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== PHP MySQL Extension === &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
*Joomla no longer supports using PHP&#039;s ext/MySQL driver (which was removed in PHP 7.0). Joomla will automatically try to use the MySQLi extension (available since PHP 5.3) or the MySQL PDO Driver (available since PHP 5.3). Otherwise it will fail to create a database connection.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:196--&amp;gt; * Strict mode has been enabled. The following flags are now active by default in Joomla 4 and you may have to update your database queries accordingly. This will help us with future MySQL version upgrades and also aligns more closely with PostgreSQL to enable easier compatibility with queries in both languages.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&#039;STRICT_TRANS_TABLES&#039;,&lt;br /&gt;
&#039;ERROR_FOR_DIVISION_BY_ZERO&#039;,&lt;br /&gt;
&#039;NO_AUTO_CREATE_USER&#039;,&lt;br /&gt;
&#039;NO_ENGINE_SUBSTITUTION&#039;,&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:215--&amp;gt;&lt;br /&gt;
As a consequence, Joomla 4 will only use &#039;&#039;&#039;NULL date defaults&#039;&#039;&#039;. The use of the &#039;&#039;invalid default date&#039;&#039; of 0000-00-00 00:00:00 in Joomla 4 has been deprecated.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== PHP PostgreSQL Extension === &amp;lt;!--T:105--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:106--&amp;gt; Joomla no longer supports using PHP&#039;s ext/pgsql driver. Joomla will automatically try to use the PostgreSQL PDO Driver (available since PHP 5.3 and Joomla 3.9). Otherwise it will fail to create a database connection with a PostgreSQL database.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== PHP GMP Extension === &amp;lt;!--T:211--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:212--&amp;gt; This is required for using the [[WebAuthn Passwordless Login]] feature. Note the PHP GMP Extension is installed by default on the majority of hosting sites. The [[WebAuthn Passwordless Login]] System Plugin is enabled by default in Joomla 4 on HTTPS sites.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHP &#039;&#039;mcrypt&#039;&#039; Extension === &amp;lt;!--T:213--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:214--&amp;gt; This is required for using the Joomla\CMS\Crypt\Cipher\CrytoCipher class and its alias JCryptCipherCrypto.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== CMS Libraries == &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
The following changes have been made to Joomla! CMS libraries (this is primarily code that was found in the “libraries/cms” directory in Joomla! 3.7 and earlier).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Installer === &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:107--&amp;gt; Plugin discover installs will no longer search for XML files in the Joomla! 1.5 plugin folder layouts&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:108--&amp;gt; In 3.x, only plugins scripts have the preflight method called and none make postflight available during the uninstall process. All extensions types will have these hooks available in 4.0 when being uninstalled. If you currently preflight and postflight and assume they only apply in an install/update context - this logic is now incorrect and you should use the install route (given as one of the method parameters)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:109--&amp;gt; When uninstalling a plugin the uninstall function in the extension script is now triggered before triggering any SQL queries (this is now consistent with all other extension types).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Removed Classes ==== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
The following classes have been removed in Joomla! 4.0:&lt;br /&gt;
*JInstallerComponent (use JInstallerAdapterComponent instead)&lt;br /&gt;
*JInstallerFile (use JInstallerAdapterFile instead)&lt;br /&gt;
*JInstallerLanguage (use JInstallerAdapterLanguage instead)&lt;br /&gt;
*JInstallerLibrary (use JInstallerAdapterLibrary instead)&lt;br /&gt;
*JInstallerModule (use JInstallerAdapterModule instead)&lt;br /&gt;
*JInstallerPackage (use JInstallerAdapterPackage instead)&lt;br /&gt;
*JInstallerPlugin (use JInstallerAdapterPlugin instead)&lt;br /&gt;
*JInstallerTemplate (use JInstallerAdapterTemplate instead)&lt;br /&gt;
*JSubMenuHelper (use JHtmlSidebar instead; note that in contrast to JSubMenuHelper, this requires an addition of a placeholder in your view template)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== JInstallerAdapter Inheritance ==== &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
JInstallerAdapter no longer extends from JAdapterInstance and inherently JObject.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:110--&amp;gt; Custom Installer Adapters must now be autoloaded.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Menu === &amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== JMenu is Now an Abstract Class ==== &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
JMenu is now an abstract class. Subclasses of JMenu must now also implement a load method.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Manual Include Behavior Removed ==== &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
The logic in JMenu::getInstance() to manually include a file from the application&#039;s includes/menu.php path has been removed. The JMenu subclass should be autoloaded instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== JMenuItem ==== &amp;lt;!--T:216--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:217--&amp;gt;&lt;br /&gt;
* You can no longer retrieve the params property from JMenuItem directly. Use the getParams() method instead (available since Joomla 3.7)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:218--&amp;gt;&lt;br /&gt;
* JMenuItem::set and JMenuItem::get have been removed. Properties must be explicitly named&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:219--&amp;gt;&lt;br /&gt;
* There is now a AdministratorMenuItem class which extends from MenuItem that contains extra public properties used for the Administrator menu item.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Pagination === &amp;lt;!--T:220--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:221--&amp;gt;&lt;br /&gt;
* The magic pagination functions &#039;&#039;pagination_item_active&#039;&#039;, &#039;&#039;pagination_item_inactive&#039;&#039; have been removed. Use the JLayout&#039;s joomla.pagination.link instead&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:222--&amp;gt;&lt;br /&gt;
* The magic pagination function &#039;&#039;pagination_list_render&#039;&#039; is deprecated. Use the JLayout joomla.pagination.list instead&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Pathway === &amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Manual Include Behavior Removed ==== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
The logic in JPathway::getInstance() to manually include a file from the application&#039;s &#039;&#039;includes/pathway.php&#039;&#039; path has been removed. The JPathway subclass should be autoloaded instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Router === &amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Manual Include Behavior Removed ==== &amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
The logic in JRouter::getInstance() to manually include a file from the application&#039;s &#039;&#039;includes/router.php&#039;&#039; path has been removed. The JRouter subclass should be autoloaded instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Method Signature Changes ==== &amp;lt;!--T:111--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:112--&amp;gt; The attachBuildRule and attachParseRule are now typehinted to require callables.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== JVersion === &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
Support for accessing the JVersion class constants as class properties is no longer supported. The constants were introduced in Joomla! 3.5 to prevent the old class properties from being edited.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:113--&amp;gt; The following deprecated constants have been removed:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* JVersion::RELEASE&lt;br /&gt;
* JVersion::DEV_LEVEL&lt;br /&gt;
* JVersion::BUILD&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== JHtml === &amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:115--&amp;gt; The register function in JHtml is now typehinted to require a callable. Subclasses of JHtml will now need to match this signature (note this was already required at the function code level).&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:116--&amp;gt; JHtml::_ no longer allows you to call non-public methods in JHtml&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt; JHtml::_ is now a final method (you can no longer override it if you subclass JHtml) and its signature has changed to take advantage of modern PHP features (scalar and variadic typehints)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:191--&amp;gt; JHtmlBootstrap::modal has been removed. Use JHtmlBootstrap::renderModal&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:223--&amp;gt; JHtmlSortablelist::sortable has been deprecated in favour of JHtmlDraggablelist::draggable - the old method acts as a proxy to the new method currently to facilitate the removal of jQuery UI from Joomla Core. All media assets relating to the original jQuery UI implementation have been removed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:224--&amp;gt; JHtmlBatch has been removed as all the code had been moved to layouts for template overrides. Use the JLayouts directly in your code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Updater === &amp;lt;!--T:209--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:210--&amp;gt;&lt;br /&gt;
* We removed the deprecated integer client handling from the updater extension adapter class. Please use &#039;&#039;&#039;site&#039;&#039;&#039; and &#039;&#039;&#039;administrator&#039;&#039;&#039; now and not the integer values &#039;&#039;&#039;0&#039;&#039;&#039; / &#039;&#039;&#039;1&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Platform == &amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
The following changes have been made to Joomla! Platform libraries. This is primarily code found in the &#039;&#039;libraries/joomla&#039;&#039; or &#039;&#039;libraries/legacy&#039;&#039; directories in Joomla! 3.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Access === &amp;lt;!--T:225--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:226--&amp;gt;&lt;br /&gt;
* JAccess::$assetPermissionsById and JAccess::$assetPermissionsByName and JAccess::preloadPermissionsParentIdMapping have been removed without replacement. Since 3.6 we&#039;ve used other methods and class properties to optimize the loading of assets. See the [https://github.com/joomla/joomla-cms/pull/12850 JAccess bug fixes and optimizations pull request] to see the reasons for this deprecation.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:227--&amp;gt;&lt;br /&gt;
* JAccess::getActions has been removed. Use JAccess::getActionsFromFile or JAccess::getActionsFromData instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Application === &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Removed Classes ==== &amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
The following classes have been removed in Joomla! 4.0:&lt;br /&gt;
*JApplicationWebRouter (use the `joomla/router` package instead)&lt;br /&gt;
*JApplicationWebRouterBase (use the `joomla/router` package instead)&lt;br /&gt;
*JApplicationWebRouterRest (use the `joomla/router` package instead)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:228--&amp;gt;&lt;br /&gt;
All references to JSite and JAdministrator have been removed (these were just class alias&#039; since Joomla 3.2)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Deprecated Classes ==== &amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
The following classes have been deprecated and scheduled for removal in Joomla! 5.0:&lt;br /&gt;
*JApplicationBase (use Joomla\Application\AbstractApplication instead)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== CLI/Web Class Changes ==== &amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
The JApplicationCli and JApplicationWeb classes have been recomposed to extend from the Framework&#039;s Application package instead. This breaks type checks for a JApplicationBase object. For forward compatibility, it is recommended to check if application classes are an instance of Joomla\Application\AbstractApplication (JApplicationBase has extended this class since Joomla! 3.4).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
Additionally, both of these classes are now abstract. Developers implementing these classes must provide a &#039;&#039;doExecute&#039;&#039; method with their application&#039;s logic.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:118--&amp;gt; The registerEvent method is now typehinted to require a callable for the $handler parameter.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:178--&amp;gt; Applications that want to support both Web and CLI Applications should now typehint against the \Joomla\CMS\Application\ CMSApplicationInterface - this contains common methods (some of which in Joomla 3.x were only found in the JApplicationCms class) that can be used by all code. It&#039;s strongly recommended any custom applications (especially CLI applications) implement this interface to make compatibility checks easier, simultaneously any typehints should use the interface rather than a concrete class.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== JApplicationCli =====&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
Old:&amp;lt;/translate&amp;gt; JApplicationCli{{rarr}}JApplicationBase{{rarr}} Joomla\Application\AbstractApplication&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
New:&amp;lt;/translate&amp;gt; JApplicationCli{{rarr}}Joomla\Application\AbstractCliApplication{{rarr}} Joomla\Application\AbstractApplication&lt;br /&gt;
&lt;br /&gt;
===== JApplicationWeb =====&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
Old:&amp;lt;/translate&amp;gt; JApplicationWeb{{rarr}}JApplicationBase{{rarr}} Joomla\Application\AbstractApplication&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
New:&amp;lt;/translate&amp;gt; JApplicationWeb{{rarr}}Joomla\Application\AbstractWebApplication{{rarr}} Joomla\Application\AbstractApplication&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:179--&amp;gt;&lt;br /&gt;
* The legacy ways of calling JApplicationWeb::redirect have been removed&lt;br /&gt;
** With a message and messageType parameters. (Call enqueueMessage separately.)&lt;br /&gt;
** Passing in a true/false value as the 2nd/3rd parameters instead of a redirect code will give an InvalidArgumentException instead of defaulting to a 303.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:180--&amp;gt; * JApplicationWeb::$singleValueResponseHeaders has been removed because the Framework Application will be internally using PSR-7 Response objects as of its 2.0 release. This changes how the headers data is stored so it is always a multi-dimensional array with each top level key being the header names and the value being an array holding all of the values for that header.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== CMSApplication =====&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt; The $_clientId, $_messageQueue and $_name class properties have all been renamed to remove their underscore prefix.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:181--&amp;gt; Now implements CMSApplicationInterface.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:182--&amp;gt; If there is an error retrieving a Pathway, Router or Menu object using the respective methods, the exception will now bubble up rather than the method silently catching the exception and returning null.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:183--&amp;gt; CMSApplication::getInstance will now additionally try to load the user object (using the loadIdentity function).&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:206--&amp;gt; CMSApplication::isSite and CMSApplication::isAdmin have been removed as with the addition of the ConsoleApplication and ApiApplication can give misleading results. Please use CMSApplication::isClient (available from {{JVer | 3.7}}). For more information please see [[S:MyLanguage/J3.x:Discover_on_which_client_your_extension_code_is_running|Discover on which client your extension code is running]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== JApplicationSite =====&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:120--&amp;gt;&lt;br /&gt;
The $_language_filter and $_detect_browser class properties have all been renamed to remove their underscore prefix.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:121--&amp;gt; The deprecated method JApplicationSite::getPageParameters has been removed in favour of its alias JApplicationSite::getParams&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== JApplicationHelper =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:122--&amp;gt; JApplicationHelper::parseXMLLangMetaFile has been removed without replacement.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Archive === &amp;lt;!--T:123--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:124--&amp;gt; The archive package has been removed in favour of the frameworks archive package. Note the API should remain unchanged.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:184--&amp;gt; Errors handing now uses Exceptions rather than JError&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Client ===&lt;br /&gt;
\Joomla\CMS\Client\ClientWrapper &amp;lt;translate&amp;gt;&amp;lt;!--T:229--&amp;gt; has been removed. Use the static methods in&amp;lt;/translate&amp;gt; \Joomla\CMS\Client\ClientHelper&lt;br /&gt;
&lt;br /&gt;
=== Crypt ===&lt;br /&gt;
* JCrypt::hasStrongPasswordSupport &amp;lt;translate&amp;gt;&amp;lt;!--T:230--&amp;gt; has been removed without replacement as all PHP versions Joomla 4 matches will support strong password hashing.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Removed Classes ==== &amp;lt;!--T:98--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:99--&amp;gt;&lt;br /&gt;
The following ciphers have been removed in Joomla! 4.0:&amp;lt;/translate&amp;gt;&lt;br /&gt;
*JCryptCipher3Des&lt;br /&gt;
*JCryptCipherBlowfish&lt;br /&gt;
*JCryptCipherMcrypt&lt;br /&gt;
*JCryptCipherRijndael256&lt;br /&gt;
*JCryptCipherSimple&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:100--&amp;gt;&lt;br /&gt;
These have been removed without replacement. Use JCryptCipherCrypto&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Removed Methods ==== &amp;lt;!--T:167--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:185--&amp;gt; JCrypt::hasStrongPasswordSupport has been removed without replacement (this attempted to detect bcrypt polyfills on linux hosting but has always returned true since we required PHP 5.3.10 in Joomla 3.3)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Cache === &amp;lt;!--T:186--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;gt; JCacheController::get now requires a callable. As a result JCacheControllerCallback::call has been removed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:127--&amp;gt; JCacheStorage::test has been removed. Use JCacheStorage::isSupported instead&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:128--&amp;gt; The default storage engines are no longer manually loaded as they are now autoloaded&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:129--&amp;gt; JCacheControllerOutput::start and JCacheControllerOutput::end have been removed without replacement&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt; Removed CacheLite storage as it not compatible with PHP7 (which is our minimum version)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:187--&amp;gt; Error handling now uses Exceptions instead of JError&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Component === &amp;lt;!--T:131--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:132--&amp;gt; \Joomla\CMS\Component\ComponentRecord no longer extends JObject&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Document === &amp;lt;!--T:101--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Inheritance Change ==== &amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt;&lt;br /&gt;
The following classes have had their inheritance changed:&lt;br /&gt;
*JDocumentError (now extends from \Joomla\Cms\Document\HtmlDocument instead of \Joomla\Cms\Document\Document)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:133--&amp;gt; Note as a result of this change rendering an error page resets the document object in Joomla\CMS\Factory::$document, the rationale being we want a clean document to work from; if the error page is triggered we aren&#039;t interested in the metadata your component has set, or the media added from some bad module, or whatever plugins are adding to the display. We want a clean environment for rendering the error page only containing the error page&#039;s loaded data.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Renderers ==== &amp;lt;!--T:134--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:135--&amp;gt; In order to comply with the RSS feed specification, JDocumentRendererFeedRss now allows the lastBuildDate element to be configured using the JDocumentFeed::$lastBuildDate class property when a feed is rendered.  This value defaults to the current time, as is the case with Joomla! 3.x and earlier, however the time can be correctly set by changing this class property to a JDate object representing the desired timestamp.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt; There is now a RendererInterface that all Renderers should implement&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:137--&amp;gt; JDocumentRenderer is now an abstract class and implements RendererInterface&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:188--&amp;gt; As an alternative to &amp;lt;jdoc:include type=&amp;quot;head&amp;quot; /&amp;gt; you can now individually load &amp;lt;jdoc:include type=&amp;quot;metas&amp;quot; /&amp;gt; for metadata, &amp;lt;jdoc:include type=&amp;quot;styles&amp;quot; /&amp;gt; for CSS and &amp;lt;jdoc:include type=&amp;quot;scripts&amp;quot; /&amp;gt; for JavaScript. The intention of this is to optionally allow users to place all JavaScript at the bottom of the HTML Document in their templates.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== JDocumentFeed ====&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
The property type of JDocumentFeed::$lastBuildDate has changed from a string to a JDate object. The property was previously unused by the core Joomla API but extensions may have used it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Database === &amp;lt;!--T:138--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:139--&amp;gt; This package has been replaced by the Joomla Framework Database Package&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:197--&amp;gt; Debug mode has been reworked (see the framework docs for more information&amp;lt;/translate&amp;gt; [https://github.com/joomla-framework/database])&lt;br /&gt;
&lt;br /&gt;
=== Factory ===&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:140--&amp;gt; Factory::getApplication no longer takes arguments. These were misleading as it always returned the active application after the first call in the bootstrap, whatever arguments were passed into the function.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:141--&amp;gt; Factory::getXml has been removed along with JXMLElement. Use SimpleXMLElement directly instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:142--&amp;gt; Factory:: getEditor has been removed use JEditor::getInstance instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:278--&amp;gt; Factory:: getUri has been removed use Uri::getInstance() instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Environment === &amp;lt;!--T:198--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;noinclude&amp;gt;JBrowser::isSSLConnection has been removed. Use JApplicationCms::isSSLConnection (available since Joomla 3.2)&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Filesystem === &amp;lt;!--T:207--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:208--&amp;gt; The filesystem wrapper classes have been removed. Continue using the original static methods.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Filter ===&lt;br /&gt;
* JFilterInput::_remove &amp;lt;translate&amp;gt;&amp;lt;!--T:231--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFilterInput::remove&lt;br /&gt;
* JFilterInput::_cleanTags &amp;lt;translate&amp;gt;&amp;lt;!--T:232--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFilterInput::cleanTags&lt;br /&gt;
* JFilterInput::_cleanAttributes &amp;lt;translate&amp;gt;&amp;lt;!--T:233--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFilterInput::cleanAttributes&lt;br /&gt;
* JFilterInput::_decode &amp;lt;translate&amp;gt;&amp;lt;!--T:234--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFilterInput::decode&lt;br /&gt;
* JFilterInput::_escapeAttributeValues &amp;lt;translate&amp;gt;&amp;lt;!--T:235--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFilterInput::escapeAttributeValues&lt;br /&gt;
* JFilterInput::_stripCSSExpressions &amp;lt;translate&amp;gt;&amp;lt;!--T:236--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFilterInput::stripCSSExpressions&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:237--&amp;gt;&lt;br /&gt;
All of the above deprecations and removals are to allow the class to be reunified with the framework parent class.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Form ===&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:143--&amp;gt; The libraries/joomla/form/fields and libraries/joomla/form/rules directories are no longer registered to find form classes, all form classes should be autoloaded instead&amp;lt;/translate&amp;gt;&lt;br /&gt;
*&amp;lt;translate&amp;gt;&amp;lt;!--T:192--&amp;gt; Two new properties added addfieldprefix which registers a namespace prefix for extensions (intended to be used as a replacement for addfieldpath). For example usage please see [https://github.com/joomla/joomla-cms/pull/16419 this GitHub PR]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:193--&amp;gt; JForm::getControlGroup has been removed use the alias JForm::renderField (available since Joomla 3.2.3)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:194--&amp;gt; JForm::getControlGroups has been removed use the alias JForm::renderFieldset (available since Joomla 3.2.3)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:238--&amp;gt;&lt;br /&gt;
* When rendering a field using the hiddenLabel option in JForm - it now only hides the label from the User Interface - the HTML is still rendered with the sr-only class for screen-reader accessibility purposes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:199--&amp;gt; JFormFieldUsergroup has been removed. Use Joomla\CMS\Form\Field\UsergrouplistField instead (available since Joomla 3.2)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:239--&amp;gt;&lt;br /&gt;
* The Form class has removed the protected methods filterField() and validateField(). This will break any custom Form classes that extends core Form and use these methods. This has been replaced in favour of filtering at the field level (see https://github.com/joomla/joomla-cms/pull/12414 for more information)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Fields ====&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:205--&amp;gt;&lt;br /&gt;
JFormFieldFilelist and JFormFieldFolderList have had their filter properties renamed to &amp;lt;code&amp;gt;fileFilter&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;folderFilter&amp;lt;/code&amp;gt; respectively (in order to allow the use of the regular Joomla filter attribute on returned values)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* JFormPredefinedlistField &amp;lt;translate&amp;gt;&amp;lt;!--T:240--&amp;gt; has its filter properties renamed to &amp;lt;code&amp;gt;optionsFilter&amp;lt;/code&amp;gt; (in order to allow the use of the regular Joomla filter attribute on returned values)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* JFormFieldEditor::save &amp;lt;translate&amp;gt;&amp;lt;!--T:241--&amp;gt; has been removed without replacement&amp;lt;/translate&amp;gt;&lt;br /&gt;
* JFormFieldText::getSuggestions &amp;lt;translate&amp;gt;&amp;lt;!--T:242--&amp;gt; has been removed in favour of&amp;lt;/translate&amp;gt; JFormFieldText::getOptions&lt;br /&gt;
&lt;br /&gt;
==== Media Field ====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:283--&amp;gt; The Media field type now encodes image metadata into the internal value. This is a sample value:&amp;lt;/translate&amp;gt;&amp;lt;/br&amp;gt;&#039;&#039;images/banners/osmbanner1.png#joomlaImage://local-images/banners/osmbanner1.png?width=468&amp;amp;height=60&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:284--&amp;gt; To produce the final Image URL or the relative image file path, you can use the new helper:&amp;lt;/translate&amp;gt;&amp;lt;/br&amp;gt;&#039;&#039;echo \Joomla\CMS\HTML\HTMLHelper::cleanImageURL($oldValue);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:285--&amp;gt; To get the clean value (without adapter information and metadata) from the value which is stored in media form field: &amp;lt;/translate&amp;gt;&amp;lt;/br&amp;gt;&#039;&#039;echo \Joomla\CMS\Helper\MediaHelper::getCleanMediaFieldValue($oldValue);&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:286--&amp;gt; Function cleanImageURL does not clean the image URL but returns object where one part of the object is cleaned URL. Using echo throws an error. For more information visit [https://github.com/joomla/joomla-cms/issues/35871#issuecomment-968107241]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Wrapper === &amp;lt;!--T:291--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:243--&amp;gt; * The form wrapper classes have been removed. Continue using the original static methods.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== HTTP ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Deprecated Classes and Interfaces ==== &amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
The following classes and interfaces have been deprecated and scheduled for removal in Joomla! 5.0:&lt;br /&gt;
*JHttpResponse (use Joomla\Http\Response instead)&lt;br /&gt;
*JHttpTransport (implement Joomla\Http\TransportInterface instead)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Class Changes ==== &amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
The Framework&#039;s HTTP package is now included in Joomla! 4.0 and JHttp and the JHttpTransport subclasses have been refactored to use the upstream package.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== JHttp =====&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:277--&amp;gt; * JHttp no longer ships with a cacerts.pem bundle in the transports directory use the composer/ca-bundle instead which ships with core.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
The JHttp class constructor has been loosened with the following changes:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
*The options parameter is no longer typehinted as a Joomla\Registry\Registry object, an array or any object implementing the [https://secure.php.net/manual/en/class.arrayaccess.php ArrayAccess] interface can be used instead&lt;br /&gt;
*The transport parameter now allows any Joomla\Http\TransportInterface object.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== JHttpTransport =====&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
The now deprecated JHttpTransport interface extends Joomla\Http\TransportInterface now and has caused backward compatibility breaking changes in the interface.  The constructor is no longer part of the interface, and the interface&#039;s `request()` method has had a signature change.  Specifically, the second parameter which previously typehinted the JUri class now typehints Joomla\Uri\UriInterface.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== JHttpResponse =====&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
In refactoring the response object to inherit from the Framework&#039;s HTTP package, which is now using the PSR-7 ResponseInterface API, a minor compatibility break has been made in the structure of the response headers.  As of 4.0, this will now always be a multi-dimensional array where the key is the header name and the value is an array of values for that header (previously, this was a string).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Image === &amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Deprecated Classes and Interfaces ==== &amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt;&lt;br /&gt;
The following classes and interfaces have been deprecated and scheduled for removal in Joomla! 5.0:&lt;br /&gt;
* JImageFilter (use Joomla\CMS\Image\ImageFilter instead)&lt;br /&gt;
* JImageFilterBackgroundfill (use Joomla\CMS\Image\Filter\Backgroundfill instead)&lt;br /&gt;
* JImageFilterBrightness (use Joomla\CMS\Image\Filter\Brightness instead)&lt;br /&gt;
* JImageFilterContrast (use Joomla\CMS\Image\Filter\Contrast instead)&lt;br /&gt;
* JImageFilterEdgedetect (use Joomla\CMS\Image\Filter\Edgedetect instead)&lt;br /&gt;
* JImageFilterEmboss (use Joomla\CMS\Image\Filter\Emboss instead)&lt;br /&gt;
* JImageFilterGrayscale (use Joomla\CMS\Image\Filter\Grayscale instead)&lt;br /&gt;
* JImageFilterNegate (use Joomla\CMS\Image\Filter\Negate instead)&lt;br /&gt;
* JImageFilterSketchy (use Joomla\CMS\Image\Filter\Sketchy instead) &lt;br /&gt;
* JImageFilterSmooth (use Joomla\CMS\Image\Filter\Smooth instead)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Class Changes ==== &amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
The classes from Framework&#039;s Image package have been inlined into CMS and JImage and the JImageFilter subclasses have been refactored to use them. I.e. all classes under Joomla\Image namespace moved to Joomla\CMS\Image namespace.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Menu === &amp;lt;!--T:144--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:145--&amp;gt; JMenu::$_items, JMenu::$_default and JMenu::$_active have been had their underscore prefix&#039;s removed (note these properties were protected so this only affects custom subclasses of JMenu)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== New MVC Layer === &amp;lt;!--T:287--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:244--&amp;gt;&lt;br /&gt;
* This has been removed in Joomla 4. We have decided that this effort was not successful and as a result have continued development work on the original MVC Layer (see the &amp;quot;Legacy MVC&amp;quot; section). There is a plugin located [https://github.com/joomla-extensions/legacy-mvc on GitHub] you can ship with your extensions whilst you migrate them back to the Legacy MVC (note that this is not shipped by default in Joomla 4).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Keychain ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:146--&amp;gt; Removing the keychain with 4.0 has resulted in the removal of the following class:&amp;lt;/translate&amp;gt;&lt;br /&gt;
*JKeychain&lt;br /&gt;
&lt;br /&gt;
=== Pathway ===&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:147--&amp;gt; JPathway::$_pathway and JPathway::$_count have been had their underscore prefix&#039;s removed (note these properties were protected so this only affects custom subclasses of JPathway)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:148--&amp;gt; JPathway::_makeItem has been removed in favour of JPathway::makeItem (note this method was protected so this only affects custom subclasses of JPathway)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Profiler ===&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:245--&amp;gt; JProfiler::getmicrotime and JProfiler::getMemory have been removed in favour of the native PHP methods they wrapped (&amp;lt;source lang=&amp;quot;php&amp;quot; inline&amp;gt;microtime(1)&amp;lt;/source&amp;gt; and &amp;lt;source lang=&amp;quot;php&amp;quot; inline&amp;gt;memory_get_usage()&amp;lt;/source&amp;gt; respectively)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Table === &amp;lt;!--T:149--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:150--&amp;gt;&lt;br /&gt;
* JTable::__construct database object is now typehinted to be a JDatabaseDriver.&lt;br /&gt;
** Subclasses of JTable will need to ensure they are passing a JDatabaseDriver object to the parent constructor&lt;br /&gt;
** Subclasses of JTable will need to change the method signature of setDbo() if they have an extended version of that method to include the typehint&lt;br /&gt;
* There is a new method JTable::hasField - all instances of property_exists on JTable instances will now use this proxy method instead to allow better interoperability of Table instances&lt;br /&gt;
* The JTableObserver pattern (and corresponding classes) has been removed from JTable. JTable now triggers events and Tags, Content History (and any other custom uses of this pattern) should move to standard plugins.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Mail === &amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
The following methods have been removed in Joomla! 4.0:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
* JMail::sendAdminMail has been removed&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Exceptions ==== &amp;lt;!--T:288--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:246--&amp;gt; JMail no longer catches exceptions from PHPMailer. It is now the object calling JMail&#039;s responsibility to handle these exceptions as appropriate. In addition if mail sending is disabled in global configuration calling &amp;lt;source lang=&amp;quot;php&amp;quot; inline&amp;gt;\ Joomla\CMS\Mail\Mail::send()&amp;lt;/source&amp;gt; will throw a &amp;lt;source lang=&amp;quot;php&amp;quot; inline&amp;gt;\Joomla\CMS\Mail\Exception\MailDisabledException&amp;lt;/source&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Language === &amp;lt;!--T:151--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt;&lt;br /&gt;
* The functions setTransliterator, setPluralSuffixesCallback, setIgnoredSearchWordsCallback, setLowerLimitSearchWordCallback, setUpperLimitSearchWordCallback and setSearchDisplayedCharactersNumberCallback are now typehinted to require a callable.&lt;br /&gt;
* The &amp;lt;tt&amp;gt;&amp;quot;_QQ_&amp;quot;&amp;lt;/tt&amp;gt; placeholder for double quotes has been removed (this only existed to work around an old PHP Bug that has been fixed). Escape double quotes if required (i.e. &amp;lt;tt&amp;gt;\&amp;quot;&amp;lt;/tt&amp;gt;)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:247--&amp;gt;&lt;br /&gt;
* The format for language file names has been changes to ease the work in 3rd party translation tools (such as Crowdin). INI language files no longer have to contain the language code (i.e. en-GB.com_contact.ini =&amp;gt; com_contact.ini), in this case the special case of en-GB.ini has been renamed to &#039;&#039;joomla.ini&#039;&#039; in the core language pack. en-GB.xml has been named langmetadata.xml. There is a b/c layer that will continue to read the old Joomla 3 file names throughout Joomla 4.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:248--&amp;gt;&lt;br /&gt;
* \Joomla\CMS\Language\Multilanguage::getSiteLangs has been removed. Use \Joomla\CMS\Language\LanguageHelper::getInstalledLanguages(0) instead&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:249--&amp;gt;&lt;br /&gt;
* JLanguage::exists has been removed. Use Joomla\CMS\Language\LanguageHelper::exists instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:250--&amp;gt;&lt;br /&gt;
* The wrapper classes JTextWrapper, LanguageHelperWrapper and TransliterateWrapper have been removed. Continue to use the static methods they wrapped.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:289--&amp;gt; * The pdf_fonts handling/support for language packs (&amp;lt;code&amp;gt;language/pdf_fonts&amp;lt;/code&amp;gt;) has been removed from the language installer ([https://github.com/joomla/joomla-cms/pull/31288 see GitHub PR #31288]).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Legacy MVC Layer === &amp;lt;!--T:65--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Legacy Controller ==== &amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
* JControllerLegacy has been removed from the legacy layer, and we no longer intend to remove it or its subclasses in the near future.&lt;br /&gt;
* JControllerLegacy no longer extends JObject. Controllers should not call any of the methods contained in the JObject class.&lt;br /&gt;
* JControllerLegacy implements an interface for multiple task controllers&lt;br /&gt;
* JControllerLegacy::_construct now takes additional arguments. If you were previously getting a Controller object through JControllerLegacy::getInstance you do not need to change your code.&lt;br /&gt;
** Parameter 2: An optional MVCFactoryInterface instance&lt;br /&gt;
** Parameter 3: An optional CMSApplicationInterface instance&lt;br /&gt;
** Parameter 4: An optional Input instance&lt;br /&gt;
** Parameter 5: An optional FormFactoryInterface instance&lt;br /&gt;
* JControllerForm now uses the StringInflector package to determine the list view. This should improve its ability to determine the list view of more view names. If extension developers find that their list view is no longer being found they should manually set the &#039;&#039;view_list&#039;&#039; class property in their controller.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Legacy View ==== &amp;lt;!--T:153--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:154--&amp;gt;&lt;br /&gt;
* JViewLegacy has been removed from the legacy layer, and we no longer intend to remove it or its subclasses in the near future.&lt;br /&gt;
* JViewHtml has been split into two classes - AbstractView and HtmlView. Abstract view contains the logic for accessing models and getting the name of the view and is intended to be a base class for non-Html views. Html view contains the same logic as before.&lt;br /&gt;
* There are now two subclasses of JViewHtml - \Joomla\CMS\MVC\View\ListView and \Joomla\CMS\MVC\View\FormView designed to speed up the development of list and form views and reduce code duplication.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Library ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:251--&amp;gt;&lt;br /&gt;
* JLibraryHelper::_load has been removed. Use \Joomla\CMS\Helper\LibraryHelper::loadLibrary instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Session === &amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
The session package has undergone a major refactoring to use the Framework&#039;s Session package. This change primarily affects the internals of the package; changes to the primary public API through the JSession class are minimal.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== String ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:195--&amp;gt; The old JString class alias has been removed. Use \Joomla\String\StringHelper instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Removed Classes and Interfaces ==== &amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
The following classes and interfaces have been removed in Joomla! 4.0:&amp;lt;/translate&amp;gt;&lt;br /&gt;
*JSessionExceptionUnsupported&lt;br /&gt;
*JSessionHandlerInterface&lt;br /&gt;
*JSessionHandlerJoomla&lt;br /&gt;
*JSessionHandlerNative&lt;br /&gt;
*JSessionStorage&lt;br /&gt;
*JSessionStorageApc&lt;br /&gt;
*JSessionStorageDatabase&lt;br /&gt;
*JSessionStorageMemcache&lt;br /&gt;
*JSessionStorageMemcached&lt;br /&gt;
*JSessionStorageNone&lt;br /&gt;
*JSessionStorageWincache&lt;br /&gt;
*JSessionStorageXcache&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== JSession ==== &amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:73--&amp;gt;&lt;br /&gt;
JSession now extends from the Framework&#039;s Joomla\Session\Session class. Many of the methods have a modified signature and a compatibility layer exists to help with the transition.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Namespace Parameter Deprecated ===== &amp;lt;!--T:74--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
The &#039;&#039;get&#039;&#039;, &#039;&#039;set&#039;&#039;, &#039;&#039;has&#039;&#039; and &#039;&#039;clear&#039;&#039; methods previously supported a namespace parameter. This parameter is now deprecated. The namespace should be prepended to the name before calling these methods.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== JSession::clear() Repurposed ===== &amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:77--&amp;gt;&lt;br /&gt;
In the Joomla\Session\Session class, the &#039;&#039;clear&#039;&#039; method is used to clear all data from the session store. In JSession, this method is used to remove a single key. When this method is called with parameters, it will call the new &#039;&#039;Joomla\Session\Session::remove()&#039;&#039; method.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== JSession::getInstance() Deprecated ===== &amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
The singleton &#039;&#039;getInstance()&#039;&#039; method has been deprecated. The session object should be retrieved from the active application or the dependency injection container instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Session Handlers ===== &amp;lt;!--T:80--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:81--&amp;gt;&lt;br /&gt;
In Joomla! 3.x and earlier, session handlers were represented by the JSessionStorage class and its subclasses. In Joomla! 4.0, session handlers are now implementations of Joomla\Session\HandlerInterface (which is an extension of PHP&#039;s [https://secure.php.net/manual/en/class.sessionhandlerinterface.php SessionHandlerInterface]. All handlers which were supported in Joomla! 3.x are still available in 4.0 in addition to two additional handlers: a handler natively implementing the APCu extension and a handler supporting Redis.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Social Media Libraries === &amp;lt;!--T:155--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:156--&amp;gt; The facebook, github, google, linkedin, openstreetmap, mediawiki and twitter packages have all been removed from the CMS.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== User ===&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:252--&amp;gt; JUser::getParameters has been removed. You can no longer retrieve all parameters for a user but instead use JUser::getParam to get individual parameters as required.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Helper ====&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:253--&amp;gt; JUserHelper::getCryptedPassword has been removed. Joomla 4 only supports hashing with the native PHP password_hash function (via JUserHelper::hashPassword (available since Joomla 3.2.1))&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:254--&amp;gt; JUserHelper::getSalt has been removed without replacement (it generated the hash&#039;s JUserHelper::getCryptedPassword which is now removed as above)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:255--&amp;gt; JUserHelper::invalidateCookie, JUserHelper::clearExpiredTokens and JUserHelper::getRememberCookieData have been removed without replacement. They had been unused in core since Joomla 3.2 when their logic was moved into the Cookie Authentication Plugin&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:256--&amp;gt; JUserWrapperHelper has been removed. Continue using the original static methods in JUserHelper.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Classes Removed Without Replacement === &amp;lt;!--T:82--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* JNode&lt;br /&gt;
* JTree&lt;br /&gt;
* JGrid&lt;br /&gt;
* JError &amp;lt;translate&amp;gt;&amp;lt;!--T:189--&amp;gt; (use native exceptions when error handling is required)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Utilities ==== &amp;lt;!--T:102--&amp;gt; &lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===== Removed Classes and Interfaces ===== &amp;lt;!--T:103--&amp;gt; &lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:104--&amp;gt;&lt;br /&gt;
The following classes and interfaces have been removed in Joomla! 4.0:&lt;br /&gt;
*JArrayHelper&lt;br /&gt;
use Joomla\Utilities\ArrayHelper; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== External Libraries == &amp;lt;!--T:83--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:84--&amp;gt;&lt;br /&gt;
The following changes have been made to the external libraries that Joomla! packages and ships.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHPMailer ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:85--&amp;gt;&lt;br /&gt;
Joomla! 4.0 ships with PHPMailer 6.  Please review the [https://github.com/PHPMailer/PHPMailer GitHub repository] for relevant changes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== PHPUTF8 ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:86--&amp;gt;&lt;br /&gt;
At Joomla! 3.4, the PHPUTF8 library lived in two locations in the Joomla! package; `libraries/phputf8` and `libraries/vendor/joomla/string/src/phputf8`.  In Joomla! 4.0, the copy of the library in `libraries/phputf8` has been removed.  The Joomla\String\StringHelper class exposes many of the library&#039;s functions and the Composer autoloader definition imports much of the library as well, however, if you need a feature that is not already included then you should import the required functions from the `libraries/vendor/joomla/string/src/phputf8` path.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== SimplePie ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:87--&amp;gt;&lt;br /&gt;
The SimplePie library is no longer included with Joomla! 4.0.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== jQuery ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:88--&amp;gt;&lt;br /&gt;
Joomla! 4.0 ships with jQuery 3.  Please review [https://jquery.com/upgrade-guide/3.0/ the upgrading guide] for relevant changes. Note that we are not including jQuery Migrate anymore either. We recommend using it locally to help debug your code if there are any issues.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== jQuery UI ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:257--&amp;gt; jQuery UI has been removed from Joomla 4. Whilst it hasn&#039;t been officially announced as dead, there hasn&#039;t been a release of jQuery UI since 2016.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bootstrap ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:89--&amp;gt;&lt;br /&gt;
Joomla! 4.0 ships with Bootstrap 5. Bootstrap 2.3.2 has been removed, however we have left some BS2 classes in to ease the migration (e.g. The old BS2 element-invisible still exists for screenreaders)&amp;lt;/translate&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== FOF ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:157--&amp;gt; FOF 2.x has been removed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Templates == &amp;lt;!--T:90--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:91--&amp;gt;&lt;br /&gt;
All the Joomla! 3 templates - ISIS and Hathor in the Backend (Administrator), and Protostar and Beez in the Frontend (Site) are no longer supported. The new 4.0 Backend template is called Atum and the Frontend template is Cassiopeia.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:158--&amp;gt; As a consequence, all extensions must migrate to the new Bootstrap 5 style, away from the current Bootstrap 2.3.2 implementation. For more information about Bootstrap, visit the [https://getbootstrap.com/docs/5.0/getting-started/introduction/ Bootstrap 5] Website and the [https://getbootstrap.com/2.3.2/ Bootstrap 2.3.2] Website.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:258--&amp;gt; Joomla 4 will load the template favicon first rather than the one in the Joomla Root in keeping with the concept the template is the single source of truth.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:259--&amp;gt; Frontend components and module views now use Block Element Modifier (BEM) class markup to make it easier for templates to support frameworks other than bootstrap. See the [http://getbem.com/ BEM Website] for more information on how to build similar classes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:260--&amp;gt; There where also changes to options of the core components that you should take a look at when your tempalte should support 3.x and 4.x at the same time: https://docs.joomla.org/J4.x:Changed_parameters_for_template_providers&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Other == &amp;lt;!--T:95--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:261--&amp;gt; The &#039;&#039;$_PROFILER&#039;&#039; global variable has been removed. Use &#039;&#039;/Joomla/CMS/Profiler/Profiler::getInstance&#039;&#039; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Media in Libraries === &amp;lt;!--T:159--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:160--&amp;gt; No media is allowed in the libraries root folder in the CMS. All assets associated with Joomla libraries should be put in the media folder per best practices. Direct access is blocked with a &#039;&#039;.htaccess&#039;&#039; and the &#039;&#039;web.config&#039;&#039; file in the root of the libraries directory.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Bin === &amp;lt;!--T:96--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:97--&amp;gt;&lt;br /&gt;
Removing the keychain with 4.0 has resulted in the removal of the entire Bin directory as it only contained keychain.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Components === &amp;lt;!--T:200--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:201--&amp;gt; All components have been namespaced and directories reworked accordingly. For more information about this read the tutorial on building a component in Joomla 4.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:202--&amp;gt; com_admin profile view has been removed. (This appears to have been created historically due to issues accessing com_users. This is no longer the case so all user edits go through com_users edit user view in the backend.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:203--&amp;gt; com_actionlogs PHP 5.5 backfill code has been removed and accordingly &amp;lt;source inline lang=&amp;quot;php&amp;quot;&amp;gt;ActionlogsHelper::getCsvData()&amp;lt;/source&amp;gt; is now type hinted to return a &amp;lt;source inline lang=&amp;quot;php&amp;quot;&amp;gt;Generator&amp;lt;/source&amp;gt; object&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:262--&amp;gt; com_actionlogs CSV export headers have been changed to match the strings shown in the UI.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:204--&amp;gt; Core components have had URL Routing &#039;Legacy&#039; mode removed from Joomla 3.7. You should either use your .htaccess file or the redirect component to fix any internal URLs that change. You can try the &#039;Modern&#039; mode in Joomla 3 by following the instructions [[S:MyLanguage/J3.x:New_Routing_System|here]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:263--&amp;gt; The MailTo component has been removed without replacement. If you used this functionality you will need to find an alternative component on JED.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:264--&amp;gt; In com_contact &#039;s frontend contact view - the contact property has been removed as it was a duplicate of the item property. We chose to keep $this-&amp;gt;item as it was consistent with that in the article and tag views. Template overrides will need updating to reflect this.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:265--&amp;gt; The repeatable field in com_fields has been removed in favour of the new subform field. Data from repeatable fields is automatically migrated to the new subform field but is stored in a different format.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:266--&amp;gt; The xreference fields have been removed from &#039;&#039;#__contact_details&#039;&#039;, &#039;&#039;#__content&#039;&#039; and &#039;&#039;#__newsfeeds&#039;&#039; as they were unused.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Plugins === &amp;lt;!--T:161--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:162--&amp;gt; The Gmail authentication plugin has been removed. For more information please read [https://developer.joomla.org/news/724-removal-of-the-gmail-authentication-plugin-as-of-joomla-4-0.html this blog post].&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:163--&amp;gt; Google reCAPTCHA v1 support has been fully removed from the CAPTCHA plugin. This hasn&#039;t worked since Q2 2018. Google dropped support for it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:164--&amp;gt; The reCAPTCHA plugin now uses Google&#039;s official PHP library for CAPTCHA under the hood&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:168--&amp;gt; For plugins using the 3.x compatibility layer, the name result is a protected property for both input parameters and return values. For information on the new recommended approach to plugins please read [[S:MyLanguage/J4.x:Creating_a_Plugin_for_Joomla]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:267--&amp;gt; For plugins using the 3.x compatibility layer, for any type hints for events that require a class, that class &#039;&#039;&#039;must&#039;&#039;&#039; be autoloaded before the plugin is instantiated.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:190--&amp;gt; The onContentBeforeSave event now requires the data parameter. This has been passed in \Joomla\CMS\MVC\Model\LegacyModel since 3.7 but is now passed in consistently by core extensions and used by the core Joomla content plugin.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:268--&amp;gt; Returning before calling &amp;lt;source lang=&amp;quot;php&amp;quot; inline&amp;gt;parent::__construct()&amp;lt;/source&amp;gt; in the constructor of a plugin is no longer supported to avoid queuing the plugin into the event dispatcher.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:269--&amp;gt; &#039;&#039;onUserBeforeDataValidation&#039;&#039; is deprecated as an event in favor of &#039;&#039;onContentBeforeValidateData&#039;&#039; (The event was usable by all content types and was not specific to users. Note that both events will be called for the duration of Joomla 4. You should migrate your code to the new event when you no longer need to support Joomla 3.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Plugins (Events) === &amp;lt;!--T:279--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt; &lt;br /&gt;
* &amp;lt;translate&amp;gt; &amp;lt;!--T:280--&amp;gt; In Joomla 4, events whose name does not start with &amp;quot;on&amp;quot; no longer work. They don&#039;t even produce an error, so it&#039;s hard to figure out why they don&#039;t work. This means that you need to overwrite both the names of functions in plugins and the names of their calls. For more information please read [https://github.com/joomla/joomla-cms/issues/36062]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Administrator Helpers === &amp;lt;!--T:169--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:170--&amp;gt; JAdministratorHelper has been removed without replacement. (It&#039;s been merged into JApplicationAdministrator.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:171--&amp;gt; JSubMenuHelper has been removed without replacement. (Use JHtmlSidebar instead - available since 3.0.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:172--&amp;gt; JToolbarHelper has been moved to the main libraries directory.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Modules === &amp;lt;!--T:173--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:174--&amp;gt; The administrator module &#039;&#039;submenu&#039;&#039; has been removed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:270--&amp;gt; Logic of &#039;&#039;Module Chromes&#039;&#039; (module styles) in template files &amp;lt;code&amp;gt;html/modules.php&amp;lt;/code&amp;gt; have been moved to &amp;lt;code&amp;gt;JLayout&amp;lt;/code&amp;gt; files. &amp;lt;code&amp;gt;modChrome_x&amp;lt;/code&amp;gt; functions in &amp;lt;code&amp;gt;modules.php&amp;lt;/code&amp;gt; are no longer supported. See https://github.com/joomla/joomla-cms/pull/23570 for details.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:271--&amp;gt; &#039;&#039;Module Chromes&#039;&#039; (module styles) &amp;lt;code&amp;gt;modChrome_horz&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;modChrome_xhtml&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;modChrome_rounded&amp;lt;/code&amp;gt; have been removed from template &amp;lt;code&amp;gt;system&amp;lt;/code&amp;gt; without replacement.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:272--&amp;gt; Module Class Suffixes have been renamed and standardized. These are now called Module Class and are appended to the list of classes in the Module Chrome. (They are no longer rendered in the module output itself.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Error Handling === &amp;lt;!--T:165--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:166--&amp;gt; Joomla will now handle PHP&#039;s E_USER_DEPRECATED errors and pipes them into JLog - this is useful for handling deprecations in many third party PHP Libraries. (Note it will block the page load if debug mode is enabled.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:175--&amp;gt; Joomla\CMS\Exception\ExceptionHandler now only operates on Exceptions thrown in JApplication::execute. We now use Symfony&#039;s ErrorHandler when this fails or exceptions are thrown outside of this. We expect this to have minimal effect on most users and should give a more helpful message in many cases than the traditional &amp;quot;Error displaying the error page&amp;quot; error for users when things go very wrong.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:176--&amp;gt; Joomla\CMS\Exception\ExceptionHandler is now format-aware and will render errors in HTML, JSON, XML, feed- or cli-aware formats&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &amp;lt;translate&amp;gt;&amp;lt;!--T:177--&amp;gt; The Joomla\CMS\Exception\ExceptionHandler::render() signature is changed to include the Throwable typehint. Before 3.5 when PHP 7 support was added this was typehinted as Exception, and since 3.5 has been typechecked in the code itself.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Base Tag ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:273--&amp;gt; Previous Joomla versions set a &#039;&#039;&amp;lt;base&amp;gt;&#039;&#039; header tag of the current URL in the Frontend. This has been removed as it served no clear purpose.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== JavaScript ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:274--&amp;gt; The &#039;&#039;caption.js&#039;&#039; file has been removed from Joomla. Use the native HTML elements &#039;&#039;figure&#039;&#039; and &#039;&#039;figcaption&#039;&#039;. (You can look at JLayout in &#039;&#039;layouts/joomla/content/intro_image.php&#039;&#039; for an example).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:281--&amp;gt; saveOrderAjax does not send complete form data (like it did in Joomla 3), only cid and order variable. This may be insufficient because some extensions need more data for proper sorting - see: https://github.com/joomla/joomla-cms/issues/36346&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Namespacing ===&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:275--&amp;gt; Class usage like &#039;&#039;$msg = JText::_( &#039;Hello man!&#039; );&#039;&#039; can now use namespacing. That would turn into &#039;&#039;$msg = Text::_( &#039;Hello man!&#039; );&#039;&#039;. To use namespacing, you need to add the proper namespace declaration. This should be added after the &#039;&#039;defined(&#039;_JEXEC&#039;) or die;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:276--&amp;gt;&lt;br /&gt;
To find out the proper namespace you can either follow the instructions here: [https://groups.google.com/forum/#!topic/joomla-dev-general/1ua9zIqlcVc SO confused about namespace &amp;amp; enquemessage...] or use the generated file PDF reference file:&lt;br /&gt;
[https://docs.joomla.org/images/9/9c/J%21_namespace_reference.pdf namespace reference.pdf]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Namespace Mapping and Manifest File Name ==== &amp;lt;!--T:290--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:282--&amp;gt; Automatic namespace mapping won&#039;t work with extension manifest files named &amp;lt;code&amp;gt;manifest.xml&amp;lt;/code&amp;gt;. See: https://github.com/joomla/joomla-cms/issues/37750&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Compatibility{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Platform{{#translation:}}]]&lt;br /&gt;
[[Category:Migration{{#translation:}}]]&lt;br /&gt;
[[Category:Update Working Group{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.0{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_to_use_user_state_variables&amp;diff=1001237</id>
		<title>How to use user state variables</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_to_use_user_state_variables&amp;diff=1001237"/>
		<updated>2023-05-10T22:21:17Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags. Corrected some URLs.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Joomla! provides built in functionality to make it easy for Joomla! developers to store and retrieve variables that are stored with the session.&lt;br /&gt;
&lt;br /&gt;
==Why Should I Use the Joomla! User State Variables?==&lt;br /&gt;
Joomla!&#039;s built in session handling capabilities make it easy to retain values of certain variables across page accesses. This makes development much simpler because the developer no longer has to worry about losing variable values if it is left out of a form. Storing variables with sessions also makes the application cleaner and tidier since it reduces the amount of form variables, and persistent variables no longer have to be passed in either the query string (making very long URLs) or in POST variables.&lt;br /&gt;
&lt;br /&gt;
The downside of using session variables is that it makes page URLs stateful. That is, if used improperly, a URL might point to certain information in one context, but different information in another context. This can make search engines less effective since the web crawler might pull up a certain page using a certain URL, that when the user links to the URL from the search engine, might pull up a different page, resulting in user confusion and frustration.&lt;br /&gt;
&lt;br /&gt;
==Setting and Retrieving User State Variables==&lt;br /&gt;
There are two ways to set user state variables. The first is fairly intuitive, and is done using the [https://api.joomla.org/cms-2.5/classes/JApplication.html#method_setUserState JApplication::setUserState] method. The second is a little less obvious, and uses the [https://api.joomla.org/cms-2.5/classes/JApplication.html#method_getUserStateFromRequest JApplication::getUserStateFromRequest] method. There are also two ways to retrieve user state variables. The first is using the [https://api.joomla.org/cms-2.5/classes/JApplication.html#method_getUserState JApplication::getUserState] method, and the second is to use the [https://api.joomla.org/cms-2.5/classes/JApplication.html#method_getUserStateFromRequest JApplication::getUserStateFromRequest] method. [https://api.joomla.org/cms-2.5/classes/JApplication.html#method_getUserStateFromRequest JApplication::getUserStateFromRequest] can be used to both store and retrieve user state variables.&lt;br /&gt;
&lt;br /&gt;
The following methods are used for accessing the user state variables:&lt;br /&gt;
&lt;br /&gt;
===Method 1: JApplication::setUserState===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$mainframe =JFactory::getApplication();&lt;br /&gt;
&lt;br /&gt;
// store the variable that we would like to keep for next time&lt;br /&gt;
// function syntax is setUserState( $key, $value );&lt;br /&gt;
$mainframe-&amp;gt;setUserState( &amp;quot;$option.state_variable&amp;quot;, &amp;quot;state1&amp;quot; );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first parameter is the key under which to store the variable. You will note that in this example the key began with the $option variable. Although the value for $key is arbitrary, it is good practice to use this as a prefix for all user state variables since these are all in the same name space. Using an extension-specific prefix avoids extensions interfering with each other. In the example above, state_variable is the name of the state variable that will be stored, and the second parameter is the value to store with the state variable.&lt;br /&gt;
&lt;br /&gt;
===Method 2: JApplication::getUserStateFromRequest===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$mainframe =JFactory::getApplication();&lt;br /&gt;
&lt;br /&gt;
// retrieve the value of the state variable. First see if the variable has been passed&lt;br /&gt;
// in the request. Otherwise retrieve the stored value. If none of these are specified,&lt;br /&gt;
// the specified default value will be returned&lt;br /&gt;
// function syntax is getUserStateFromRequest( $key, $request, $default );&lt;br /&gt;
$stateVar = $mainframe-&amp;gt;getUserStateFromRequest( &amp;quot;$option.state_variable&amp;quot;, &#039;state_variable&#039;, &#039;state1&#039; );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first parameter is the key under which to store the variable. Note again that this is prefixed with the name of the current extension. This method will update the user state variable by looking in the variables that were passed with the request (in either GET or POST) and updating the user state variable if the specified request variable is set. This can be used to set user state variables with values that are passed from forms (i.e. from the user). If an existing value can be found either in the request or in the stored state variable, this is returned. Otherwise, the specified default value is returned (if it is specified), or NULL is returned if no value can be found.&lt;br /&gt;
&lt;br /&gt;
===Method 3: JApplication::getUserState===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$mainframe =JFactory::getApplication();&lt;br /&gt;
&lt;br /&gt;
// retrieve the value of the state variable. If no value is specified,&lt;br /&gt;
// the specified default value will be returned.&lt;br /&gt;
// function syntax is getUserState( $key, $default );&lt;br /&gt;
$stateVar = $mainframe-&amp;gt;getUserState( &amp;quot;$option.state_variable&amp;quot;, &#039;state1&#039; );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first parameter is the key under which to store the variable. Note again that this is prefixed with the name of the current extension. This method will retrieve the value of the specified user state variable. If this user state variable has not been set, then the value is read from the $default parameter. If the user state variable has not been set and $default is not specified, the method will return NULL.&lt;br /&gt;
&lt;br /&gt;
==A Real Life Example of the Use of Joomla! User State Variables==&lt;br /&gt;
The following code excerpts are taken from the admin section of the Newsfeed component, which is a core Joomla! component. These snippets are meant to demonstrate how user state variable can be used in an actual application.&lt;br /&gt;
&lt;br /&gt;
===Purpose===&lt;br /&gt;
Notice that many components that have database tables associated with them present to the user a list of items. In the case of the Newsfeed component, the administration section presents a list of Newsfeeds. If there are too many newsfeeds to list on one page, two variables are used to keep track of where the user is in the list: the limit variable and the limitstart variable. The Newsfeed component (like other components) uses state variables to store the value of limit and limitstart between page requests.&lt;br /&gt;
&lt;br /&gt;
If a user goes to administer another component or navigates away from the component, these values are available when the user returns. In addition, these values only have to be passed if they are being changed. The developer does not have to bother with inserting hidden form feeds to pass these values along.&lt;br /&gt;
&lt;br /&gt;
===Setting and Retrieving the Variables===&lt;br /&gt;
The following code is used to set and retrieve the values of these variables:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$mainframe =JFactory::getApplication();&lt;br /&gt;
&lt;br /&gt;
$limit = $mainframe-&amp;gt;getUserStateFromRequest( &amp;quot;limit&amp;quot;, &#039;limit&#039;, $mainframe-&amp;gt;getCfg(&#039;list_limit&#039;) );&lt;br /&gt;
$limitstart = $mainframe-&amp;gt;getUserStateFromRequest( &amp;quot;$option.limitstart&amp;quot;, &#039;limitstart&#039;, 0 );&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first variable that is stored is the limit variable. The limit variable specifies how many records should be retrieved from the database and displayed. Note that there is no &#039;&#039;&#039;$option&#039;&#039;&#039; prefix in the &#039;&#039;&#039;$key&#039;&#039;&#039; parameter. This variable is used as a global parameter (and its initial value is retrieved from the site configuration value). The value is retrieved from the request variable called &#039;limit&#039;. If the state variable has not been specified yet and it is not specified in the request, then the value is retrieved from the site configuration using the [[JApplication/getCfg|JApplication::getCfg]] method.&lt;br /&gt;
&lt;br /&gt;
The second variable that is stored is the limitstart variable. This specifies how many records to skip over before returning records from the database. Each component has its own list and so keeps its own place in its own list. The &#039;&#039;&#039;$option&#039;&#039;&#039; parameter in this case has the value &#039;com_newsfeeds&#039;, and so the session variable name is &#039;com_newsfeeds.limitstart&#039;.&lt;br /&gt;
&lt;br /&gt;
===Passing Values to JPagination class===&lt;br /&gt;
In this example, the stored values are used as parameters for constructing the pagination class, which helps the developer implement pagination functionality.&lt;br /&gt;
&lt;br /&gt;
Ultimately, this will result in the following form elements being displayed on the page:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html4strict&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;limit&amp;quot;&amp;gt;Display #&lt;br /&gt;
&amp;lt;select name=&amp;quot;limit&amp;quot; id=&amp;quot;limit&amp;quot; class=&amp;quot;inputbox&amp;quot; size=&amp;quot;1&amp;quot; onchange=&amp;quot;document.adminForm.submit();&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;5&amp;quot;  selected=&amp;quot;selected&amp;quot;&amp;gt;5&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;10&amp;quot; &amp;gt;10&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;15&amp;quot; &amp;gt;15&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;20&amp;quot; &amp;gt;20&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;25&amp;quot; &amp;gt;25&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;30&amp;quot; &amp;gt;30&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;50&amp;quot; &amp;gt;50&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;option value=&amp;quot;100&amp;quot; &amp;gt;100&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;start&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Start&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;button2-right off&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;prev&amp;quot;&amp;gt;&amp;lt;span&amp;gt;Prev&amp;lt;/span&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&amp;lt;div class=&amp;quot;button2-left&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;page&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;span&amp;gt;1&amp;lt;/span&amp;gt;&lt;br /&gt;
&amp;lt;a title=&amp;quot;2&amp;quot; onclick=&amp;quot;javascript: document.adminForm.limitstart.value=5; document.adminForm.submit();return false;&amp;quot;&amp;gt;2&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;button2-left&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;next&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a title=&amp;quot;Next&amp;quot; onclick=&amp;quot;javascript: document.adminForm.limitstart.value=5; document.adminForm.submit();return false;&amp;quot;&amp;gt;Next&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;button2-left&amp;quot;&amp;gt;&amp;lt;div class=&amp;quot;end&amp;quot;&amp;gt;&amp;lt;a title=&amp;quot;End&amp;quot; onclick=&amp;quot;javascript: document.adminForm.limitstart.value=5; document.adminForm.submit();return false;&amp;quot;&amp;gt;End&amp;lt;/a&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;limit&amp;quot;&amp;gt;&lt;br /&gt;
Results 1 - 5 of 10&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;input type=&amp;quot;hidden&amp;quot; name=&amp;quot;limitstart&amp;quot; value=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
One may be observant and notice that the values are passed in hidden form elements anyway, and claim therefore that it is really not necessary to use state variables. But this will not help in the situation where the user has navigated away from the component, and it will also not help in the situation which occurs in the list, for example, where each newsfeed is listed and linked using a standard link, and not the form. Using state variables saves having to add limit and limitstart on to the end of these URLs.&lt;br /&gt;
&lt;br /&gt;
==See Also==&lt;br /&gt;
For information on the Joomla! API relating to session variables, please consult the following sources:&lt;br /&gt;
* [https://api.joomla.org/cms-2.5/classes/JApplication.html JApplication]&lt;br /&gt;
* [https://api.joomla.org/cms-2.5/classes/JSession.html JSession]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:Development]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Selecting_data_using_JDatabase&amp;diff=1001236</id>
		<title>J4.x:Selecting data using JDatabase</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Selecting_data_using_JDatabase&amp;diff=1001236"/>
		<updated>2023-05-10T21:16:25Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Replaced deprecated &amp;#039;source&amp;#039; tags with &amp;#039;syntaxhighlight&amp;#039; tags.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Joomla version|version=4.x}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
{{tip|&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
Note that many examples online do not use the prepared statements methods that have been introduced with Joomla 4.x. Please do not use these old APIs for new projects. They result in massive security issues if user input is not strictly escaped.&amp;lt;/translate&amp;gt;|title=&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
Version Note&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
This tutorial is split into two independent parts:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
* Inserting, updating and removing data from the database.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
* Selecting data from one or more tables and retrieving it in a variety of different forms&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
This section of the documentation looks at selecting data from a database table and retrieving it in a variety of formats. To see the other part [[S:MyLanguage/J4.x:Inserting_Updating_and_Removing_data_using_JDatabase|click here]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Introduction== &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
Joomla provides a sophisticated database abstraction layer to simplify the usage for third party developers. New versions of the Joomla Platform API provide additional functionality which extends the database layer further, and includes features such as connectors to a greater variety of database servers and the query chaining to improve readability of connection code and simplify SQL coding.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
Joomla can use different kinds of SQL database systems and 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 you need just two 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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==The Query== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Since Joomla introduced support for a variety of database types in Joomla 1.6 - the recommended way of building database queries is through &amp;quot;query chaining&amp;quot; (although string queries will always be supported).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Query chaining refers to a method of connecting a number of methods, one after the other, with each method returning an object that can support the next method, improving readability and simplifying code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
To obtain a new instance of the \Joomla\Database\DatabaseQuery class we use the \Joomla\Database\DatabaseDriver getQuery method:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
&lt;br /&gt;
$db = Factory::getDbo();&lt;br /&gt;
&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
The \Joomla\Database\DatabaseDriver::getQuery takes an optional argument, $new, which can be true or false (the default being false).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
To query our data source we can call a number of \Joomla\Database\DatabaseQuery methods; these methods encapsulate the data source&#039;s query language (in most cases SQL), hiding query-specific syntax from the developer and increasing the portability of the developer&#039;s source code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
Some of the more frequently used methods include; select, from, join, where and order. There are also methods such as insert, update and delete for modifying records in the data store. By chaining these and other method calls, you can create almost any query against your data store without compromising portability of your code&amp;lt;/translate&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Selecting Records from a Single Table== &amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
Below is an example of creating a database query using the &amp;lt;tt&amp;gt;\Joomla\Database\DatabaseQuery&amp;lt;/tt&amp;gt; class. Using the select, from, where and order methods, we can create queries which are flexible, easily readable and portable:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
&lt;br /&gt;
// Get a db connection.&lt;br /&gt;
$db = Factory::getDbo();&lt;br /&gt;
&lt;br /&gt;
// Create a new query object.&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
// Select all records from the user profile table where key begins with &amp;quot;custom.&amp;quot;.&lt;br /&gt;
// Order it by the ordering field.&lt;br /&gt;
$query-&amp;gt;select($db-&amp;gt;quoteName([&#039;user_id&#039;, &#039;profile_key&#039;, &#039;profile_value&#039;, &#039;ordering&#039;]));&lt;br /&gt;
$query-&amp;gt;from($db-&amp;gt;quoteName(&#039;#__user_profiles&#039;));&lt;br /&gt;
$query-&amp;gt;where($db-&amp;gt;quoteName(&#039;profile_key&#039;) . &#039; LIKE :profile_key&#039;);&lt;br /&gt;
$query-&amp;gt;order($db-&amp;gt;quoteName(&#039;ordering&#039;) . &#039; ASC&#039;);&lt;br /&gt;
&lt;br /&gt;
// bind value for prepared statements&lt;br /&gt;
$query-&amp;gt;bind(&#039;:profile_key&#039;, &#039;custom.%&#039;);&lt;br /&gt;
&lt;br /&gt;
// Reset the query using our newly populated query object.&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&lt;br /&gt;
// Load the results as a list of stdClass objects (see later for more options on retrieving data).&lt;br /&gt;
$results = $db-&amp;gt;loadObjectList();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
The query can also be chained to simplify further:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select($db-&amp;gt;quoteName([&#039;user_id&#039;, &#039;profile_key&#039;, &#039;profile_value&#039;, &#039;ordering&#039;]))&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__user_profiles&#039;))&lt;br /&gt;
    -&amp;gt;where($db-&amp;gt;quoteName(&#039;profile_key&#039;) . &#039; LIKE :profile_key&#039;)&lt;br /&gt;
    -&amp;gt;order($db-&amp;gt;quoteName(&#039;ordering&#039;) . &#039; ASC&#039;)&lt;br /&gt;
    -&amp;gt;bind(&#039;:profile_key&#039;, &#039;custom.%&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
Chaining can become useful when queries become longer and more complex.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
Grouping can be achieved simply too. The following query would count the number of articles in each category.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select( [&#039;catid&#039;, &#039;COUNT(*)&#039;] )&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__content&#039;))&lt;br /&gt;
    -&amp;gt;group($db-&amp;gt;quoteName(&#039;catid&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
A limit can be set to a query using &amp;quot;setLimit&amp;quot;. For example in the following query, it would return up to 10 records.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select($db-&amp;gt;quoteName([&#039;user_id&#039;, &#039;profile_key&#039;, &#039;profile_value&#039;, &#039;ordering&#039;]))&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__user_profiles&#039;))&lt;br /&gt;
    -&amp;gt;setLimit(&#039;10&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Selecting Records from Multiple Tables== &amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
Using the \Joomla\Database\DatabaseQuery&#039;s [https://api.joomla.org/framework-1/classes/Joomla.Database.DatabaseQuery.html#join join] methods, we can select records from multiple related tables. The generic &amp;quot;join&amp;quot; method takes two arguments: the join &amp;quot;type&amp;quot; (inner, outer, left, right) and the join condition. In the following example you will notice that we can use all of the keywords we would normally use if we were writing a native SQL query, including the AS keyword for aliasing tables and the ON keyword for creating relationships between tables. Also note that the table alias is used in all methods which reference table columns (I.e. select, where, order).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
&lt;br /&gt;
// Get a db connection.&lt;br /&gt;
$db = Factory::getDbo();&lt;br /&gt;
&lt;br /&gt;
// Create a new query object.&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
&lt;br /&gt;
// Select all articles for users who have a username which starts with &#039;a&#039;.&lt;br /&gt;
// Order it by the created date.&lt;br /&gt;
// Note by putting &#039;a&#039; as a second parameter will generate `#__content` AS `a`&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select([&#039;a.*&#039;, &#039;b.username&#039;, &#039;b.name&#039;])&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__content&#039;, &#039;a&#039;))&lt;br /&gt;
    -&amp;gt;join(&#039;INNER&#039;, $db-&amp;gt;quoteName(&#039;#__users&#039;, &#039;b&#039;) . &#039; ON (&#039; . $db-&amp;gt;quoteName(&#039;a.created_by&#039;) . &#039; = &#039; . $db-&amp;gt;quoteName(&#039;b.id&#039;) . &#039;)&#039;)&lt;br /&gt;
    -&amp;gt;where($db-&amp;gt;quoteName(&#039;b.username&#039;) . &#039; LIKE :username&#039;)&lt;br /&gt;
    -&amp;gt;order($db-&amp;gt;quoteName(&#039;a.created&#039;) . &#039; DESC&#039;)&lt;br /&gt;
    -&amp;gt;bind(&#039;:username&#039;, &#039;a%&#039;);&lt;br /&gt;
&lt;br /&gt;
// Reset the query using our newly populated query object.&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
&lt;br /&gt;
// Load the results as a list of stdClass objects (see later for more options on retrieving data).&lt;br /&gt;
$results = $db-&amp;gt;loadObjectList();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
The join method above enables us to query both the content and user tables, retrieving articles with their author details. There are also convenience methods for joins:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* [https://api.joomla.org/framework-1/classes/Joomla.Database.DatabaseQuery.html#method_innerJoin innerJoin()]&lt;br /&gt;
* [https://api.joomla.org/framework-1/classes/Joomla.Database.DatabaseQuery.html#method_leftJoin leftJoin()]&lt;br /&gt;
* [https://api.joomla.org/framework-1/classes/Joomla.Database.DatabaseQuery.html#method_rightJoin rightJoin()]&lt;br /&gt;
* [https://api.joomla.org/framework-1/classes/Joomla.Database.DatabaseQuery.html#method_outerJoin outerJoin()]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
We can use multiple joins to query across more than two tables:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select(array(&#039;a.*&#039;, &#039;b.username&#039;, &#039;b.name&#039;, &#039;c.*&#039;, &#039;d.*&#039;))&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__content&#039;, &#039;a&#039;))&lt;br /&gt;
    -&amp;gt;join(&#039;INNER&#039;, $db-&amp;gt;quoteName(&#039;#__users&#039;, &#039;b&#039;) . &#039; ON (&#039; . $db-&amp;gt;quoteName(&#039;a.created_by&#039;) . &#039; = &#039; . $db-&amp;gt;quoteName(&#039;b.id&#039;) . &#039;)&#039;)&lt;br /&gt;
    -&amp;gt;join(&#039;LEFT&#039;, $db-&amp;gt;quoteName(&#039;#__user_profiles&#039;, &#039;c&#039;) . &#039; ON (&#039; . $db-&amp;gt;quoteName(&#039;b.id&#039;) . &#039; = &#039; . $db-&amp;gt;quoteName(&#039;c.user_id&#039;) . &#039;)&#039;)&lt;br /&gt;
    -&amp;gt;join(&#039;RIGHT&#039;, $db-&amp;gt;quoteName(&#039;#__categories&#039;, &#039;d&#039;) . &#039; ON (&#039; . $db-&amp;gt;quoteName(&#039;a.catid&#039;) . &#039; = &#039; . $db-&amp;gt;quoteName(&#039;d.id&#039;) . &#039;)&#039;)&lt;br /&gt;
    -&amp;gt;where($db-&amp;gt;quoteName(&#039;b.username&#039;) . &#039; LIKE :username&#039;)&lt;br /&gt;
    -&amp;gt;order($db-&amp;gt;quoteName(&#039;a.created&#039;) . &#039; DESC&#039;)&lt;br /&gt;
    -&amp;gt;bind(&#039;:username&#039;, &#039;a%&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
Notice how chaining makes the source code more readable for these longer queries.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
In some cases, you will also need to use the AS clause when selecting items to avoid column name conflicts. In this case, multiple select statements can be chained in conjunction with using the second parameter of $db-&amp;gt;quoteName.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select(&#039;a.*&#039;)&lt;br /&gt;
    -&amp;gt;select($db-&amp;gt;quoteName(&#039;b.username&#039;, &#039;username&#039;))&lt;br /&gt;
    -&amp;gt;select($db-&amp;gt;quoteName(&#039;b.name&#039;, &#039;name&#039;))&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__content&#039;, &#039;a&#039;))&lt;br /&gt;
    -&amp;gt;join(&#039;INNER&#039;, $db-&amp;gt;quoteName(&#039;#__users&#039;, &#039;b&#039;), $db-&amp;gt;quoteName(&#039;a.created_by&#039;) . &#039; = &#039; . $db-&amp;gt;quoteName(&#039;b.id&#039;))&lt;br /&gt;
    -&amp;gt;where($db-&amp;gt;quoteName(&#039;b.username&#039;) . &#039; LIKE :username&#039;)&lt;br /&gt;
    -&amp;gt;order($db-&amp;gt;quoteName(&#039;a.created&#039;) . &#039; DESC&#039;)&lt;br /&gt;
    -&amp;gt;bind(&#039;:username&#039;, &#039;a%&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
A second array can also be used as the second parameter of the select statement to populate the values of the AS clause. Remember to include nulls in the second array to correspond to columns in the first array that you don&#039;t want to use the AS clause for:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query&lt;br /&gt;
    -&amp;gt;select([&#039;a.*&#039;])&lt;br /&gt;
    -&amp;gt;select($db-&amp;gt;quoteName(array(&#039;b.username&#039;, &#039;b.name&#039;), [&#039;username&#039;, &#039;name&#039;]))&lt;br /&gt;
    -&amp;gt;from($db-&amp;gt;quoteName(&#039;#__content&#039;, &#039;a&#039;))&lt;br /&gt;
    -&amp;gt;join(&#039;INNER&#039;, $db-&amp;gt;quoteName(&#039;#__users&#039;, &#039;b&#039;) . &#039; ON (&#039; . $db-&amp;gt;quoteName(&#039;a.created_by&#039;) . &#039; = &#039; . $db-&amp;gt;quoteName(&#039;b.id&#039;) . &#039;)&#039;)&lt;br /&gt;
    -&amp;gt;where($db-&amp;gt;quoteName(&#039;b.username&#039;) . &#039; LIKE :username&#039;)&lt;br /&gt;
    -&amp;gt;order($db-&amp;gt;quoteName(&#039;a.created&#039;) . &#039; DESC&#039;)&lt;br /&gt;
    -&amp;gt;bind(&#039;:username&#039;, &#039;a%&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Using Prepared Statements== &amp;lt;!--T:140--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:141--&amp;gt;&lt;br /&gt;
With Joomla! 4.0 we have [[J4.x:Moving_Joomla_To_Prepared_Statements|moved all queries to use prepared statements]]. For easier use of prepared statements we introduced some helper functions and allow to use arrays in several function calls.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:142--&amp;gt;&lt;br /&gt;
Simple query with prepared statements.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = $this-&amp;gt;db-&amp;gt;getQuery(true)&lt;br /&gt;
	-&amp;gt;select($this-&amp;gt;db-&amp;gt;quoteName(array(&#039;id&#039;, &#039;password&#039;)))&lt;br /&gt;
	-&amp;gt;from($this-&amp;gt;db-&amp;gt;quoteName(&#039;#__users&#039;))&lt;br /&gt;
	-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;username&#039;) . &#039; = :username&#039;)&lt;br /&gt;
	-&amp;gt;bind(&#039;:username&#039;, $credentials[&#039;username&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:143--&amp;gt;&lt;br /&gt;
You see that we don&#039;t add the &#039;&#039;&#039;$credentials[&#039;username&#039;]&#039;&#039;&#039; directly to the query, instead we add the placeholder &#039;&#039;&#039;:username&#039;&#039;&#039; into the query and &#039;&#039;&#039;bind&#039;&#039;&#039; the variable to the query. When we bind a variable to a query we don&#039;t need to escape nor to quote it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:144--&amp;gt;&lt;br /&gt;
Beware that binding a variable will always be a reference. A nice side effect of this, is that you can manipulate the query in a loop.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
$listOfUsernames = [ &#039;admin&#039;, &#039;user1&#039; ];&lt;br /&gt;
&lt;br /&gt;
$query = $this-&amp;gt;db-&amp;gt;getQuery(true)&lt;br /&gt;
	-&amp;gt;select($this-&amp;gt;db-&amp;gt;quoteName(array(&#039;id&#039;, &#039;password&#039;)))&lt;br /&gt;
	-&amp;gt;from($this-&amp;gt;db-&amp;gt;quoteName(&#039;#__users&#039;))&lt;br /&gt;
	-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;username&#039;) . &#039; = :username&#039;)&lt;br /&gt;
	-&amp;gt;bind(&#039;:username&#039;, $username);&lt;br /&gt;
&lt;br /&gt;
foreach($listOfUsernames as $name)&lt;br /&gt;
{&lt;br /&gt;
  $username = $name;&lt;br /&gt;
  $this-&amp;gt;db-&amp;gt;setQuery($query);&lt;br /&gt;
  $user = $this-&amp;gt;db-&amp;gt;loadObject();&lt;br /&gt;
  print_r($user);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:145--&amp;gt;&lt;br /&gt;
In the loop we set the previously bound $username variable with the $name variable from the loop, then we have to set the query again (because Joomla resets the database driver after query execution which is only true for load* functions).&lt;br /&gt;
The result will be multiple queries with different username values.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:146--&amp;gt;&lt;br /&gt;
We can use arrays to add multiple variables at once.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = $this-&amp;gt;db-&amp;gt;getQuery(true)&lt;br /&gt;
	-&amp;gt;select($this-&amp;gt;db-&amp;gt;quoteName(array(&#039;id&#039;, &#039;password&#039;)))&lt;br /&gt;
	-&amp;gt;from($this-&amp;gt;db-&amp;gt;quoteName(&#039;#__users&#039;))&lt;br /&gt;
	-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;username&#039;) . &#039; = :username&#039;)&lt;br /&gt;
	-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;id&#039;) . &#039; = :id&#039;)&lt;br /&gt;
	-&amp;gt;bind([&#039;:username&#039;, &#039;:id&#039;], [$credentials[&#039;username&#039;], 42], [Joomla\Database\ParameterType::STRING, Joomla\Database\ParameterType::INTEGER]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:147--&amp;gt;&lt;br /&gt;
We add &#039;&#039;&#039;username&#039;&#039;&#039; and &#039;&#039;&#039;id&#039;&#039;&#039; as bind parameter and set the correct ParameterType for each variable.&lt;br /&gt;
It&#039;s also possible to use one variable for all bind values and ParameterTypes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$query = $this-&amp;gt;db-&amp;gt;getQuery(true)&lt;br /&gt;
	-&amp;gt;select($this-&amp;gt;db-&amp;gt;quoteName(array(&#039;id&#039;, &#039;password&#039;)))&lt;br /&gt;
	-&amp;gt;from($this-&amp;gt;db-&amp;gt;quoteName(&#039;#__users&#039;))&lt;br /&gt;
	-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;username&#039;) . &#039; = :username&#039;)&lt;br /&gt;
	-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;password&#039;) . &#039; = :password&#039;)&lt;br /&gt;
	-&amp;gt;bind([&#039;:username&#039;, &#039;:password], $credentials[&#039;username&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:148--&amp;gt;&lt;br /&gt;
The parameter :username and :password get set to the same value and the default ParameterType.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:149--&amp;gt;&lt;br /&gt;
The function &#039;&#039;&#039;whereIn()&#039;&#039;&#039; and &#039;&#039;&#039;whereNotIn()&#039;&#039;&#039; always use prepared statements, internal these functions uses the &#039;&#039;&#039;bindArray&#039;&#039;&#039; function. It can be used to bind an array of variables without specifying the placeholder.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$userids = [1,2,3,4];&lt;br /&gt;
&lt;br /&gt;
$query = $this-&amp;gt;db-&amp;gt;getQuery(true)&lt;br /&gt;
	-&amp;gt;select($this-&amp;gt;db-&amp;gt;quoteName(array(&#039;id&#039;, &#039;password&#039;)))&lt;br /&gt;
	-&amp;gt;from($this-&amp;gt;db-&amp;gt;quoteName(&#039;#__users&#039;));&lt;br /&gt;
&lt;br /&gt;
$parameterNames = $query-&amp;gt;bindArray($userids);&lt;br /&gt;
&lt;br /&gt;
$query-&amp;gt;where($this-&amp;gt;db-&amp;gt;quoteName(&#039;id&#039;) . &#039; IN (&#039; . implode(&#039;,&#039;, $parameterNames) . &#039;)&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &#039;&#039;&#039;bindArray&#039;&#039;&#039; function returns an array of placeholders. The index is unique for the whole query.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$placeholders = [&lt;br /&gt;
  &#039;:preparedArray1&#039;,&lt;br /&gt;
  &#039;:preparedArray2&#039;,&lt;br /&gt;
  &#039;:preparedArray3&#039;,&lt;br /&gt;
  &#039;:preparedArray4&#039;&lt;br /&gt;
];&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Query Results == &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
The database class contains many methods for working with a query&#039;s result set.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Single Value Result === &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadResult() ==== &amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Use &#039;&#039;&#039;loadResult()&#039;&#039;&#039; when you expect just a single value back from your database query.&amp;lt;/translate&amp;gt;&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;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
id&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
name&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
email&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
username&amp;lt;/translate&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || &amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
johnsmith@domain.example&amp;lt;/translate&amp;gt; || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || &amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt;&lt;br /&gt;
magda_h@domain.example&amp;lt;/translate&amp;gt; || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || &amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
ydg@domain.example&amp;lt;/translate&amp;gt; || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
This is often the result of a &#039;count&#039; query to get the number of records:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
$db = Factory::getDbo();&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
$query-&amp;gt;select(&#039;COUNT(*)&#039;);&lt;br /&gt;
$query-&amp;gt;from($db-&amp;gt;quoteName(&#039;#__my_table&#039;));&lt;br /&gt;
$query-&amp;gt;where($db-&amp;gt;quoteName(&#039;name&#039;).&amp;quot; = :value&amp;quot;);&lt;br /&gt;
$query-&amp;gt;bind(&#039;value&#039;, $value)&lt;br /&gt;
&lt;br /&gt;
// Reset the query using our newly populated query object.&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$count = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:134--&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).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
use Joomla\CMS\Factory;&lt;br /&gt;
$db = Factory::getDbo();&lt;br /&gt;
$query = $db-&amp;gt;getQuery(true);&lt;br /&gt;
$query-&amp;gt;select(&#039;field_name&#039;);&lt;br /&gt;
$query-&amp;gt;from($db-&amp;gt;quoteName(&#039;#__my_table&#039;));&lt;br /&gt;
$query-&amp;gt;where($db-&amp;gt;quoteName(&#039;some_name&#039;).&amp;quot; = :value&amp;quot;);&lt;br /&gt;
$query-&amp;gt;bind(&#039;:value&#039;, $some_value);&lt;br /&gt;
&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$result = $db-&amp;gt;loadResult();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Single Row Results === &amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;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.&amp;lt;/translate&amp;gt;&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;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt;&lt;br /&gt;
id&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
name&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt;&lt;br /&gt;
email&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
username&amp;lt;/translate&amp;gt;&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || &amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt;&lt;br /&gt;
johnsmith@domain.example&amp;lt;/translate&amp;gt; || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Magda Hellman || &amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
magda_h@domain.example&amp;lt;/translate&amp;gt; || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Yvonne de Gaulle || &amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt;&lt;br /&gt;
ydg@domain.example&amp;lt;/translate&amp;gt; || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadRow() ==== &amp;lt;!--T:52--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadRow()&amp;lt;/tt&amp;gt; returns an indexed array from a single record in the table:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:133--&amp;gt;&lt;br /&gt;
will give:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; 1, [1] =&amp;gt; John Smith, [2] =&amp;gt; johnsmith@domain.example, [3] =&amp;gt; johnsmith ) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt;&lt;br /&gt;
You can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
Notes:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt;&lt;br /&gt;
# The array indices are numeric starting from zero.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt;&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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadAssoc() ==== &amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadAssoc()&amp;lt;/tt&amp;gt; returns an associated array from a single record in the table:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&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@domain.example, [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt;&lt;br /&gt;
You can access the individual values by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$row[&#039;name&#039;] // e.g. $row[&#039;email&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:62--&amp;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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadObject() ==== &amp;lt;!--T:63--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt;&lt;br /&gt;
loadObject returns a PHP object from a single record in the table:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&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@domain.example, [username] =&amp;gt; johnsmith )&amp;lt;/pre&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
You can access the individual values by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$result-&amp;gt;index // e.g. $result-&amp;gt;email&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:67--&amp;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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Single Column Results === &amp;lt;!--T:68--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
Each of these results functions will return a single column from the database.&amp;lt;/translate&amp;gt;&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;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt;&lt;br /&gt;
id&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:71--&amp;gt;&lt;br /&gt;
name&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:72--&amp;gt;&lt;br /&gt;
email&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:73--&amp;gt;&lt;br /&gt;
username&amp;lt;/translate&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
| 1 || style=&amp;quot;background:yellow&amp;quot; | John Smith || &amp;lt;translate&amp;gt;&amp;lt;!--T:74--&amp;gt;&lt;br /&gt;
johnsmith@domain.example&amp;lt;/translate&amp;gt; || johnsmith&lt;br /&gt;
|-&lt;br /&gt;
| 2 || style=&amp;quot;background:yellow&amp;quot; | Magda Hellman || &amp;lt;translate&amp;gt;&amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
magda_h@domain.example&amp;lt;/translate&amp;gt; || magdah&lt;br /&gt;
|-&lt;br /&gt;
| 3 || style=&amp;quot;background:yellow&amp;quot; | Yvonne de Gaulle || &amp;lt;translate&amp;gt;&amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
ydg@domain.example&amp;lt;/translate&amp;gt; || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadColumn() ==== &amp;lt;!--T:77--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:78--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadColumn()&amp;lt;/tt&amp;gt; returns an indexed array from a single column in the table:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query-&amp;gt;select(&#039;name&#039;));&lt;br /&gt;
      -&amp;gt;from . . .&amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadColumn();&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
will give:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:80--&amp;gt;&lt;br /&gt;
You can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:81--&amp;gt;&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&lt;br /&gt;
# &amp;lt;tt&amp;gt;loadColumn()&amp;lt;/tt&amp;gt; is equivalent to loadColumn(0).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadColumn($index) ==== &amp;lt;!--T:82--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:83--&amp;gt;&lt;br /&gt;
loadColumn($index) returns an indexed array from a single column in the table:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
$query-&amp;gt;select(array(&#039;name&#039;, &#039;email&#039;, &#039;username&#039;));&lt;br /&gt;
      -&amp;gt;from . . .&amp;quot;;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$column= $db-&amp;gt;loadColumn(1);&lt;br /&gt;
print_r($column);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:84--&amp;gt;&lt;br /&gt;
will give:&lt;br /&gt;
&amp;lt;pre&amp;gt;Array ( [0] =&amp;gt; johnsmith@domain.example, [1] =&amp;gt; magda_h@domain.example, [2] =&amp;gt; ydg@domain.example )&amp;lt;/pre&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:85--&amp;gt;&lt;br /&gt;
You can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:86--&amp;gt;&lt;br /&gt;
loadColumn($index) allows you to iterate through a series of columns in the results:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;loadColumn($i);&lt;br /&gt;
  print_r($column);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:87--&amp;gt;&lt;br /&gt;
will give:&amp;lt;/translate&amp;gt;&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@domain.example, [1] =&amp;gt; magda_h@domain.example, [2] =&amp;gt; ydg@domain.example ),&lt;br /&gt;
Array ( [0] =&amp;gt; johnsmith, [1] =&amp;gt; magdah, [2] =&amp;gt; ydegaulle )&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:88--&amp;gt;&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Multi-Row Results === &amp;lt;!--T:89--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:90--&amp;gt;&lt;br /&gt;
Each of these results functions will return multiple records from the database.&amp;lt;/translate&amp;gt;&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;
! &amp;lt;translate&amp;gt;&amp;lt;!--T:91--&amp;gt;&lt;br /&gt;
id&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:92--&amp;gt;&lt;br /&gt;
name&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:93--&amp;gt;&lt;br /&gt;
email&amp;lt;/translate&amp;gt; !! &amp;lt;translate&amp;gt;&amp;lt;!--T:94--&amp;gt;&lt;br /&gt;
username&amp;lt;/translate&amp;gt;&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 1 || John Smith || johnsmith@domain.example || johnsmith&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 2 || Magda Hellman || magda_h@domain.example || magdah&lt;br /&gt;
|- style=&amp;quot;background:yellow&amp;quot;&lt;br /&gt;
| 3 || Yvonne de Gaulle || ydg@domain.example || ydegaulle&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== loadRowList() ==== &amp;lt;!--T:95--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:96--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadRowList()&amp;lt;/tt&amp;gt; returns an indexed array of indexed arrays from the table records returned by the query:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:97--&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&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@domain.example, [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@domain.example, [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@domain.example, [3] =&amp;gt; ydegaulle )&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:98--&amp;gt;&lt;br /&gt;
You can access the individual rows by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:99--&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:100--&amp;gt;&lt;br /&gt;
Notes:&lt;br /&gt;
# The array indices are numeric starting from zero.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;==== loadAssocList() ==== &amp;lt;!--T:101--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:102--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadAssocList()&amp;lt;/tt&amp;gt; returns an indexed array of associated arrays from the table records returned by the query:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:103--&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&amp;lt;/translate&amp;gt;&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@domain.example, [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@domain.example, [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@domain.example, [username] =&amp;gt; ydegaulle )&lt;br /&gt;
) &amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:104--&amp;gt;&lt;br /&gt;
You can access the individual rows by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:105--&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;==== loadAssocList($key) ==== &amp;lt;!--T:106--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:107--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadAssocList(&#039;key&#039;)&amp;lt;/tt&amp;gt; returns an associated array - indexed on &#039;key&#039; - of associated arrays from the table records returned by the query:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:108--&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&amp;lt;/translate&amp;gt;&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@domain.example, [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@domain.example, [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@domain.example, [username] =&amp;gt; ydegaulle )&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:109--&amp;gt;&lt;br /&gt;
You can access the individual rows by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:110--&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:111--&amp;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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;==== loadAssocList($key, $column) ==== &amp;lt;!--T:112--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:113--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadAssocList(&#039;key&#039;, &#039;column&#039;)&amp;lt;/tt&amp;gt; returns an associative array, indexed on &#039;key&#039;, of values from the column named &#039;column&#039; returned by the query:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;id&#039;, &#039;username&#039;);&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Array (&lt;br /&gt;
[1] =&amp;gt; John Smith,&lt;br /&gt;
[2] =&amp;gt; Magda Hellman,&lt;br /&gt;
[3] =&amp;gt; Yvonne de Gaulle,&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:115--&amp;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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;==== loadObjectList() ==== &amp;lt;!--T:116--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadObjectList()&amp;lt;/tt&amp;gt; returns an indexed array of PHP objects from the table records returned by the query:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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();&lt;br /&gt;
print_r($row);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:118--&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&amp;lt;/translate&amp;gt;&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@domain.example, [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@domain.example, [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@domain.example, [username] =&amp;gt; ydegaulle )&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt;&lt;br /&gt;
You can access the individual rows by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$row[&#039;index&#039;] // e.g. $row[&#039;2&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:120--&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;==== loadObjectList($key) ==== &amp;lt;!--T:121--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:122--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;loadObjectList(&#039;key&#039;)&amp;lt;/tt&amp;gt; returns an associated array - indexed on &#039;key&#039; - of objects from the table records returned by the query:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:123--&amp;gt;&lt;br /&gt;
will give (with line breaks added for clarity):&amp;lt;/translate&amp;gt;&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@domain.example, [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@domain.example, [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@domain.example, [username] =&amp;gt; ydegaulle )&lt;br /&gt;
)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:124--&amp;gt;&lt;br /&gt;
You can access the individual rows by using:&amp;lt;/translate&amp;gt;&amp;lt;pre&amp;gt;$row[&#039;key_value&#039;] // e.g. $row[&#039;johnsmith&#039;]&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:125--&amp;gt;&lt;br /&gt;
and you can access the individual values by using:&amp;lt;/translate&amp;gt;&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;
&amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;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.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Miscellaneous Result Set Methods === &amp;lt;!--T:127--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== getNumRows() ==== &amp;lt;!--T:128--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:129--&amp;gt;&lt;br /&gt;
&amp;lt;tt&amp;gt;getNumRows()&amp;lt;/tt&amp;gt; will return the number of result rows found by the last SELECT or SHOW 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. To retrieve the number of rows affected by a INSERT, UPDATE, REPLACE or DELETE query, use getAffectedRows().&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&#039;php&#039;&amp;gt;&lt;br /&gt;
. . .&lt;br /&gt;
$db-&amp;gt;setQuery($query);&lt;br /&gt;
$db-&amp;gt;execute();&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;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt;&lt;br /&gt;
will return&amp;lt;/translate&amp;gt; &amp;lt;pre&amp;gt;3&amp;lt;/pre&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:131--&amp;gt;&lt;br /&gt;
Note: getNumRows() is only valid for statements like SELECT or SHOW that return an actual result set. If you run getNumRows() after loadRowList() - or any other retrieval method - you will get a PHP Warning:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Warning: mysql_num_rows(): 80 is not a valid MySQL result resource&lt;br /&gt;
in libraries\joomla\database\database\mysql.php on line 344&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== See Also === &amp;lt;!--T:135--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
*[[S:MyLanguage/J4.x:Inserting, Updating and Removing data using JDatabase|&amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt; Inserting, Updating and Removing data using JDatabase&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
*[[S:MyLanguage/J4.x:Moving_Joomla_To_Prepared_Statements|&amp;lt;translate&amp;gt;&amp;lt;!--T:151--&amp;gt; Moving Joomla To Prepared Statements&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
*[[S:MyLanguage/Using the union methods in database queries|&amp;lt;translate&amp;gt;&amp;lt;!--T:137--&amp;gt; Using the union methods in database queries&amp;lt;/translate&amp;gt;]] &amp;lt;translate&amp;gt;&amp;lt;!--T:138--&amp;gt; (Joomla! 3.3+)&amp;lt;/translate&amp;gt;&lt;br /&gt;
*[https://php.net/manual/en/pdo.prepared-statements.php &amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt; The PHP Manual on Prepared statements&amp;lt;/translate&amp;gt;]&lt;br /&gt;
*[https://api.joomla.org/framework-1/classes/Joomla.Database.DatabaseQuery.html &amp;lt;translate&amp;gt;&amp;lt;!--T:139--&amp;gt; Joomla Framework API&amp;lt;/translate&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Database{{#translation:}}]]&lt;br /&gt;
[[Category:JFactory{{#translation:}}]]&lt;br /&gt;
[[Category:Extension development{{#translation:}}]]&lt;br /&gt;
[[Category:Development Recommended Reading{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_to_debug_your_code&amp;diff=1001234</id>
		<title>How to debug your code</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_to_debug_your_code&amp;diff=1001234"/>
		<updated>2023-05-09T21:11:36Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Corrected some markup, phrasing and syntax highlighting.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==The Easy Way 1 (&#039;&#039;echo&#039;&#039;)== &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; The simplest way to see what is going on inside your code is to temporarily add &#039;&#039;echo&#039;&#039; statements for variables to show their values on the screen. For example, say you want to know what the value of some variables are when $i is &amp;quot;5&amp;quot;. You could use code like this:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;for ( $i = 0; $i &amp;lt; 10; $i++ ) {&lt;br /&gt;
	if ( $i == 5 ) {&lt;br /&gt;
		echo &#039;$i=&#039; . $i;&lt;br /&gt;
                // other echo statements&lt;br /&gt;
	}&lt;br /&gt;
}&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt; This works for simple situations. However, if you are planning on doing a lot of Joomla! development, it is worth the effort to install and learn an integrated development environment (IDE) that includes a real PHP debugger.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==The Easy Way 2 (Joomla &#039;&#039;message&#039;&#039;)== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; Your code won&#039;t always display simple echo statements. In that case you can try this alternative, still an easy way:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;JFactory::getApplication()-&amp;gt;enqueueMessage(&#039;Some debug string(s)&#039;);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; You can choose different [[Display_error_messages_and_notices|message types]] which correspond to grouping with different styles (colors mainly).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Joomla Logging== &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; Joomla allows you to log messages to a log file, and optionally also display these on the web page (in the same way as &#039;&#039;enqueueMessage&#039;&#039; above) and on the Joomla Debug Console (described below).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt; To log a message in the log file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
JLog::add(&#039;my error message&#039;, JLog::ERROR);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; To log a message and also display it on the screen:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
JLog::add(&#039;my error message&#039;, JLog::ERROR, &#039;jerror&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; The logging to the log file and to the Debug Console is controlled via the settings of the System – Debug plugin. To understand how this works, and the relevant settings of the System-Debug plugin, read the Joomla documentation page on [[S:MyLanguage/Using JLog|Using JLog]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Using an IDE== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt; Check this 3 minutes video that shows&amp;lt;/translate&amp;gt; [http://www.youtube.com/watch?v=sP4dHAuq2kc&amp;amp;feature=youtu.be &amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; how you can debug your code with a browser and an IDE&amp;lt;/translate&amp;gt;]&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|sP4dHAuq2kc}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; Many Joomla! developers use the Eclipse IDE. This is free and includes a debugger. Instructions for installing it are available at [[S:Mylanguage/Setting up your workstation for Joomla! development|Setting up your workstation for Joomla! development]], or you can watch this video on setting up Eclipse and Xdebug:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{#widget:YouTube|id=MiIEF8-XAkc}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Using the PHP Expert Editor== &amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt; Another option is the PHP Expert editor with an installed extension for debugging. Add the following lines to the &#039;&#039;php.ini&#039;&#039; file:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 extension=php_dbg.dll&lt;br /&gt;
 [Debugger]&lt;br /&gt;
 debugger.enabled=on&lt;br /&gt;
 debugger.profiler_enabled=off&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt; It is best to set &#039;&#039;profiler_enable&#039;&#039; to &#039;&#039;off&#039;&#039;. Then you need to set options in the Run/Options menu to use HTTP-server and the directory in which your script is located.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
If all options are correct, you may run your script in debug mode by clicking on the Debug button (F8).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==J!Dump== &amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; An often handy extension that can be found in the JED is the J!Dump extension that will allow you to dump variable, stack traces, and system information into a popup window at run time. This extension works like the PHP command &#039;&#039;var_dump&#039;&#039; but formats the output in a more readable fashion.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Joomla Debug Console== &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt; The Debug Console can be enabled from the Joomla! Global Configuration, System tab, by setting the Debug System option to Yes. Once enabled, the output of the debug plugin will be displayed at the bottom of each page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[File:Jdebug-module-&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg|&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; The JDebug Plugin output&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:25--&amp;gt; Setting this Debug System option also sets the global variable &#039;&#039;JDEBUG&#039;&#039; to true, so that you can control whether to log messages by testing this variable:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;PHP&amp;quot;&amp;gt;&lt;br /&gt;
if(JDEBUG)&lt;br /&gt;
{&lt;br /&gt;
    // whatever debugging code you want to run, e.g.&lt;br /&gt;
    JLog::add(&#039;my debug message&#039;, JLog::DEBUG, &#039;my-debug-category&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
This plugin provides information that can assist in debugging and improving the performance of your component.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Session Information=== &amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; This section displays state variables which are stored in the Session data to enable them to be &#039;remembered&#039; across HTTP requests. Examples include variables defining the current search filters the user has defined, the pagination point in a list of records, etc.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:session-&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Profile Information=== &amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt; The Profile Information tab from the debug plugin provides information about the time and memory taken to render the page based on each of the application events. This can help to identify areas outside of network speed that are contributing to long page load times and high server memory usage.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Jdebug-profile-&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg|&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt; JDEBUG Profile&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
===Database Queries=== &amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; One of the most useful tabs is the Database Queries tab. This will provide a log of all queries that have been executed while loading the page and identify both the time taken to execute the query and whether duplicate queries have occurred. This is particularly useful when debugging performance problems on larger components as duplicate queries are often a contributing factor.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Jdebug-query-&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; en&amp;lt;/translate&amp;gt;.jpg]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Komodo IDE== &amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[S:MyLanguage/Debugging Joomla with Komodo IDE|Debugging Joomla with Komodo IDE]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Video{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=WebAuthn_Passwordless_Login&amp;diff=1001218</id>
		<title>WebAuthn Passwordless Login</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=WebAuthn_Passwordless_Login&amp;diff=1001218"/>
		<updated>2023-05-05T22:59:36Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Phrasing, capitalization, punctuation and markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;noinclude&amp;gt;{{Joomla version|version=4.x}}&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== System - WebAuthn Passwordless Login == &amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; Web Authentication, or WebAuthn for short, allows a user to securely log into a site without using a password — though you still need to provide your username. It uses strong cryptography and in a manner which is extremely resistant to the most common problems of passwords: someone guessed it (brute force attack), someone intercepted it (man in the middle attack), someone tricked you into divulging it (phishing attack), someone cracked it after getting hold of a copy of your database data (SQL injection attacks) or someone stole it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; WebAuthn is not just secure; it is also user friendly! You no longer have to remember long passwords or use a password manager. All you need is an &#039;&#039;authenticator&#039;&#039;, sometimes also called a &#039;&#039;passkey&#039;&#039;. An authenticator can have many forms, physical or virtual. It can be a separate hardware key connecting to your device via USB, Bluetooth or NFC. It can be your device itself, unlocking its built-in authenticator with a PIN, fingerprint reader, facial scan or similar biometric check. This feature already works on Android and iOS/iPadOS devices and we&#039;re working on enabling it on Windows as well. It can even be your phone — currently this is possible with Android phones but this feature is also coming to iOS/iPadOS devices.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; WebAuthn only works over HTTPS and only when your site is using a valid, trusted certificate for it. Don&#039;t worry, you don&#039;t have to spend any extra money; free of charge services such as Let&#039;s Encrypt are typically integrated into web hosting control panels and work perfectly fine with WebAuthn.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; WebAuthn uses public key cryptography, the same proven technology that keeps your sites safe with HTTPS, your banking information secure and so on. The private key never leaves the authenticator. Your site only stores a public key. Even if you suffer a data breach the attacker will be left with a practically useless public key; it would take them thousands to millions of CPU years to crack it as opposed to a few minutes or hours required to crack the hash of a fixed password that you can remember.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt; WebAuthn is the future of authentication. Easy, secure and hassle-free. Everything that fixed passwords are not.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; The following picture shows a hardware device inserted into a laptop computer&#039;s USB port. It cost £15 in February, 2022.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:j4x-passwordless-login-hardware-device.jpg|center|Hardware device]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; WebAuthn uses a system plugin that is enabled by default. A &#039;&#039;Web Authentication&#039;&#039; button will be present in default Joomla 4 login screens, as illustrated in the Administrator login screen:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:j4x-passwordless-login-admin-login.png|center|border|Administrator Login]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== User Configuration == &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The user must first register with a normal Username and Password. After logging in, go to the User Profile form. For an Administrator:&lt;br /&gt;
* Select {{rarr|User Menu, Edit Account, W3C Web Authentication (WebAuthn) Login}} to bring up the form, initially with no authenticators registered.&lt;br /&gt;
* Select &#039;&#039;&#039;Add New Authenticator&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
The exact presentation of the next step depends on your browser. Typically, you will see an alert, message or window asking you to select an authenticator type or, if you&#039;re using a hardware authenticator attached to your device, reminding you to press the button on the hardware authenticator. For security and practical reasons there is a relatively short time interval allowed for activating the authenticator: 60 seconds.&lt;br /&gt;
&lt;br /&gt;
[[File:j4x-passwordless-login-hardware-propmpt.png|center|Hardware Prompt]]&lt;br /&gt;
&lt;br /&gt;
Once you unlock your authenticator — tapping on a button, scanning your fingerprint/face, entering a PIN or a combination of the above depending on your authenticator — the message disappears, the authenticator is registered and the screen appears as follows:&lt;br /&gt;
&lt;br /&gt;
[[File:j4x-passwordless-login-registered-authenticator.png|center|Registered Authenticator]]&lt;br /&gt;
&lt;br /&gt;
It is important to note that you can only register or remove authenticators on your own user account. For security reasons, even a Super User is disallowed from registering, editing or adding authenticators on other user accounts.&lt;br /&gt;
&lt;br /&gt;
=== Authenticators ===&lt;br /&gt;
You can use any FIDO U2F or FIDO2 authenticator. FIDO U2F is an older standard which supports a more limited, less secure selection of cryptographic methods. FIDO2 is the newer standard which supports much more secure cryptographic methods including Elliptic Curve Cryptography, a cryptographic method which is believed to be resistant even to quantum computing (if and when it becomes a practical reality). Moreover, FIDO2 authenticators can be set up to have additional protections such as a PIN or a biometric control (e.g. fingerprint scan) which means that even if you lose physical possession of the authenticator itself whoever finds it cannot log into your sites.&lt;br /&gt;
&lt;br /&gt;
If you are looking to buy a hardware authenticator you can look for &amp;quot;FIDO2&amp;quot; in your favorite marketplace, such as Amazon. There is a wide selection to choose from.&lt;br /&gt;
&lt;br /&gt;
You may also use a software FIDO key such as Krypton as your authenticator.&lt;br /&gt;
&lt;br /&gt;
Many devices have built-in FIDO2-compliant authentication:&lt;br /&gt;
&lt;br /&gt;
* Windows 10 and 11 have Windows Hello with a PIN, fingerprint scanner, facial recognition camera or a combination of hardware key and PIN. Support for Windows Hello is being added to the plugin with a release target of Joomla 4.2.0.&lt;br /&gt;
* macOS has TouchID on all laptops with the T2 chipset or those based on Apple Silicon using the built-in TouchID sensor, as well as all Apple Silicon–based desktops using the new Apple Aluminium keyboard with a fingerprint scanner.&lt;br /&gt;
* iOS/iPadOS has TouchID on all devices with a fingerprint scanner and FaceID on all newer devices with a FaceID infrared dot projection camera.&lt;br /&gt;
* Some Android devices have a fingerprint scanner or a face recognition camera. These can also work as FIDO2 authenticators, on Android 9 or later using Google Chrome at least.&lt;br /&gt;
* Other devices may be available too. For example, Android phones using [https://groups.google.com/a/fidoalliance.org/g/fido-dev/c/go6GoFW27Dw/m/9flCLR5pBQAJ?pli=1 caBLE]&lt;br /&gt;
&lt;br /&gt;
=== WebAuthn Compatible Browsers ===&lt;br /&gt;
Chromium and Firefox based browsers have supported WebAuthn since early 2019.&lt;br /&gt;
&lt;br /&gt;
Safari and all iOS/iPadOS browsers (which are, in fact, Safari with a different skin) fully support WebAuthn since iOS/iPadOS 13 released late 2019.&lt;br /&gt;
&lt;br /&gt;
Practically speaking, if your operating system and browser were released after mid-2020 you should have no problem. Only some uncommon browsers still lack support for WebAuthn.&lt;br /&gt;
&lt;br /&gt;
== Authentication ==&lt;br /&gt;
To login you must enter your username in the login form Username field. You do not need to enter your password but if your browser enters it for you just leave it. The password is &#039;&#039;&#039;not&#039;&#039;&#039; sent to the server when the form is submitted via the Web Authentication button.&lt;br /&gt;
&lt;br /&gt;
It follows that you can login with either your Username and Password or Username and Web Authentication.&lt;br /&gt;
&lt;br /&gt;
== How To Disable the Plugin ==&lt;br /&gt;
If you do not wish to allow WebAuthn, just go to the list of plugins and find &#039;&#039;System - WebAuthn Passwordless Login&#039;&#039; in the System group and disable it. There are no parameters to set.&lt;br /&gt;
&lt;br /&gt;
== Server Requirements ==&lt;br /&gt;
For WebAuthn to work the following preconditions must be met:&lt;br /&gt;
&lt;br /&gt;
* HTTPS with a valid, signed certificate. Most hosts let you use free of charge certificates issues by Let&#039;s Encrypt. These work perfectly fine with WebAuthn.&lt;br /&gt;
* The OpenSSL extension for PHP must be installed and enabled.&lt;br /&gt;
* The PHP extension GMP or the PHP extension BCmath must be installed and enabled (either will do).&lt;br /&gt;
* The Sodium library should ideally be enabled; it enables the use of Elliptic Curve Cryptography on compatible FIDO2 authenticators which, as we said, is the most secure cryptographic method.&lt;br /&gt;
&lt;br /&gt;
== Frequently Asked Questions and Troubleshooting ==&lt;br /&gt;
=== I can&#039;t see the “Web Authentication” login button ===&lt;br /&gt;
You are not accessing your site under HTTPS. WebAuthn is only available for HTTPS sites with a valid certificate. This is a security precaution baked into the WebAuthn standard. The plugin actually checks if the site is accessed through HTTPS using Joomla&#039;s Uri class. In rare cases where the server lies about the protocol you might not see the button even though your site (claims to be) HTTPS. The same applies if you have edited your &#039;&#039;configuration.php&#039;&#039; file and set up the optional &#039;&#039;$live_site&#039;&#039; configuration parameter with an &#039;&#039;http://&#039;&#039; protocol prefix instead of &#039;&#039;https://&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Also note that third party login modules and components implementing their own login form may not display these buttons just yet. We added new infrastructure to support them, much like what we had to do in Joomla! 3.2 to support Two Factor Authentication.&lt;br /&gt;
&lt;br /&gt;
=== I still need to provide a username. Isn&#039;t WebAuthn supposed to get rid of usernames? ===&lt;br /&gt;
Not really, no. The current specification of WebAuthn does not provide identity management. Web browsers require us to send them a list of acceptable WebAuthn public keys during the login phase. This means that we need your username to fetch them.&lt;br /&gt;
&lt;br /&gt;
That said, using WebAuthn finally makes it clear that usernames &#039;&#039;&#039;are not to be considered secrets&#039;&#039;&#039;. They are considered public information which can be freely transmitted to an adversary, just like the public keys stored in the site&#039;s database. The only secret is stored in the authenticator itself and never leaves the authenticator!&lt;br /&gt;
&lt;br /&gt;
=== I have registered an authenticator but trying to log in tells me that I haven&#039;t. Is this a bug? ===&lt;br /&gt;
It is a bug but not with the WebAuthn plugin itself.&lt;br /&gt;
&lt;br /&gt;
One or more plugins on your site throw PHP Notices, Warnings or Errors, thus corrupting the reply sent back by your server. As a result the JavaScript on the page cannot parse the server response and is unsure whether any authenticators are registered by the user.&lt;br /&gt;
&lt;br /&gt;
Go to your site&#039;s {{rarr|Backend,System,Global Configuration}} and set &#039;&#039;Error Reporting&#039;&#039; to &#039;&#039;None&#039;&#039;. In most cases of misbehaving core and 3PD plugins this is enough. Otherwise please examine the output of the request using your browser&#039;s developer tools to see what is corrupting the request.&lt;br /&gt;
&lt;br /&gt;
=== There is no prompt on Safari to use my authenticator ===&lt;br /&gt;
This should no longer be happening with iOS 13, iPadOS 13 and macOS Catalina or any later version.&lt;br /&gt;
&lt;br /&gt;
This is a Safari bug in older versions of Safari. Older versions of Safari only included support for WebAuthn as an experimental feature and not quite finished.&lt;br /&gt;
&lt;br /&gt;
=== I cannot use a biometric sensor (TouchID, fingerprint, Windows Hello) ===&lt;br /&gt;
Some older Chromium-based browsers (except Google Chrome proper) didn&#039;t have full support for built-in authenticators. They would crash or hang when you tried using one. These issues were fixed in these browsers around mid-2020.&lt;br /&gt;
&lt;br /&gt;
If you are using Windows please remember that your device MUST have a Trusted Platform Module (TPM) chip and it must be enabled in the BIOS. Just having a Windows Hello-compatible biometric sensor won&#039;t do the trick. This is a security precaution in the WebAuthn standard itself: the authenticator information must be processed using secure, tamper-resistant hardware to prevent key subversion (e.g. malware running on the computer cannot steal the key used for authentication).&lt;br /&gt;
&lt;br /&gt;
Finally, do keep in mind that Windows Hello support is still being worked on and will be released with Joomla 4.2.&lt;br /&gt;
&lt;br /&gt;
=== If I can use a software authenticator why should I bother with a hardware token? ===&lt;br /&gt;
The linchpin of WebAuthn is the absolute secrecy of the private key. It is only known to the authenticator and it should be impossible to communicate to the outside world.&lt;br /&gt;
&lt;br /&gt;
In the case of a hardware authenticator, be it a discrete hardware device or a TPM / Secure Enclave built into your device, this is a given by the very nature of that hardware.&lt;br /&gt;
&lt;br /&gt;
A software authenticator generates a secret key and stores it in the filesystem. However, it is still a regular software application which runs inside your regular operating system, be it your phone&#039;s or your computer&#039;s. As a result it is susceptible to several classes of attacks which can be used to surreptitiously steal information (security issues in the software itself, malware using Spectre-class vulnerabilities in modern CPUs etc).&lt;br /&gt;
&lt;br /&gt;
So, a software authenticator is far more convenient and secure than a regular password but a hardware authenticator offers the best security. Choose your authenticator based on your budget and security needs.&lt;br /&gt;
&lt;br /&gt;
Considering that the price of a FIDO key–-which is compatible with WebAuthn–-is under €10 on Amazon you can use a hardware authenticator in most practical use cases.&lt;br /&gt;
&lt;br /&gt;
=== Why are the credentials encrypted in the database? Isn&#039;t this an overkill? ===&lt;br /&gt;
The only thing stored in the database is the public key returned by the authenticator when we are performing the attestation ceremony (that&#039;s the formal name of registering an authenticator per the WebAuthn specification). Being a public key it does not need protecting from reading. Even if an unauthorised user was able to read this information they would not be able to impersonate the authenticator e.g. by cloning it.&lt;br /&gt;
&lt;br /&gt;
However, if a malicious user had write access just to the &#039;&#039;#__webauthn_credentials&#039;&#039; database table, without read access to the filesystem and without write access to any other table, they could conceivably &#039;&#039;&#039;add&#039;&#039;&#039; their own authenticator, therefore being able to impersonate the targeted user on the system. This is a theoretical attack since they would also need to know the user handle for the user they are attacking which is harder to derive without some inside knowledge of the site itself. Besides, having write access to just this table and not the entire database (in which case they could create a new Super User) is extremely unlikely. Still, we are encrypting the credentials to make it impossible for even this theoretical attack to succeed.&lt;br /&gt;
&lt;br /&gt;
We are fully aware that if a user has read access to the server filesystem they have access to the encryption key and the database connection information, all of which is stored in &#039;&#039;configuration.php&#039;&#039;. However, in this case you are already hacked: the attacker can read &#039;&#039;configuration.php&#039;&#039; therefore they know how to connect to your database. In this case they can do whatever they please to your site, including deleting all existing Super Users and creating their own Super User account. Therefore there&#039;s no reason to try to address this situation; you&#039;d be fully compromised (hacked). The only that could be a saving grace is regular, tested, off-site backups.&lt;br /&gt;
&lt;br /&gt;
=== I have set up Two Factor Authentication but I am logged in without providing my Secret Key. Isn&#039;t this insecure? ===&lt;br /&gt;
No, it&#039;s intentional and by design.&lt;br /&gt;
&lt;br /&gt;
When we added Two Factor Authentication (TFA) in Joomla! 3.2 you were only able to log into your site using a username and password. Passwords can be stolen or guessed. Therefore TFA was the only way to provide a modicum of security on high risk and high value targets. That was back in 2013.&lt;br /&gt;
&lt;br /&gt;
WebAuthn is an entirely different authentication solution which has none of the problem of fixed passwords. It uses strong cryptography and secure hardware to make it practically impossible to subvert the authentication cryptographic keys. It&#039;s also unphishable, i.e. you cannot be fooled into using it on an impersonating site since the WebAuthn credential is tied to the exact domain name for which it was issued. (Yes, if you use multiple domains for your site or transfer your site to another domain you&#039;ll need to re-register all your WebAuthn authenticators – you got that right!). As a result, authentication with WebAuthn is incredibly secure and supersedes the reasons that necessitated TFA. This means that if you successfully authenticate using WebAuthn the TFA secret key needs not be-–and is therefore not–-checked at all.&lt;br /&gt;
&lt;br /&gt;
In an ideal world, you would only be able to log into your site using WebAuthn. This is a feature we are working on and you may not want to enable; after all, if your domain name changes or you lose access to or reset all of your WebAuthn authenticators, you&#039;d be locked out of your site. Therefore you should still enable TFA on your user account on the basis that password login can still be used as a fallback to logging into your site and must be protected from known attacks against fixed passwords.&lt;br /&gt;
&lt;br /&gt;
=== Isn&#039;t TFA good enough? Why do we need WebAuthn? ===&lt;br /&gt;
TFA alone is good enough in most cases but suffers from two issues.&lt;br /&gt;
&lt;br /&gt;
First, it is awkward user experience. You need to provide your ever-changing secret key with your username and password. Most people use TOTP (the six digit PIN that changes every 30 seconds) that slows down logging in and frustrates users. Using a YubiKey is much faster but more expensive and complicated to provision when you have more than a couple of users on the site. A YubiKey also has an expected life of about two years of everyday use when generating One Time Passwords. (It runs out of the write-once memory it uses to keep track of the signatures it has issued.)&lt;br /&gt;
&lt;br /&gt;
Second, if you are using TOTP you still are susceptible to security issues such as keyloggers, phishing and the possibility that the secret key used for generating the TOTP is stolen. Moreover, with one million possibilities and thirty seconds to try them, it is conceivable that an attacker can get lucky since Joomla doesn&#039;t lock your account or otherwise employ rate limiting for failed login attempts. While these protections could be implemented, the implementation itself could be abused to create a denial of service situation which locks a legitimate user out of their site while the attacker is busy infiltrating it. It&#039;s a case of the cure being worse than the disease.&lt;br /&gt;
&lt;br /&gt;
WebAuthn greatly improves the user experience. Major browsers embraced WebAuthn and offer a compelling user experience, guiding the users into using authenticators successfully. Logging in with WebAuthn is more convenient even when compared to using a password manager&#039;s auto-fill feature. With recent versions of mobile operating systems even that experience, once slightly confusing, is rapidly becoming easier than passwords and TFA ever were.&lt;br /&gt;
&lt;br /&gt;
Where WebAuthn is truly killing it is at the security front. By virtue of using secure hardware and strong validation of the site&#039;s domain name it is practically immune to keyloggers, phishing and key subversion. It even has built-in protection against key cloning. Yes, you can still lose your hardware--but FIDO2 authenticators, be they external devices or built-in, can be locked out with a PIN or biometrics. Overall, using WebAuthn with FIDO2 authenticators is more theft- and loss-resistant than your house or car keys.&lt;br /&gt;
&lt;br /&gt;
== Developer Notes ==&lt;br /&gt;
=== Extra Login Buttons ===&lt;br /&gt;
The plugin module and &#039;&#039;com_users&#039;&#039; now use the &#039;&#039;onUserLoginButtons&#039;&#039; event, defined and called in Joomla\CMS\Helper\AuthenticationHelper::getLoginButtons, to retrieve the definitions of any additional buttons which need to be placed after the regular login button.&lt;br /&gt;
&lt;br /&gt;
All developers implementing a login module or, more generally, a login form should also use the Joomla\CMS\Helper\AuthenticationHelper::getLoginButtons public static method to retrieve said definitions and render these buttons to make their software fully compatible with Joomla 4.&lt;br /&gt;
&lt;br /&gt;
Developers wishing to implement custom buttons should look at how the WebAuthn system plugin implements this functionality. Such buttons can be used for implementing third party single-sign-on services or even logging in using third party identity services such as those offered by popular social media (Facebook, Google, Twitter, GitHub etc).&lt;br /&gt;
&lt;br /&gt;
This change does not adversely impact backwards compatibility. Third-party login modules and login forms will continue functioning normally even if they do not implement the extra login buttons feature with the notable omission of integration afforded by said feature such as Web Authentication itself. That is to say they won&#039;t stop functioning (which would be a b/c break) but they won&#039;t be feature-complete.&lt;br /&gt;
&lt;br /&gt;
=== Allowing &#039;&#039;com_ajax&#039;&#039; in the Backend Login Page ===&lt;br /&gt;
The Administrator login page whitelists &#039;&#039;com_ajax&#039;&#039; in AdministratorApplication so it can be used to handle requests by guest users.&lt;br /&gt;
&lt;br /&gt;
This change does not cause backwards compatibility issues as long as developers use sane practices and do not assume that being called by &#039;&#039;com_ajax&#039;&#039; in the Backend is proof that the user is logged into the Backend. That would be a bad security practice. The sane practice is to use Joomla&#039;s User object to detect if it&#039;s a guest user and, if not, whether the user is allowed a permission required to effect the action requested through &#039;&#039;com_ajax&#039;&#039;. That is to say, if this change has broken your code then your code was already broken and needed to be reworked anyway.&lt;br /&gt;
&lt;br /&gt;
== Further Information ==&lt;br /&gt;
&#039;&#039;The initial documentation of this feature is in the pull request at [https://github.com/joomla/joomla-cms/pull/28094 PR #28094].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Security{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! Wiki need pages]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Web_Assets&amp;diff=1001149</id>
		<title>J4.x:Web Assets</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Web_Assets&amp;diff=1001149"/>
		<updated>2023-05-02T23:51:48Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Phrasing, capitalization and markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Concept == &amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:115--&amp;gt; In the Frontend world many assets are related. For example, our &#039;&#039;keepalive&#039;&#039; script depends on the &#039;&#039;core.js&#039;&#039; file for options management. In Joomla there never was an easy way to specify this; you just had to include multiple files. Joomla 4 changes this with the concept of web assets.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Definition == &amp;lt;!--T:116--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt; Related assets are defined in a JSON file such as [https://github.com/joomla/joomla-cms/blob/7b72c565b610e02c1b01f8958d622879631fa6a2/build/media_source/system/joomla.asset.json#L14-L21 system/joomla.asset.json#L14-L21]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:118--&amp;gt; This has a structure of having a schema definition (for validation), name, version, license and then one or more asset definitions. Assets comprise a list of JavaScript files and CSS files related to the assets and any dependencies. The dependencies section is just a list of asset names that are required for the asset to function. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;Joomla CMS&amp;quot;,&lt;br /&gt;
  &amp;quot;license&amp;quot;: &amp;quot;GPL-2.0+&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.css&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;beer&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/beer.css&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;bar&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;beer&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;core&amp;quot;,&lt;br /&gt;
        &amp;quot;bar&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/beer.js&amp;quot;,&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;defer&amp;quot;: true,&lt;br /&gt;
        &amp;quot;data-foo&amp;quot;: &amp;quot;bar&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt; The &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; inline&amp;gt;$schema&amp;lt;/syntaxhighlight&amp;gt; attribute is a schema definition file that allows you to validate your file using JSON Schema. Read [https://json-schema.org/understanding-json-schema/index.html the official website] for more information on how JSON schema validation works.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:120--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Having &#039;&#039;joomla.asset.json&#039;&#039; for your extension or template are recommended but not required for WebAsset to work. (See the next section).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:121--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; It is not recommended to add an inline asset to a JSON file. Prefer to use a file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Explaining Asset Stages == &amp;lt;!--T:122--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:123--&amp;gt; Each asset has two stages: registered and used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:124--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Registered&#039;&#039;&#039; is where an asset is loaded into &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;. That means &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; knows about the existence of these assets, but will not attach them to a document while rendering. All assets loaded from joomla.asset.json is at &#039;&#039;&#039;registered&#039;&#039;&#039; stage.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:125--&amp;gt; &#039;&#039;&#039;Used&#039;&#039;&#039; is where an asset is enabled via &amp;quot;$wa-&amp;gt;useAsset()&amp;quot; (-&amp;gt;useScript(), -&amp;gt;useStyle(), -&amp;gt;registerAndUseX() etc). That means &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; will attach these assets and their dependencies to a document while rendering.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;gt; An asset cannot be used if it was not registered before. This will cause an unknown asset exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Register an Asset == &amp;lt;!--T:127--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:128--&amp;gt; All known assets loaded and then stored in &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;. (To enable/disable an asset item, use &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;. See the next section.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:129--&amp;gt; Joomla! will look for next assets definition automatically at runtime (in following order):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
media/vendor/joomla.asset.json (on first access to WebAssetRegistry)&lt;br /&gt;
media/system/joomla.asset.json&lt;br /&gt;
media/legacy/joomla.asset.json&lt;br /&gt;
media/{com_active_component}/joomla.asset.json (on dispatch the application)&lt;br /&gt;
templates/{active_template}/joomla.asset.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt; And load them to the registry of known assets.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:131--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Each following assets definition will override asset items from previous assets definition, by item name.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:132--&amp;gt; You can register your own assets definition via &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wr = $wa-&amp;gt;getRegistry();&lt;br /&gt;
$wr-&amp;gt;addRegistryFile(&#039;relative/path/to/your/joomla.asset.json&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:133--&amp;gt; To add a custom asset item at runtime:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wr-&amp;gt;add(&#039;script&#039;, new Joomla\CMS\WebAsset\WebAssetItem(&#039;foobar&#039;, &#039;com_foobar/file.js&#039;, [&#039;type&#039; =&amp;gt; &#039;script&#039;]));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:134--&amp;gt; Or more simply, using &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;foobar&#039;, &#039;com_foobar/file.js&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:135--&amp;gt; The new asset item &#039;&#039;foobar&#039;&#039; will be added to the registry of know assets, but will not be attached to a document until your code (a layout, template etc) will request it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt; To check whether an asset exists:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($wa-&amp;gt;assetExists(&#039;script&#039;, &#039;foobar&#039;))&lt;br /&gt;
{&lt;br /&gt;
    var_dump(&#039;Script &amp;quot;foobar&amp;quot; exists!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Enabling an Asset == &amp;lt;!--T:137--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:138--&amp;gt; All asset management in the current Document handled by &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;, which is accessible with &#039;&#039;&#039;$doc-&amp;gt;getWebAssetManager();&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:139--&amp;gt; By using AssetManager you can enable or disable needed asset easily in Joomla! through a standard methods.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:140--&amp;gt; To enable an asset in the page, use the useAsset function:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;keepalive&#039;);&lt;br /&gt;
&lt;br /&gt;
// Or multiple&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;keepalive&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;fields.validate&#039;)&lt;br /&gt;
    -&amp;gt;useStyle(&#039;foobar&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add new asset item with dependency and use it&lt;br /&gt;
$wa-&amp;gt;registerAndUseScript(&#039;bar&#039;, &#039;com_foobar/bar.js&#039;, [], [], [&#039;core&#039;, &#039;foobar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:141--&amp;gt; &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; will look to &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039; whether the requested asset exists, and will enable it for current Document instance. Otherwise it will throw an UnknownAssetException.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:142--&amp;gt; To disable an asset in the page use the &#039;&#039;disableAsset&#039;&#039; function. The example below will disable the &#039;&#039;jquery-noconflict&#039;&#039; asset from being loaded.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wa-&amp;gt;disableScript(&#039;jquery-noconflict&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:143--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; If there are any dependencies to the disabled asset, this asset will be re-enabled automatically, no matter what.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:144--&amp;gt; To check whether an asset is enabled, and the asset state:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Checking whether an asset are active (enabled manually or automatically as dependency).&lt;br /&gt;
if ($wa-&amp;gt;isAssetActive(&#039;script&#039;, &#039;foobar&#039;))&lt;br /&gt;
{&lt;br /&gt;
    var_dump(&#039;Script &amp;quot;foobar&amp;quot; is active!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checking state&lt;br /&gt;
switch($wa-&amp;gt;getAssetState(&#039;script&#039;, &#039;foobar&#039;)){&lt;br /&gt;
	case Joomla\CMS\WebAsset\WebAssetManager::ASSET_STATE_ACTIVE:&lt;br /&gt;
		var_dump(&#039;Active! Was enabled manually&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	case Joomla\CMS\WebAsset\WebAssetManager::ASSET_STATE_DEPENDENCY:&lt;br /&gt;
		var_dump(&#039;Active! Was enabled automatically while resolving dependencies&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	default:&lt;br /&gt;
		var_dump(&#039;not active!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Overriding an Asset == &amp;lt;!--T:145--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:146--&amp;gt;&lt;br /&gt;
Overriding may be useful when you need to redefine the URI of asset item or its dependencies.&lt;br /&gt;
As already noted, each of the following assets definition from joomla.asset.json will override asset items from previous assets definitions, by item name.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:147--&amp;gt;&lt;br /&gt;
If you provide joomla.asset.json which contains already loaded asset items, they will be replaced with your items.&lt;br /&gt;
Another way to override in the code is to register an item with the same name.&lt;br /&gt;
Example, we have &#039;&#039;foobar&#039;&#039; script, that loads the &#039;&#039;com_example/foobar.js&#039;&#039; library, and we want to use CDN for this exact library:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:148--&amp;gt; How it defined in the system initially:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:149--&amp;gt; To override the URI, we define the asset item with &#039;&#039;foobar&#039;&#039; name in our joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;http://foobar.cdn.blabla/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:150--&amp;gt; Or, register new asset item with AssetManager:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;foobar&#039;, &#039;http://fobar.cdn.blabla/foobar.js&#039;, [], [], [&#039;core&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with Styles == &amp;lt;!--T:151--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt; AssetManager allows you to manage style sheet files. Style sheet asset items have a type &amp;quot;style&amp;quot;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:153--&amp;gt; Example JSON definition of item in joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.css&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Styles === &amp;lt;!--T:154--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:155--&amp;gt; AssetManager offers the following methods to work with style files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach foobar to the document&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable foobar from being attached&lt;br /&gt;
$wa-&amp;gt;disableStyle(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerStyle(&#039;bar&#039;, &#039;com_example/bar.css&#039;, [], [&#039;data-foo&#039; =&amp;gt; &#039;some attribute&#039;], [&#039;some.dependency&#039;]);&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUseStyle(&#039;bar&#039;, &#039;com_example/bar.css&#039;, [], [&#039;data-foo&#039; =&amp;gt; &#039;some attribute&#039;], [&#039;some.dependency&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add Inline Style === &amp;lt;!--T:156--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:157--&amp;gt;&lt;br /&gt;
Additionally to style files, WebAssetManager allows you to add an inline style, and maintain their relation to the file asset.&lt;br /&gt;
Inline styles may be placed directly before the dependency, after the dependency, or as usual after all styles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:158--&amp;gt; Inline asset may have a name as well as other assets (but not required). The name can be used to retrieve the asset item from a registry, or as a dependency to another inline asset. If the name is not specified then a generated name based on a content hash will be used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Add an inline content as usual, will be rendered in flow after all assets&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline1&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed after &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [&#039;data-foo&#039; =&amp;gt; &#039;bar&#039;], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed before &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline3&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Named inline asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline4&#039;, [&#039;name&#039; =&amp;gt; &#039;my.inline.asset&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:159--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; The &#039;&#039;foobar&#039;&#039; asset should exist in the asset registry, otherwise you will get an unsatisfied dependency exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:160--&amp;gt; The example above will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline3&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;foobar.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style data-foo=&amp;quot;bar&amp;quot;&amp;gt;content of inline2&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline1&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline4&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:161--&amp;gt; If an inline asset has multiple dependencies, then will be used last one for positioning. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline1&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:162--&amp;gt; Will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;foo.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline1&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;bar.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline2&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:163--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Named inline assets may be a dependency to another inline asset, however it is not recommended to use an inline asset as dependency to non-inline asset. This will work, but this behavior may change in the future. Prefer to use &#039;&#039;position&#039;&#039; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with Scripts == &amp;lt;!--T:164--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:165--&amp;gt; AssetManager allow you to manage JavaScript files. Script asset items have a type &amp;quot;script&amp;quot;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:166--&amp;gt; Example JSON definition of item in joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:167--&amp;gt; Example JSON definition of ES6 module script, with fallback to legacy:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar-legacy&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-as5.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;nomodule&amp;quot;: true,&lt;br /&gt;
    &amp;quot;defer&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;core&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar-legacy&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Scripts === &amp;lt;!--T:168--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:169--&amp;gt; AssetManager offers these methods to work with script files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach foobar to the document&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable foobar from being attached&lt;br /&gt;
$wa-&amp;gt;disableScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;bar&#039;, &#039;com_example/bar.js&#039;, [], [&#039;defer&#039; =&amp;gt; true], [&#039;core&#039;]);&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUseScript(&#039;bar&#039;,&#039;com_example/bar.js&#039;, [], [&#039;defer&#039; =&amp;gt; true], [&#039;core&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add Inline Script === &amp;lt;!--T:170--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:171--&amp;gt;&lt;br /&gt;
In addition to script files, WebAssetManager allows you to add an inline script, and maintain their relation to the file asset.&lt;br /&gt;
Inline script may be placed directly before the dependency, after the dependency, or as usual after all scripts.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:172--&amp;gt; Inline asset may have a name as well as other assets (but not required). The name can be used to retrieve the asset item form a registry, or as dependency to another inline asset. If a name is not specified, a generated name based on a content hash will be used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Add an inline content as usual, will be rendered in flow after all assets&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline1&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed after &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [&#039;data-foo&#039; =&amp;gt; &#039;bar&#039;], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed before &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline3&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Named inline asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline4&#039;, [&#039;name&#039; =&amp;gt; &#039;my.inline.asset&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Specify script type&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline5&#039;, [], [&#039;type&#039; =&amp;gt; &#039;module&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:173--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; The &#039;&#039;foobar&#039;&#039; asset should exist in the asset registry, otherwise you will get an unsatisfied dependency exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:174--&amp;gt; Example above will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline3&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;foobar.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script data-foo=&amp;quot;bar&amp;quot;&amp;gt;content of inline2&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline1&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline4&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;module&amp;quot;&amp;gt;content of inline5&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:175--&amp;gt; If an inline asset has multiple dependencies, it will be the last one for positioning. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline1&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:176--&amp;gt; Will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script src=&amp;quot;foo.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline1&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;bar.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline2&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:177--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; Named inline assets may be a dependency on another inline asset, however it is not recommended to use an inline asset as dependency to non-inline asset. This will work, but this behavior may changes in future. Prefer to use &#039;&#039;position&#039;&#039; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with a Web Component == &amp;lt;!--T:178--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:179--&amp;gt;&lt;br /&gt;
Joomla! allows you to use [https://developer.mozilla.org/en-US/docs/Web/Web_Components Web Components] for your needs. In Joomla! web components are not loaded as regular scripts, but loaded via Web Component loader so that they are loaded asynchronously. Therefore, a web component asset item must have a flag &#039;&#039;webcomponent&#039;&#039; set to the boolean &#039;&#039;true&#039;&#039;.&lt;br /&gt;
In all other aspects, working with web components in AssetManager is the same as working with a &#039;&#039;script&#039;&#039; asset item.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:180--&amp;gt; Example JSON definitions of some web components in joomla.asset.json (as ES6 module):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.css&amp;quot;,&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
     &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:181--&amp;gt; Example with fallback, for browsers that does not support ES6 &amp;quot;module&amp;quot; feature. Note that the legacy script should have &amp;quot;wcpolyfill&amp;quot; dependency, and module script should have dependency from legacy script:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.css&amp;quot;,&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar-legacy&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element-es5.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;nomodule&amp;quot;: true,&lt;br /&gt;
    &amp;quot;defer&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;wcpolyfill&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;webcomponent.foobar-legacy&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:182--&amp;gt; Alternatively you can register them in PHP (as an ES6 module):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerStyle(&#039;webcomponent.foobar&#039;, &#039;com_example/foobar-custom-element.css&#039;)&lt;br /&gt;
    -&amp;gt;registerScript(&#039;webcomponent.foobar&#039;, &#039;com_example/foobar-custom-element.js&#039;, [&#039;type&#039; =&amp;gt; &#039;module&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:183--&amp;gt; Attach to document:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;webcomponent.foobar&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;webcomponent.foobar&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:184--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; It is preferred to prefix the asset name with &#039;&#039;webcomponent.&#039;&#039; to make it easily to spot, and distinguish it from regular scripts in a layout.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Web Component === &amp;lt;!--T:185--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:186--&amp;gt; All methods to work with a web component are the same as methods to work with script asset items.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with a Presets == &amp;lt;!--T:187--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:188--&amp;gt;&lt;br /&gt;
A &#039;&#039;preset&#039;&#039; is a special kind of asset item that holds a list of items to be enabled, in the same way as direct call of &#039;&#039;useAsset()&#039;&#039; to each of item in the list.&lt;br /&gt;
Preset can hold mixed types of assets (script, style, another preset, etc.). The type should be provided after a # symbol and follows after an asset name. Example: foo#style, bar#script.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:189--&amp;gt; Example JSON definition of item in joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;preset&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;core#script&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar#style&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar#script&amp;quot;,&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Preset === &amp;lt;!--T:190--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:191--&amp;gt; AssetManager offers these methods to work with preset items:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach all items from foobar preset to the document&lt;br /&gt;
$wa-&amp;gt;usePreset(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable all items from foobar preset from being attached&lt;br /&gt;
$wa-&amp;gt;disablePreset(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerPreset(&#039;bar&#039;, &#039;&#039;, [], [], [&#039;core#script&#039;, &#039;bar#script&#039;]);&lt;br /&gt;
&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;usePreset(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUsePreset(&#039;bar&#039;,&#039;&#039;, [], [], [&#039;core#script&#039;, &#039;bar#script&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Advanced: Custom WebAssetItem Class == &amp;lt;!--T:192--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:193--&amp;gt; The default class for all WebAsset items is &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:194--&amp;gt; You are also allowed to use a custom class, which must implement &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItemInterface&#039;&#039;&#039; or extend &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:195--&amp;gt; A custom class allows you to do advanced actions. For example, including a script file depending on an active language:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class MyComExampleAssetItem extends WebAssetItem&lt;br /&gt;
{&lt;br /&gt;
	public function getUri($resolvePath = true): string&lt;br /&gt;
	{&lt;br /&gt;
		$langTag = Factory::getApplication()-&amp;gt;getLanguage()-&amp;gt;getTag();&lt;br /&gt;
		// For script asset use &amp;quot;.js&amp;quot;, for style we would use &amp;quot;.css&amp;quot;&lt;br /&gt;
		$path    = &#039;com_example/bar-&#039; . $langTag . &#039;.js&#039;;&lt;br /&gt;
&lt;br /&gt;
		if ($resolvePath)&lt;br /&gt;
		{&lt;br /&gt;
			// For script asset use &amp;quot;script&amp;quot;, for style we would use &amp;quot;stylesheet&amp;quot;&lt;br /&gt;
			$path = $this-&amp;gt;resolvePath($path, &#039;script&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return $path;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:196--&amp;gt; Additionally, implementing &#039;&#039;Joomla\CMS\WebAsset\WebAssetAttachBehaviorInterface&#039;&#039; allows you to add script options (which may depend on the environment) when your asset is enabled and attached to the Document.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class MyFancyFoobarAssetItem extends WebAssetItem implements WebAssetAttachBehaviorInterface&lt;br /&gt;
{&lt;br /&gt;
	public function onAttachCallback(Document $doc): void&lt;br /&gt;
	{&lt;br /&gt;
		$user = Factory::getApplication()-&amp;gt;getIdentity();&lt;br /&gt;
		$doc-&amp;gt;addScriptOptions(&#039;com_example.fancyfoobar&#039;, [&#039;userName&#039; =&amp;gt; $user-&amp;gt;username]);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:197--&amp;gt; &#039;&#039;&#039;Important Note&#039;&#039;&#039; An asset item that implements &#039;&#039;WebAssetAttachBehaviorInterface&#039;&#039; should be enabled before a [https://docs.joomla.org/Plugin/Events/System#onBeforeCompileHead onBeforeCompileHead] event, otherwise &#039;&#039;onAttachCallback&#039;&#039; will be ignored.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Defining a Custom WebAssetItem Class in &#039;&#039;joomla.asset.json&#039;&#039; === &amp;lt;!--T:198--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:199--&amp;gt;&lt;br /&gt;
In joomla.asset.json you can define which Class should be used with a specific AssetItem.&lt;br /&gt;
For this you can use two properties &#039;&#039;&#039;namespace&#039;&#039;&#039; and &#039;&#039;&#039;class&#039;&#039;&#039;. &#039;&#039;&#039;namespace&#039;&#039;&#039; can be defined at Root level. (Then it will be used as default namespace for all Asset items in joomla.asset.json) or in the Item level. For example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;namespace&amp;quot;: &amp;quot;Joomla\Component\Example\WebAsset&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;foo&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;FooAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/foo.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;namespace&amp;quot;: &amp;quot;MyFooBar\Library\Example\WebAsset&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;BarAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:200--&amp;gt; Here the asset &#039;&#039;foo&#039;&#039; will be associated with class &#039;&#039;Joomla\Component\Example\WebAsset\FooAssetItem&#039;&#039;, and &#039;&#039;bar&#039;&#039; with class &#039;&#039;MyFooBar\Library\Example\WebAsset\BarAssetItem&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:201--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; If &#039;&#039;namespace&#039;&#039; is not defined, by default &#039;&#039;Joomla\CMS\WebAsset&#039;&#039; will be used. When &#039;&#039;namespace&#039;&#039; is defined but empty, no namespace will be used, only &#039;&#039;class&#039;&#039;. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;foo&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;FooAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/foo.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;namespace&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;BarAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:202--&amp;gt; Here the asset &#039;&#039;foo&#039;&#039; will be associated with class &#039;&#039;Joomla\CMS\WebAsset\FooAssetItem&#039;&#039;, and &#039;&#039;bar&#039;&#039; with class &#039;&#039;BarAssetItem&#039;&#039; (without namespace).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.0{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Web_Assets&amp;diff=1001132</id>
		<title>J4.x:Web Assets</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Web_Assets&amp;diff=1001132"/>
		<updated>2023-04-30T22:34:04Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Markup, spelling changes and some Words2Watch corrections.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Concept == &amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:115--&amp;gt; In the Frontend world many assets are related. For example our keepalive script depends on the core.js file for options management. In Joomla there never was an easy way to specify this; you just had to include multiple files. Joomla 4 changes this with the concept of web assets.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Definition == &amp;lt;!--T:116--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt; Related assets are defined in a JSON file such as [https://github.com/joomla/joomla-cms/blob/7b72c565b610e02c1b01f8958d622879631fa6a2/build/media_source/system/joomla.asset.json#L14-L21 system/joomla.asset.json#L14-L21]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:118--&amp;gt; This has a structure of having a schema definition (for validation), name, version, license and then one or more asset definitions. Assets are comprised of a list of JavaScript files and CSS files related to the assets and any dependencies. The dependencies section is just a list of asset names that are required for the asset to function. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;description&amp;quot;: &amp;quot;Joomla CMS&amp;quot;,&lt;br /&gt;
  &amp;quot;license&amp;quot;: &amp;quot;GPL-2.0+&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.css&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;beer&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/beer.css&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;bar&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;beer&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
        &amp;quot;core&amp;quot;,&lt;br /&gt;
        &amp;quot;bar&amp;quot;&lt;br /&gt;
      ],&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/beer.js&amp;quot;,&lt;br /&gt;
      &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
        &amp;quot;defer&amp;quot;: true,&lt;br /&gt;
        &amp;quot;data-foo&amp;quot;: &amp;quot;bar&amp;quot;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt; The &amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot; inline&amp;gt;$schema&amp;lt;/syntaxhighlight&amp;gt; attribute is a schema definition file that allows you to validate your file using JSON Schema. Read [https://json-schema.org/understanding-json-schema/index.html the official website] for more information on JSON schema validation works.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:120--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; Having joomla.asset.json for your extension or template are recommend but not required to WebAsset to work (see next section).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:121--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; It is not recommended to add an inline asset to a JSON file, prefer to use a file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Explaining Asset Stages == &amp;lt;!--T:122--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:123--&amp;gt; Each asset has two stages: registered and used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:124--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Registered&#039;&#039;&#039; is where an asset is loaded into &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;. That means &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; knows about the existence of these assets, but will not attach them to a document while rendering.&lt;br /&gt;
All assets loaded from joomla.asset.json is at &#039;&#039;&#039;registered&#039;&#039;&#039; stage.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:125--&amp;gt; &#039;&#039;&#039;Used&#039;&#039;&#039; is where an asset is enabled via &amp;quot;$wa-&amp;gt;useAsset()&amp;quot; (-&amp;gt;useScript(), -&amp;gt;useStyle(), -&amp;gt;registerAndUseX() etc). That means &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; will attach these assets and their dependencies to a document while rendering.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;gt; An asset cannot be used if it was not registered before, this will cause an unknown asset exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Register an Asset == &amp;lt;!--T:127--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:128--&amp;gt; All known assets loaded and then stored in &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039; (to enable/disable an asset item you have to use &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;, see next section).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:129--&amp;gt; Joomla! will look for next assets definition automatically at runtime (in following order):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
media/vendor/joomla.asset.json (on first access to WebAssetRegistry)&lt;br /&gt;
media/system/joomla.asset.json&lt;br /&gt;
media/legacy/joomla.asset.json&lt;br /&gt;
media/{com_active_component}/joomla.asset.json (on dispatch the application)&lt;br /&gt;
templates/{active_template}/joomla.asset.json&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt; And load them to registry of known assets.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:131--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; Each following assets definition will override asset items from previous assets definition, by item name.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:132--&amp;gt; You can register your own assets definition via &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wr = $wa-&amp;gt;getRegistry();&lt;br /&gt;
$wr-&amp;gt;addRegistryFile(&#039;relative/path/to/your/joomla.asset.json&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:133--&amp;gt; To add a custom asset item at runtime:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wr-&amp;gt;add(&#039;script&#039;, new Joomla\CMS\WebAsset\WebAssetItem(&#039;foobar&#039;, &#039;com_foobar/file.js&#039;, [&#039;type&#039; =&amp;gt; &#039;script&#039;]));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:134--&amp;gt; Or more simply, using &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;foobar&#039;, &#039;com_foobar/file.js&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:135--&amp;gt; The new asset item &#039;&#039;&#039;foobar&#039;&#039;&#039; will be added to the registry of know assets, but will not be attached to a document until your code (a layout, template etc) will request it.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt; To check whether an asset exists:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
if ($wa-&amp;gt;assetExists(&#039;script&#039;, &#039;foobar&#039;))&lt;br /&gt;
{&lt;br /&gt;
    var_dump(&#039;Script &amp;quot;foobar&amp;quot; exists!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Enabling an Asset == &amp;lt;!--T:137--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:138--&amp;gt; All asset management in the current Document handled by &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039;, which is accessible with &#039;&#039;&#039;$doc-&amp;gt;getWebAssetManager();&#039;&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:139--&amp;gt; By using AssetManager you can enable or disable needed asset easily in Joomla! through a standard methods.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:140--&amp;gt; To enable an asset in the page use the useAsset function, for example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;keepalive&#039;);&lt;br /&gt;
&lt;br /&gt;
// Or multiple&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;keepalive&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;fields.validate&#039;)&lt;br /&gt;
    -&amp;gt;useStyle(&#039;foobar&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add new asset item with dependency and use it&lt;br /&gt;
$wa-&amp;gt;registerAndUseScript(&#039;bar&#039;, &#039;com_foobar/bar.js&#039;, [], [], [&#039;core&#039;, &#039;foobar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:141--&amp;gt; &#039;&#039;&#039;WebAssetManager&#039;&#039;&#039; will look to &#039;&#039;&#039;WebAssetRegistry&#039;&#039;&#039; whether the requested asset exists, and will enable it for current Document instance. Otherwise it will throw an UnknownAssetException.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:142--&amp;gt; To disable an asset in the page use the disableAsset function. The example below will disable the jquery-noconflict asset from being loaded.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
$wa-&amp;gt;disableScript(&#039;jquery-noconflict&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:143--&amp;gt; &#039;&#039;&#039;Note&#039;&#039;&#039; If there are any dependencies to the disabled asset, then this asset will be re-enabled automatically, no matter what.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:144--&amp;gt; To check whether asset enabled, and the asset state:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
// Checking whether an asset are active (enabled manually or automatically as dependency)&lt;br /&gt;
if ($wa-&amp;gt;isAssetActive(&#039;script&#039;, &#039;foobar&#039;))&lt;br /&gt;
{&lt;br /&gt;
    var_dump(&#039;Script &amp;quot;foobar&amp;quot; is active!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Checking state&lt;br /&gt;
switch($wa-&amp;gt;getAssetState(&#039;script&#039;, &#039;foobar&#039;)){&lt;br /&gt;
	case Joomla\CMS\WebAsset\WebAssetManager::ASSET_STATE_ACTIVE:&lt;br /&gt;
		var_dump(&#039;Active! Was enabled manually&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	case Joomla\CMS\WebAsset\WebAssetManager::ASSET_STATE_DEPENDENCY:&lt;br /&gt;
		var_dump(&#039;Active! Was enabled automatically while resolving dependencies&#039;);&lt;br /&gt;
		break;&lt;br /&gt;
	default:&lt;br /&gt;
		var_dump(&#039;not active!&#039;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Overriding an Asset == &amp;lt;!--T:145--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:146--&amp;gt;&lt;br /&gt;
Overriding may be useful when you need to redefine the URI of asset item or its dependencies.&lt;br /&gt;
As already was noted, each of the following assets definition from joomla.asset.json will override asset items from previous assets definitions, by item name.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:147--&amp;gt;&lt;br /&gt;
That means if you provide joomla.asset.json which contain already loaded asset items, they will be replaced with your items.&lt;br /&gt;
Another way to override in the code is to register an item with the same name.&lt;br /&gt;
Example, we have &amp;quot;foobar&amp;quot; script, that load com_example/foobar.js library, and we want to use CDN for this exact library:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:148--&amp;gt; How it defined in the system initially:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:149--&amp;gt; To override the URI we define the asset item with &amp;quot;foobar&amp;quot; name in our joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;http://foobar.cdn.blabla/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:150--&amp;gt; Or, register new asset item with AssetManager:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;foobar&#039;, &#039;http://fobar.cdn.blabla/foobar.js&#039;, [], [], [&#039;core&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with Styles == &amp;lt;!--T:151--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt; AssetManager allow to manage Stylesheet files. Stylesheet asset item have a type &amp;quot;style&amp;quot;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:153--&amp;gt; Example JSON definition of item in joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.css&amp;quot;&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Styles === &amp;lt;!--T:154--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:155--&amp;gt; AssetManager offers the following methods to work with style files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach foobar to the document&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable foobar from being attached&lt;br /&gt;
$wa-&amp;gt;disableStyle(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerStyle(&#039;bar&#039;, &#039;com_example/bar.css&#039;, [], [&#039;data-foo&#039; =&amp;gt; &#039;some attribute&#039;], [&#039;some.dependency&#039;]);&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUseStyle(&#039;bar&#039;, &#039;com_example/bar.css&#039;, [], [&#039;data-foo&#039; =&amp;gt; &#039;some attribute&#039;], [&#039;some.dependency&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add Inline Style === &amp;lt;!--T:156--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:157--&amp;gt;&lt;br /&gt;
Additionally to style files, WebAssetManager allows you to add an inline style, and maintain their relation to the file asset.&lt;br /&gt;
Inline styles may be placed directly before the dependency, after the dependency, or as usual after all styles.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:158--&amp;gt; Inline asset may have a name as well as other assets (but not required), the name can be used to retrieve the asset item from a registry, or as a dependency to another inline asset. If the name is not specified then a generated name based on a content hash will be used.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Add an inline content as usual, will be rendered in flow after all assets&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline1&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed after &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [&#039;data-foo&#039; =&amp;gt; &#039;bar&#039;], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed before &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline3&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Named inline asset&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline4&#039;, [&#039;name&#039; =&amp;gt; &#039;my.inline.asset&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:159--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; &amp;quot;foobar&amp;quot; asset should exist in the asset registry, otherwise you will get an unsatisfied dependency exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:160--&amp;gt; Example above will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline3&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;foobar.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style data-foo=&amp;quot;bar&amp;quot;&amp;gt;content of inline2&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline1&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline4&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:161--&amp;gt; If inline asset has multiple dependencies, then will be used last one for positioning. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline1&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
$wa-&amp;gt;addInlineStyle(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:162--&amp;gt; Will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;foo.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline1&amp;lt;/style&amp;gt;&lt;br /&gt;
&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;bar.css&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;style&amp;gt;content of inline2&amp;lt;/style&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:163--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; Named inline assets may be a dependency to another inline asset, however it is not recommended to use an inline asset as dependency to non-inline asset. This will work, but this behavior may change in the future. Prefer to use &amp;quot;position&amp;quot; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with Scripts == &amp;lt;!--T:164--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:165--&amp;gt; AssetManager allow to manage Script files. Script asset item have a type &amp;quot;script&amp;quot;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:166--&amp;gt; Example JSON definition of item in joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:167--&amp;gt; Example JSON definition of ES6 module script, with fallback to legacy:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar-legacy&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-as5.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;nomodule&amp;quot;: true,&lt;br /&gt;
    &amp;quot;defer&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&amp;quot;core&amp;quot;]&lt;br /&gt;
}&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;core&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar-legacy&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Scripts === &amp;lt;!--T:168--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:169--&amp;gt; AssetManager offer next methods to work with script files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach foobar to the document&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable foobar from being attached&lt;br /&gt;
$wa-&amp;gt;disableScript(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerScript(&#039;bar&#039;, &#039;com_example/bar.js&#039;, [], [&#039;defer&#039; =&amp;gt; true], [&#039;core&#039;]);&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;useScript(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUseScript(&#039;bar&#039;,&#039;com_example/bar.js&#039;, [], [&#039;defer&#039; =&amp;gt; true], [&#039;core&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Add Inline Script === &amp;lt;!--T:170--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:171--&amp;gt;&lt;br /&gt;
Additionally to script files WebAssetManager allow to add an inline script, and maintain their relation to the file asset.&lt;br /&gt;
Inline script may be placed directly before the dependency, after the dependency, or as usual after all scripts.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:172--&amp;gt; Inline asset may have a name as well as other assets (but not required), the name can be used to retrieve the asset item form a registry, or as dependency to another inline asset. If name not specified then will be used generated name based on a content hash.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Add an inline content as usual, will be rendered in flow after all assets&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline1&#039;);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed after &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [&#039;data-foo&#039; =&amp;gt; &#039;bar&#039;], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Add an inline content that will be placed before &amp;quot;foobar&amp;quot; asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline3&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foobar&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Named inline asset&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline4&#039;, [&#039;name&#039; =&amp;gt; &#039;my.inline.asset&#039;]);&lt;br /&gt;
&lt;br /&gt;
// Specify script type&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline5&#039;, [], [&#039;type&#039; =&amp;gt; &#039;module&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:173--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; &amp;quot;foobar&amp;quot; asset should exist in the asset registry, otherwise you will get an unsatisfied dependency exception.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:174--&amp;gt; Example above will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline3&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;foobar.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script data-foo=&amp;quot;bar&amp;quot;&amp;gt;content of inline2&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline1&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline4&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script type=&amp;quot;module&amp;quot;&amp;gt;content of inline5&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:175--&amp;gt; If inline asset have a multiple dependencies, then will be used last one for positioning. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline1&#039;, [&#039;position&#039; =&amp;gt; &#039;before&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
$wa-&amp;gt;addInlineScript(&#039;content of inline2&#039;, [&#039;position&#039; =&amp;gt; &#039;after&#039;], [], [&#039;foo&#039;, &#039;bar&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:176--&amp;gt; Will produce:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;html5&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;script src=&amp;quot;foo.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline1&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script src=&amp;quot;bar.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;
&amp;lt;script&amp;gt;content of inline2&amp;lt;/script&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:177--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; Named inline asset may be as dependency to another inline asset, however it is not recommended to use an inline asset as dependency to non-inline asset. This will work, but this behavior may changes in future. Prefer to use &amp;quot;position&amp;quot; instead.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with a Web Component == &amp;lt;!--T:178--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:179--&amp;gt;&lt;br /&gt;
Joomla! allows you to use [https://developer.mozilla.org/en-US/docs/Web/Web_Components Web Components] for your needs. In Joomla! web components are not loaded as regular script, but loaded via Web Component loader so that they are loaded asynchronously. Therefore, a web component asset item must have a flag &amp;quot;webcomponent&amp;quot; set to the boolean &amp;quot;true&amp;quot;.&lt;br /&gt;
In all other aspects, working with web components in AssetManager is the same as working with a &amp;quot;script&amp;quot; asset item.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:180--&amp;gt; Example JSON definition of some web components in joomla.asset.json (as ES6 module):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.css&amp;quot;,&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
     &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:181--&amp;gt; Example with fallback, for browsers that does not support ES6 &amp;quot;module&amp;quot; feature. Note that the legacy script should have &amp;quot;wcpolyfill&amp;quot; dependency, and module script should have dependency from legacy script:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;style&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.css&amp;quot;,&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar-legacy&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element-es5.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;nomodule&amp;quot;: true,&lt;br /&gt;
    &amp;quot;defer&amp;quot;: true&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;wcpolyfill&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
},&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;webcomponent.foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;com_example/foobar-custom-element.js&amp;quot;,&lt;br /&gt;
  &amp;quot;attributes&amp;quot;: {&lt;br /&gt;
    &amp;quot;type&amp;quot;: &amp;quot;module&amp;quot;&lt;br /&gt;
  },&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;webcomponent.foobar-legacy&amp;quot;&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:182--&amp;gt; Alternatively you can register them in PHP (as ES6 module):&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;registerStyle(&#039;webcomponent.foobar&#039;, &#039;com_example/foobar-custom-element.css&#039;)&lt;br /&gt;
    -&amp;gt;registerScript(&#039;webcomponent.foobar&#039;, &#039;com_example/foobar-custom-element.js&#039;, [&#039;type&#039; =&amp;gt; &#039;module&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:183--&amp;gt; Attach to document:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
$wa-&amp;gt;useStyle(&#039;webcomponent.foobar&#039;)&lt;br /&gt;
    -&amp;gt;useScript(&#039;webcomponent.foobar&#039;);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:184--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note:&#039;&#039;&#039; It is preferred to prefix the asset name with &amp;quot;webcomponent.&amp;quot; to make it easily to spot, and distinct it from regular scripts in a layout.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Web Component === &amp;lt;!--T:185--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:186--&amp;gt; All methods to work with a web component are the same as methods to work with script asset item.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Working with a Presets == &amp;lt;!--T:187--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:188--&amp;gt;&lt;br /&gt;
&amp;quot;Preset&amp;quot; is a special kind of asset item that hold a list of items that has to be enabled, in same way as direct call of useAsset() to each of item in the list.&lt;br /&gt;
Preset can hold mixed types of assets (script, style, another preset, etc), the type should be provided after # symbol and follows after an asset name, example: foo#style, bar#script.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:189--&amp;gt; Example JSON definition of item in joomla.asset.json:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;foobar&amp;quot;,&lt;br /&gt;
  &amp;quot;type&amp;quot;: &amp;quot;preset&amp;quot;,&lt;br /&gt;
  &amp;quot;uri&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
  &amp;quot;dependencies&amp;quot;: [&lt;br /&gt;
    &amp;quot;core#script&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar#style&amp;quot;,&lt;br /&gt;
    &amp;quot;foobar#script&amp;quot;,&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Methods to Work with Preset === &amp;lt;!--T:190--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:191--&amp;gt; AssetManager offer next methods to work with preset items:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */&lt;br /&gt;
$wa = Factory::getApplication()-&amp;gt;getDocument()-&amp;gt;getWebAssetManager();&lt;br /&gt;
&lt;br /&gt;
// Attach all items from foobar preset to the document&lt;br /&gt;
$wa-&amp;gt;usePreset(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Disable all items from foobar preset from being attached&lt;br /&gt;
$wa-&amp;gt;disablePreset(&#039;foobar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register custom item without JSON definition&lt;br /&gt;
$wa-&amp;gt;registerPreset(&#039;bar&#039;, &#039;&#039;, [], [], [&#039;core#script&#039;, &#039;bar#script&#039;]);&lt;br /&gt;
&lt;br /&gt;
// And use it later&lt;br /&gt;
$wa-&amp;gt;usePreset(&#039;bar&#039;);&lt;br /&gt;
&lt;br /&gt;
// Register and attach a custom item in one run&lt;br /&gt;
$wa-&amp;gt;registerAndUsePreset(&#039;bar&#039;,&#039;&#039;, [], [], [&#039;core#script&#039;, &#039;bar#script&#039;]);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Advanced: Custom WebAssetItem Class == &amp;lt;!--T:192--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:193--&amp;gt; The default class for all WebAsset items is &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:194--&amp;gt; You are also allowed to use a custom class, which must implement &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItemInterface&#039;&#039;&#039; or extend &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:195--&amp;gt; A custom class can allow you to do advanced actions, for example, including a script file depending on an active language:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class MyComExampleAssetItem extends WebAssetItem&lt;br /&gt;
{&lt;br /&gt;
	public function getUri($resolvePath = true): string&lt;br /&gt;
	{&lt;br /&gt;
		$langTag = Factory::getApplication()-&amp;gt;getLanguage()-&amp;gt;getTag();&lt;br /&gt;
		// For script asset use &amp;quot;.js&amp;quot;, for style we would use &amp;quot;.css&amp;quot;&lt;br /&gt;
		$path    = &#039;com_example/bar-&#039; . $langTag . &#039;.js&#039;;&lt;br /&gt;
&lt;br /&gt;
		if ($resolvePath)&lt;br /&gt;
		{&lt;br /&gt;
			// For script asset use &amp;quot;script&amp;quot;, for style we would use &amp;quot;stylesheet&amp;quot;&lt;br /&gt;
			$path = $this-&amp;gt;resolvePath($path, &#039;script&#039;);&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		return $path;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:196--&amp;gt; Additionally, implementing &#039;&#039;&#039;Joomla\CMS\WebAsset\WebAssetAttachBehaviorInterface&#039;&#039;&#039; allows you to add a script options (which may depend on the environment) when your asset is enabled and attached to the Document.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
class MyFancyFoobarAssetItem extends WebAssetItem implements WebAssetAttachBehaviorInterface&lt;br /&gt;
{&lt;br /&gt;
	public function onAttachCallback(Document $doc): void&lt;br /&gt;
	{&lt;br /&gt;
		$user = Factory::getApplication()-&amp;gt;getIdentity();&lt;br /&gt;
		$doc-&amp;gt;addScriptOptions(&#039;com_example.fancyfoobar&#039;, [&#039;userName&#039; =&amp;gt; $user-&amp;gt;username]);&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:197--&amp;gt; &#039;&#039;&#039;Important note:&#039;&#039;&#039; An asset item that implements &#039;&#039;&#039;WebAssetAttachBehaviorInterface&#039;&#039;&#039; should be enabled before [https://docs.joomla.org/Plugin/Events/System#onBeforeCompileHead onBeforeCompileHead] event, otherwise &#039;onAttachCallback&#039; will be ignored.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Defining a Custom WebAssetItem Class in &#039;&#039;joomla.asset.json&#039;&#039; === &amp;lt;!--T:198--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:199--&amp;gt;&lt;br /&gt;
In joomla.asset.json you can define which Class should be used with specific AssetItem.&lt;br /&gt;
For this you can use 2 properties &#039;&#039;&#039;namespace&#039;&#039;&#039; and &#039;&#039;&#039;class&#039;&#039;&#039;. &#039;&#039;&#039;namespace&#039;&#039;&#039; can be defined at Root level (then it will be used as default namespace for all Asset items in joomla.asset.json) or in the Item level. For example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;version&amp;quot;: &amp;quot;4.0.0&amp;quot;,&lt;br /&gt;
  &amp;quot;namespace&amp;quot;: &amp;quot;Joomla\Component\Example\WebAsset&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;foo&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;FooAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/foo.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;namespace&amp;quot;: &amp;quot;MyFooBar\Library\Example\WebAsset&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;BarAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:200--&amp;gt; Here the asset &#039;&#039;&#039;foo&#039;&#039;&#039; will be associated with class &#039;&#039;&#039;Joomla\Component\Example\WebAsset\FooAssetItem&#039;&#039;&#039;, and &#039;&#039;&#039;bar&#039;&#039;&#039; with class &#039;&#039;&#039;MyFooBar\Library\Example\WebAsset\BarAssetItem&#039;&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:201--&amp;gt; &#039;&#039;&#039;Note:&#039;&#039;&#039; If &#039;&#039;&#039;namespace&#039;&#039;&#039; are not defined then by default will be used &#039;&#039;&#039;Joomla\CMS\WebAsset&#039;&#039;&#039;. When &#039;&#039;&#039;namespace&#039;&#039;&#039; is defined but empty, then no namespace will be used, only &#039;&#039;&#039;class&#039;&#039;&#039;. Example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;json&amp;quot;&amp;gt;&lt;br /&gt;
{&lt;br /&gt;
  &amp;quot;$schema&amp;quot;: &amp;quot;https://developer.joomla.org/schemas/json-schema/web_assets.json&amp;quot;,&lt;br /&gt;
  &amp;quot;name&amp;quot;: &amp;quot;com_example&amp;quot;,&lt;br /&gt;
  &amp;quot;assets&amp;quot;: [&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;foo&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;FooAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/foo.js&amp;quot;&lt;br /&gt;
    },&lt;br /&gt;
    {&lt;br /&gt;
      &amp;quot;name&amp;quot;: &amp;quot;bar&amp;quot;,&lt;br /&gt;
      &amp;quot;type&amp;quot;: &amp;quot;script&amp;quot;,&lt;br /&gt;
      &amp;quot;namespace&amp;quot;: &amp;quot;&amp;quot;,&lt;br /&gt;
      &amp;quot;class&amp;quot;: &amp;quot;BarAssetItem&amp;quot;,&lt;br /&gt;
      &amp;quot;uri&amp;quot;: &amp;quot;com_example/bar.js&amp;quot;&lt;br /&gt;
    }&lt;br /&gt;
  ]&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:202--&amp;gt; Here the asset &#039;&#039;&#039;foo&#039;&#039;&#039; will be associated with class &#039;&#039;&#039;Joomla\CMS\WebAsset\FooAssetItem&#039;&#039;&#039;, and &#039;&#039;&#039;bar&#039;&#039;&#039; with class &#039;&#039;&#039;BarAssetItem&#039;&#039;&#039; (without namespace).&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.0{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=J4.x:Creating_a_Simple_Module&amp;diff=1001131</id>
		<title>J4.x:Creating a Simple Module</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=J4.x:Creating_a_Simple_Module&amp;diff=1001131"/>
		<updated>2023-04-30T17:28:16Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup and capitalization changes. Some Words2Watch changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{Joomla version|version=4.x|comment=&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt; Tutorial&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{-}}&lt;br /&gt;
{{Top portal heading|color=white-bkgd|icon=file-code-o|icon-color=#5091cd|size=5x|text-color=#333|title=&amp;lt;translate&amp;gt;&amp;lt;!--T:2--&amp;gt; Creating a Simple Module for Joomla 4.x&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
{{-}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt; This is a tutorial on how to Create a simple module for Joomla Version 4x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Introduction == &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt; Joomlaǃ 4 provides five types of extensionsː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;[[S:MyLanguage/Component|&amp;lt;translate&amp;gt;&amp;lt;!--T:6--&amp;gt; Components&amp;lt;/translate&amp;gt;]]&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt; A component is the main part of the site. A component handles data manipulation as well as input and storage into the database. A component on most sites is the primary focus of the page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;[[S:MyLanguage/Module|&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt; Modules&amp;lt;/translate&amp;gt;]]&#039;&#039;&#039; &amp;lt;br /&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:9--&amp;gt; A module is an add-on to the site that extends the functionality. A module usually occupies a secondary portion of the web page and is not considered the primary focus of a page. It can be displayed on different positions and you can choose on which active menu items it should be displayed. Modules are lightweight and flexible extensions. They are used for small bits of the page that are generally less complex and are able to be seen across different components.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;[[S:MyLanguage/Plugin|&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt; Plugins&amp;lt;/translate&amp;gt;]]&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt; A Plugin manipulates output that is already generated by the system. It typically does not run as separate part of the site. It takes data from other sources (i.e. the content) and manipulates this data before displaying. A plugin typically work behind the scenes.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;[[S:MyLanguage/Languages|&amp;lt;translate&amp;gt;&amp;lt;!--T:12--&amp;gt; Languages&amp;lt;/translate&amp;gt;]]&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:203--&amp;gt; Probably the most basic extensions are languages. In essence the language package files consist of key/value pairs, which provide the translation of static text strings, assigned within the Joomla! source code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
* &#039;&#039;&#039;[[S:MyLanguage/Templates|&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt; Templates&amp;lt;/translate&amp;gt;]]&#039;&#039;&#039;&amp;lt;br /&amp;gt;&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt; A template is basically the design of your Joomla! powered website.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt; Joomla! 4 is constructed using five different applications:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
* Installation (used for installing Joomla and have to delete after installation)&lt;br /&gt;
* Administrator (Backend - used for managing content)&lt;br /&gt;
* Public or site (Frontend - used for displaying content)&lt;br /&gt;
* CLI (used for accessing Joomla on the command line and for cron jobs)&lt;br /&gt;
* API (web services - used for creating APIs for machine accessible content)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
The installation application is used once. The administrator and public are used through the concept of &#039;&#039;components&#039;&#039; with &#039;&#039;modules&#039;&#039;. Each module has a single entry point located in the &#039;&#039;modules&#039;&#039; and accordingly &#039;&#039;administrator/modules&#039;&#039;  directory. This entry point is called &amp;lt;tt&amp;gt;&#039;&#039;mod_modulename/mod_modulename.php&#039;&#039;&amp;lt;/tt&amp;gt; (the &#039;&#039;mod_&#039;&#039; prefix is a historical trace). The entry point for the login module is for example &#039;&#039;/mod_login/mod_login.php&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Requirements === &amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt; You need Joomla! 4.x installation available to use for this tutorial ([https://github.com/joomla/joomla-cms/releases Download latest release here])&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt; You can download Joomla! 4 at [https://github.com/joomla/joomla-cms/releases GitHub], on the [https://developer.joomla.org/nightly-builds.html Developer website] or you can create a free website at https://launch.joomla.org.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Creating a Simple Module/Developing a Basic Module == &amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:22--&amp;gt; You can see many examples of modules in the standard Joomla! install. For example:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
* Menus&lt;br /&gt;
* Latest News&lt;br /&gt;
* Login form&lt;br /&gt;
* and many more.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt; This tutorial will explain how to create a simple module. Through this tutorial you will learn the basic file structure of a Joomlaǃ 4 module. This basic structure can then be expanded to produce more elaborate modules.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== File Structure === &amp;lt;!--T:25--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt; There are a few basic files that are used in the standard pattern of module development:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt; * &amp;lt;tt&amp;gt;mod_foo.php&amp;lt;/tt&amp;gt; - This file is the main entry point for the module. It will perform any necessary initialization routines, call helper routines to collect any necessary data, and include the template which will display the module output.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt; * &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; - This file contains information about the module. It defines the files that need to be installed by the Joomla! installer and specifies configuration parameters for the module.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt; * &amp;lt;tt&amp;gt;tmpl/default.php&amp;lt;/tt&amp;gt; - This is the module template. This file will take the data collected by mod_foo.php and generate the HTML to be displayed on the page.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt; * &amp;lt;tt&amp;gt;language/en-GB/mod_foo.ini&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;language/en-GB/mod_foo.sys.ini&amp;lt;/tt&amp;gt;- This are the files that provide the text in United Kingdom English.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating mod_foo.php === &amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt; The &amp;lt;tt&amp;gt;mod_foo.php&amp;lt;/tt&amp;gt; file will perform following tasks:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt; * Import the class &amp;lt;tt&amp;gt;ModuleHelper&amp;lt;/tt&amp;gt; to the current scope. We need it later for displaying the output.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt; * Include the template to display the output.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; The helper class is imported to our current scope at the begin of the file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;use Joomla\CMS\Helper\ModuleHelper;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt; Last we include the template to display the output via&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;require ModuleHelper::getLayoutPath(&#039;mod_foo&#039;, $params-&amp;gt;get(&#039;layout&#039;, &#039;default&#039;));&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.php File ==== &amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; The complete &amp;lt;tt&amp;gt;mod_foo.php&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    [PACKAGE_NAME]&lt;br /&gt;
 *&lt;br /&gt;
 * @author     [AUTHOR] &amp;lt;[AUTHOR_EMAIL]&amp;gt;&lt;br /&gt;
 * @copyright  [COPYRIGHT]&lt;br /&gt;
 * @license    GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 * @link       [AUTHOR_URL]&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
use Joomla\CMS\Helper\ModuleHelper;&lt;br /&gt;
&lt;br /&gt;
require ModuleHelper::getLayoutPath(&#039;mod_foo&#039;, $params-&amp;gt;get(&#039;layout&#039;, &#039;default&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt; &#039;&#039;Side note&#039;&#039;ː In Joomla 3x you usually used a line like &amp;lt;tt&amp;gt;$moduleclass_sfx = htmlspecialchars($params-&amp;gt;get(&#039;moduleclass_sfx&#039;));&amp;lt;/tt&amp;gt;. You don&#039;t need this anymore. See this PRː https://github.com/joomla/joomla-cms/pull/17447.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; The one line that we haven’t explained so far is the first line &amp;lt;tt&amp;gt;defined(&#039;_JEXEC&#039;) or die;&amp;lt;/tt&amp;gt;. This line checks to make sure that this file is being included from the Joomla application. This is necessary to prevent variable injection and other potential security concerns.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating tmpl/default.php === &amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt; The &amp;lt;tt&amp;gt;default.php&amp;lt;/tt&amp;gt; file is the template which displays the module output.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed tmpl/default.php file ==== &amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt; The code for the tmpl/default.php file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    [PACKAGE_NAME]&lt;br /&gt;
 *&lt;br /&gt;
 * @author     [AUTHOR] &amp;lt;[AUTHOR_EMAIL]&amp;gt;&lt;br /&gt;
 * @copyright  [COPYRIGHT]&lt;br /&gt;
 * @license    GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 * @link       [AUTHOR_URL]&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
echo &#039;[PROJECT_NAME]&#039;;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt; An important point to note is that the template file has the same scope as the &amp;lt;tt&amp;gt;mod_foo.php&amp;lt;/tt&amp;gt; file. It means that a variable can be defined in the &amp;lt;tt&amp;gt;mod_foo.php&amp;lt;/tt&amp;gt; file and then used in the template file without any extra declarations or function calls.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating mod_foo.xml === &amp;lt;!--T:46--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt; The &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; file is the installation file. Most entries are self-explanatory.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.xml file ==== &amp;lt;!--T:48--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt; The code for the &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt;  file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;extension type=&amp;quot;module&amp;quot; version=&amp;quot;4.0&amp;quot; client=&amp;quot;site&amp;quot; method=&amp;quot;upgrade&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;MOD_FOO&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;creationDate&amp;gt;[DATE]&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
    &amp;lt;author&amp;gt;[AUTHOR]&amp;lt;/author&amp;gt;&lt;br /&gt;
    &amp;lt;authorEmail&amp;gt;[AUTHOR_EMAIL]&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
    &amp;lt;authorUrl&amp;gt;[AUTHOR_URL]&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
    &amp;lt;copyright&amp;gt;[COPYRIGHT]&amp;lt;/copyright&amp;gt;&lt;br /&gt;
    &amp;lt;license&amp;gt;GNU General Public License version 2 or later; see LICENSE.txt&amp;lt;/license&amp;gt;&lt;br /&gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;MOD_FOO_XML_DESCRIPTION&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;files&amp;gt;&lt;br /&gt;
        &amp;lt;filename module=&amp;quot;mod_foo&amp;quot;&amp;gt;mod_foo.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;tmpl&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;language&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;filename&amp;gt;mod_foo.xml&amp;lt;/filename&amp;gt;&lt;br /&gt;
    &amp;lt;/files&amp;gt;&lt;br /&gt;
&amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating the Language Files === &amp;lt;!--T:50--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt; The files &amp;lt;tt&amp;gt;language/en-GB/mod_foo.ini&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;language/en-GB/mod_foo.sys.ini&amp;lt;/tt&amp;gt; are used to translate text in the Frontend and in the Backend. Note that the language file structure has been updated in Joomla 4, and language prefixes on the individual files in a language folder are no longer required.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; The code for &amp;lt;tt&amp;gt;language/en-GB/mod_foo.sys.ini&amp;lt;/tt&amp;gt; is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
MOD_FOO=&amp;quot;[PROJECT_NAME]&amp;quot;&lt;br /&gt;
MOD_FOO_XML_DESCRIPTION=&amp;quot;Foo Module&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:204--&amp;gt; The code for &amp;lt;tt&amp;gt;language/en-GB/mod_foo.ini&amp;lt;/tt&amp;gt; is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
MOD_FOO=&amp;quot;[PROJECT_NAME]&amp;quot;&lt;br /&gt;
MOD_FOO_XML_DESCRIPTION=&amp;quot;Foo Module&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt; The &amp;lt;tt&amp;gt;.sys.ini&amp;lt;/tt&amp;gt; file is used to translate the description of the extension upon installation, where as the &amp;lt;tt&amp;gt;.ini&amp;lt;/tt&amp;gt; file is used to translate the remaining strings and the description when viewing your extension.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt; More information about language files can be found [[S:MyLanguage/Specification_of_language_files|here]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Test Your Module == &amp;lt;!--T:55--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt; Now you can zip all files and install them via the Joomla Extension Manager.&amp;lt;br /&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; After that you can choose your module in the module manager, when you create a new site module.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial1-&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial2-&amp;lt;translate&amp;gt;&amp;lt;!--T:59--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; In the Frontend, you will see your module like displayed in the next image.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial3-&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Conclusion == &amp;lt;!--T:62--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt; Module development for Joomla is a fairly simple, straightforward process. Using the techniques described in this tutorial, an endless variety of modules can be developed with little hassle.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:64--&amp;gt; You can find boilerplates hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla-extensions/boilerplate/tree/master/module&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; The sample files for this Tutorial can be found hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/astridx/boilerplate/tree/tutorial/tutorial/modules&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Add a Helper Class Using Namespaces == &amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Requirements === &amp;lt;!--T:67--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:68--&amp;gt; You need Joomla! 4.x for this tutorial.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Namespaces == &amp;lt;!--T:69--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:70--&amp;gt; With PHP 5.3, the namespaces came into their own. In other programming languages for a long time in use, these small structures now also help us with the clarity of our code.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:71--&amp;gt; Namespaces are separate areas in which certain logical things (in our case, classes, interfaces, functions, and constants) can live. These areas provide encapsulation of the code and prevent name conflicts.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:72--&amp;gt; Let&#039;s take a look how to use them in Joomla 4. We use the helper file for this.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== File Structure === &amp;lt;!--T:73--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:74--&amp;gt; We will create/change the following files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:75--&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;Helper/FooHelper.php&amp;lt;/code&amp;gt; - This is the file we use here as an example. We have to create it.&lt;br /&gt;
* &amp;lt;code&amp;gt;mod_foo.php&amp;lt;/code&amp;gt; - In this file, we will mainly load the namespace.&lt;br /&gt;
* &amp;lt;code&amp;gt;tmpl/default.php&amp;lt;/code&amp;gt; - In this file, we will demonstrate how the data of a helper can be displayed.&lt;br /&gt;
* &amp;lt;code&amp;gt;mod_foo.xml&amp;lt;/code&amp;gt; - We create a new directory with a new file. This must be installed during the installation. For this we have to specify them in this file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating Helper/FooHelper.php === &amp;lt;!--T:76--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:77--&amp;gt; Our new helper class should belong to a namespace. We achieve this with the following code. It is important, that this line is at the beginning of the file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;namespace Joomla\Module\Foo\Site\Helper;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:78--&amp;gt; Then we create a simple class with a simple method. Of course you can do a lot more here. Take a look at the Joomla core methods. Here are many examples. They show you first-hand what options you have.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed Helper/FooHelper.php ==== &amp;lt;!--T:79--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:80--&amp;gt; The complete &amp;lt;tt&amp;gt;FooHelper.php&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package     Joomla.Site&lt;br /&gt;
 * @subpackage  mod_foo&lt;br /&gt;
 *&lt;br /&gt;
 * @copyright   Copyright (C) 2005 - 2019 Open Source Matters, Inc. All rights reserved.&lt;br /&gt;
 * @license     GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
namespace Joomla\Module\Foo\Site\Helper;&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Helper for mod_foo&lt;br /&gt;
 *&lt;br /&gt;
 * @since  4.0&lt;br /&gt;
 */&lt;br /&gt;
class FooHelper&lt;br /&gt;
{&lt;br /&gt;
	/**&lt;br /&gt;
	 * Retrieve foo test&lt;br /&gt;
	 *&lt;br /&gt;
	 * @param   Registry        $params  The module parameters&lt;br /&gt;
	 * @param   CMSApplication  $app     The application&lt;br /&gt;
	 *&lt;br /&gt;
	 * @return  array&lt;br /&gt;
	 */&lt;br /&gt;
	public static function getText()&lt;br /&gt;
	{&lt;br /&gt;
		return &#039;FooHelpertest&#039;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing mod_foo.php === &amp;lt;!--T:81--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:82--&amp;gt; Our new helper class is imported to our current scope at the beginning of the file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;use Joomla\Module\Foo\Site\Helper\FooHelper;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:83--&amp;gt; Last use the helper file for testing if it is loaded correctlyː&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$test  = FooHelper::getText($params, $app);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.php file ==== &amp;lt;!--T:84--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:85--&amp;gt; The complete &amp;lt;tt&amp;gt;mod_foo.php&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    [PACKAGE_NAME]&lt;br /&gt;
 *&lt;br /&gt;
 * @author     [AUTHOR] &amp;lt;[AUTHOR_EMAIL]&amp;gt;&lt;br /&gt;
 * @copyright  [COPYRIGHT]&lt;br /&gt;
 * @license    GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 * @link       [AUTHOR_URL]&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
use Joomla\CMS\Helper\ModuleHelper;&lt;br /&gt;
use Joomla\Module\Foo\Site\Helper\FooHelper;&lt;br /&gt;
&lt;br /&gt;
$test  = FooHelper::getText();&lt;br /&gt;
&lt;br /&gt;
require ModuleHelper::getLayoutPath(&#039;mod_foo&#039;, $params-&amp;gt;get(&#039;layout&#039;, &#039;default&#039;));&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing tmpl/default.php === &amp;lt;!--T:86--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:87--&amp;gt; In this file you make only a small change to demonstrate in the Frontend that your helper file is working properly. You only add the value of the variable at the end of the current output.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;echo &#039;[PROJECT_NAME]&#039; . $test;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed tmpl/default.php ==== &amp;lt;!--T:88--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:89--&amp;gt; The complete &amp;lt;tt&amp;gt;tmpl/default.php&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    [PACKAGE_NAME]&lt;br /&gt;
 *&lt;br /&gt;
 * @author     [AUTHOR] &amp;lt;[AUTHOR_EMAIL]&amp;gt;&lt;br /&gt;
 * @copyright  [COPYRIGHT]&lt;br /&gt;
 * @license    GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 * @link       [AUTHOR_URL]&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
echo &#039;[PROJECT_NAME]&#039; . $test;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing mod_foo.xml === &amp;lt;!--T:90--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:91--&amp;gt; First you have to add a line, so that the namespace is set automatically in Joomla. After this change, you have to re-install your module. A simple change in an already installed module is not enough. If you are doing local development you can also delete the files libraries/autoload_psr4.php and it will automatically be re-created. After inserting and installing, the namespace is known by the loader &amp;lt;tt&amp;gt;JPATH_LIBRARIES . &#039;/autoload_psr4.php&#039;&amp;lt;/tt&amp;gt;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;namespace&amp;gt;Joomla\Module\Foo&amp;lt;/namespace&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:92--&amp;gt; Joomla! should copy your helper file when installing the module. So Joomla! needs to know your helper file. For this, you need to add the following line to your XML file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;folder&amp;gt;Helper&amp;lt;/folder&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.xml ==== &amp;lt;!--T:93--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:94--&amp;gt; The complete &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&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;extension type=&amp;quot;module&amp;quot; version=&amp;quot;4.0&amp;quot; client=&amp;quot;site&amp;quot; method=&amp;quot;upgrade&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;MOD_FOO&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;creationDate&amp;gt;[DATE]&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
    &amp;lt;author&amp;gt;[AUTHOR]&amp;lt;/author&amp;gt;&lt;br /&gt;
    &amp;lt;authorEmail&amp;gt;[AUTHOR_EMAIL]&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
    &amp;lt;authorUrl&amp;gt;[AUTHOR_URL]&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
    &amp;lt;copyright&amp;gt;[COPYRIGHT]&amp;lt;/copyright&amp;gt;&lt;br /&gt;
    &amp;lt;license&amp;gt;GNU General Public License version 2 or later; see LICENSE.txt&amp;lt;/license&amp;gt;&lt;br /&gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;MOD_FOO_XML_DESCRIPTION&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;namespace&amp;gt;Joomla\Module\Foo&amp;lt;/namespace&amp;gt;&lt;br /&gt;
    &amp;lt;files&amp;gt;&lt;br /&gt;
        &amp;lt;filename module=&amp;quot;mod_foo&amp;quot;&amp;gt;mod_foo.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;tmpl&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;Helper&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;language&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;filename&amp;gt;mod_foo.xml&amp;lt;/filename&amp;gt;&lt;br /&gt;
    &amp;lt;/files&amp;gt;&lt;br /&gt;
&amp;lt;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Test Your Module == &amp;lt;!--T:95--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:96--&amp;gt; Now you can zip all files and install them via the Joomla Extension Manager.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:97--&amp;gt; After that you can choose your module in the module manager, when you create a new site module.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:98--&amp;gt; In the Frontend you will see your module like displayed in the next image. The text from your helper file is displayed.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial23-&amp;lt;translate&amp;gt;&amp;lt;!--T:99--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Conclusion == &amp;lt;!--T:100--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:101--&amp;gt; As you can see, once you get a bit into the namespaces, they are not that complicated anymore. In big projects they can bring a lot of benefits. However, we should plan namespaces, as otherwise it will soon be more time-consuming.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:102--&amp;gt; You can find boilerplates hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla-extensions/boilerplate/tree/master/module&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:103--&amp;gt; The sample files for this Tutorial can be found hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/astridx/boilerplate/tree/tutorial/tutorial/modules&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Customizationː Add Parameters Via Form Fields == &amp;lt;!--T:104--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Requirements === &amp;lt;!--T:105--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:106--&amp;gt; You need Joomla! 4.x for this tutorial.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Customization with Form Fields and Parameters == &amp;lt;!--T:107--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:108--&amp;gt; Form fields give a great deal of customization in Joomla and for modules are the sole way of allowing the user to tweak the module to the needs of their site.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:109--&amp;gt; In this case we are going to extend our previous example using a URL field for inserting a domain that we can use as link in the front end. To allow this to happen we will use the [[S:MyLanguage/URL_form_field_type|URL Form Field]] type.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:110--&amp;gt; After that, we insert parameters that allow to use standard functionality of Joomla.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:111--&amp;gt; Let&#039;s take a look on how to use them in Joomla 4.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== File Structure === &amp;lt;!--T:112--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:113--&amp;gt; We will change the following files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:114--&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; - This is the file where we add the fields.&lt;br /&gt;
* &amp;lt;tt&amp;gt;tmpl/default.php&amp;lt;/tt&amp;gt; - In this file demonstrate how the data of a field can be used.&lt;br /&gt;
* &amp;lt;tt&amp;gt;language/en-GB/en-GB.mod_foo.ini&amp;lt;/tt&amp;gt; - Here we use a language string so that the field can be labeled correctly in different languages.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing mod_foo.xml === &amp;lt;!--T:115--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:116--&amp;gt; First we set a custom parameter.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;field&lt;br /&gt;
    name=&amp;quot;domain&amp;quot;&lt;br /&gt;
    type=&amp;quot;url&amp;quot;&lt;br /&gt;
    label=&amp;quot;MOD_FOO_FIELD_URL_LABEL&amp;quot;&lt;br /&gt;
    filter=&amp;quot;url&amp;quot;&lt;br /&gt;
/&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:117--&amp;gt; Then we insert Joomla default fields, so that we can use cache, moduleclass-suffix and layouts.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;field&lt;br /&gt;
    name=&amp;quot;layout&amp;quot;&lt;br /&gt;
    type=&amp;quot;modulelayout&amp;quot;&lt;br /&gt;
    label=&amp;quot;JFIELD_ALT_LAYOUT_LABEL&amp;quot;&lt;br /&gt;
    class=&amp;quot;custom-select&amp;quot;&lt;br /&gt;
/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;field&lt;br /&gt;
    name=&amp;quot;moduleclass_sfx&amp;quot;&lt;br /&gt;
    type=&amp;quot;textarea&amp;quot;&lt;br /&gt;
    label=&amp;quot;COM_MODULES_FIELD_MODULECLASS_SFX_LABEL&amp;quot;&lt;br /&gt;
    rows=&amp;quot;3&amp;quot;&lt;br /&gt;
/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;field&lt;br /&gt;
    name=&amp;quot;cache&amp;quot;&lt;br /&gt;
    type=&amp;quot;list&amp;quot;&lt;br /&gt;
    label=&amp;quot;COM_MODULES_FIELD_CACHING_LABEL&amp;quot;&lt;br /&gt;
    default=&amp;quot;0&amp;quot;&lt;br /&gt;
&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;JGLOBAL_USE_GLOBAL&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;0&amp;quot;&amp;gt;COM_MODULES_FIELD_VALUE_NOCACHING&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/field&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;field&lt;br /&gt;
    name=&amp;quot;cache_time&amp;quot;&lt;br /&gt;
    type=&amp;quot;number&amp;quot;&lt;br /&gt;
    label=&amp;quot;COM_MODULES_FIELD_CACHE_TIME_LABEL&amp;quot;&lt;br /&gt;
    default=&amp;quot;0&amp;quot;&lt;br /&gt;
/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;field&lt;br /&gt;
    name=&amp;quot;cachemode&amp;quot;&lt;br /&gt;
    type=&amp;quot;hidden&amp;quot;&lt;br /&gt;
    default=&amp;quot;itemid&amp;quot;&lt;br /&gt;
&amp;gt;&lt;br /&gt;
    &amp;lt;option value=&amp;quot;itemid&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
&amp;lt;/field&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.xml ==== &amp;lt;!--T:118--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:119--&amp;gt; The complete &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;extension type=&amp;quot;module&amp;quot; version=&amp;quot;4.0&amp;quot; client=&amp;quot;site&amp;quot; method=&amp;quot;upgrade&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;MOD_FOO&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;creationDate&amp;gt;[DATE]&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
    &amp;lt;author&amp;gt;[AUTHOR]&amp;lt;/author&amp;gt;&lt;br /&gt;
    &amp;lt;authorEmail&amp;gt;[AUTHOR_EMAIL]&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
    &amp;lt;authorUrl&amp;gt;[AUTHOR_URL]&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
    &amp;lt;copyright&amp;gt;[COPYRIGHT]&amp;lt;/copyright&amp;gt;&lt;br /&gt;
    &amp;lt;license&amp;gt;GNU General Public License version 2 or later; see LICENSE.txt&amp;lt;/license&amp;gt;&lt;br /&gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;MOD_FOO_XML_DESCRIPTION&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;namespace&amp;gt;Joomla\Module\Foo&amp;lt;/namespace&amp;gt;&lt;br /&gt;
    &amp;lt;files&amp;gt;&lt;br /&gt;
        &amp;lt;filename module=&amp;quot;mod_foo&amp;quot;&amp;gt;mod_foo.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;tmpl&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;Helper&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;language&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;filename&amp;gt;mod_foo.xml&amp;lt;/filename&amp;gt;&lt;br /&gt;
    &amp;lt;/files&amp;gt;&lt;br /&gt;
    &amp;lt;config&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&lt;br /&gt;
                    name=&amp;quot;domain&amp;quot;&lt;br /&gt;
                    type=&amp;quot;url&amp;quot;&lt;br /&gt;
                    label=&amp;quot;MOD_FOO_FIELD_URL_LABEL&amp;quot;&lt;br /&gt;
                    filter=&amp;quot;url&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
            &amp;lt;/fieldset&amp;gt;&lt;br /&gt;
            &amp;lt;fieldset name=&amp;quot;advanced&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;layout&amp;quot;&lt;br /&gt;
                    type=&amp;quot;modulelayout&amp;quot;&lt;br /&gt;
                    label=&amp;quot;JFIELD_ALT_LAYOUT_LABEL&amp;quot;&lt;br /&gt;
                    class=&amp;quot;custom-select&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;moduleclass_sfx&amp;quot;&lt;br /&gt;
                    type=&amp;quot;textarea&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_MODULECLASS_SFX_LABEL&amp;quot;&lt;br /&gt;
                    rows=&amp;quot;3&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cache&amp;quot;&lt;br /&gt;
                    type=&amp;quot;list&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_CACHING_LABEL&amp;quot;&lt;br /&gt;
                    default=&amp;quot;0&amp;quot;&lt;br /&gt;
                &amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;JGLOBAL_USE_GLOBAL&amp;lt;/option&amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;0&amp;quot;&amp;gt;COM_MODULES_FIELD_VALUE_NOCACHING&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;/field&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cache_time&amp;quot;&lt;br /&gt;
                    type=&amp;quot;number&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_CACHE_TIME_LABEL&amp;quot;&lt;br /&gt;
                    default=&amp;quot;0&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cachemode&amp;quot;&lt;br /&gt;
                    type=&amp;quot;hidden&amp;quot;&lt;br /&gt;
                    default=&amp;quot;itemid&amp;quot;&lt;br /&gt;
                &amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;itemid&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;/field&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;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing tmpl/default.php === &amp;lt;!--T:120--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:121--&amp;gt; We can use the value of the parameter for creating a hyperlink in the Frontend. We can access the value via the variable $params.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;$domain = $params-&amp;gt;get(&#039;domain&#039;, &#039;https://www.joomla.org&#039;);&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:122--&amp;gt; Later we set use this value for creating the hyperlink.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;a href=&amp;quot;&amp;lt;?php echo $domain; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;?php echo &#039;[PROJECT_NAME]&#039; . $test; ?&amp;gt;&lt;br /&gt;
&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed tmpl/default.php file ==== &amp;lt;!--T:123--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:124--&amp;gt; The complete &amp;lt;tt&amp;gt;tmpl/default.php&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    [PACKAGE_NAME]&lt;br /&gt;
 *&lt;br /&gt;
 * @author     [AUTHOR] &amp;lt;[AUTHOR_EMAIL]&amp;gt;&lt;br /&gt;
 * @copyright  [COPYRIGHT]&lt;br /&gt;
 * @license    GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 * @link       [AUTHOR_URL]&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
$domain = $params-&amp;gt;get(&#039;domain&#039;, &#039;https://www.joomla.org&#039;);&lt;br /&gt;
?&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;a href=&amp;quot;&amp;lt;?php echo $domain; ?&amp;gt;&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;?php echo &#039;[PROJECT_NAME]&#039; . $test; ?&amp;gt;&lt;br /&gt;
&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing language/en-GB/en-GB.mod_foo.ini === &amp;lt;!--T:125--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:126--&amp;gt; Here we can specify the text for the English version of the field label.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;MOD_FOO_FIELD_URL_LABEL=&amp;quot;Url&amp;quot;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed language/en-GB/en-GB.mod_foo.ini ==== &amp;lt;!--T:127--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:128--&amp;gt; The complete &amp;lt;tt&amp;gt;language/en-GB/en-GB.mod_foo.ini&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
MOD_FOO=&amp;quot;[PROJECT_NAME]&amp;quot;&lt;br /&gt;
MOD_FOO_XML_DESCRIPTION=&amp;quot;Foo Module&amp;quot;&lt;br /&gt;
MOD_FOO_FIELD_URL_LABEL=&amp;quot;Url&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Test Your Module == &amp;lt;!--T:129--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:130--&amp;gt; Now you can zip all files and install them via the Joomla Extension Manager.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:131--&amp;gt; After that you can choose your module in the module manager, when you create a new site module.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:132--&amp;gt; In the Backend, you will see your module like displayed in the next image.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:133--&amp;gt; In the basic tab, you will see the custom field where you can insert a domain. The text for the label is fetched from the language file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial31-&amp;lt;translate&amp;gt;&amp;lt;!--T:134--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:135--&amp;gt; In the advanced tab, you will see all default options except the cache mode because of this is a hidden field.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial32-&amp;lt;translate&amp;gt;&amp;lt;!--T:136--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:137--&amp;gt; In the Frontend, you will see your module like displayed in the next image. The text form your helper file is displayed and you should see a hyperlink.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial33-&amp;lt;translate&amp;gt;&amp;lt;!--T:138--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Conclusion == &amp;lt;!--T:139--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:140--&amp;gt; Form fields give the user an easy way to customize the module to their sites settings. This allows the modules scope to be increased.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:141--&amp;gt; You can find boilerplates hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla-extensions/boilerplate/tree/master/module&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:142--&amp;gt; The sample files for this Tutorial can be found hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/astridx/boilerplate/tree/tutorial/tutorial/modules&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:143--&amp;gt; See this issue for possible future changes:&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla/joomla-cms/pull/23553&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Use Install, Update and Uninstall Script == &amp;lt;!--T:144--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Requirements === &amp;lt;!--T:145--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:146--&amp;gt; You need Joomla! 4.x for this tutorial.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Scripts === &amp;lt;!--T:147--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:148--&amp;gt; Installing, updating and uninstalling a module may require additional operations that cannot be achieved by the basic operations described in the main XML file. Joomla offers a new approach to solve this problem. It consists in using a PHP script file containing a class using five methods:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:149--&amp;gt;&lt;br /&gt;
* preflight which is executed before install and update&lt;br /&gt;
* install&lt;br /&gt;
* update&lt;br /&gt;
* uninstall&lt;br /&gt;
* postflight which is executed after install and update&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:150--&amp;gt; Let&#039;s take a look how to use them in Joomla 4. We use the helper file for this.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== File Structure === &amp;lt;!--T:151--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:152--&amp;gt; We will create/change the following files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:153--&amp;gt;&lt;br /&gt;
* &amp;lt;tt&amp;gt;script.php&amp;lt;/tt&amp;gt; - This is the file we use here as an example. We have to create it.&lt;br /&gt;
* &amp;lt;tt&amp;gt;language/en-GB/en-GB.mod_foo.sys.ini&amp;lt;/tt&amp;gt; - In this file we will add text.&lt;br /&gt;
* &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; - We create a new file. This must be installed during the installation. For this we have to specify it in this file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating script.php === &amp;lt;!--T:154--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:155--&amp;gt; Writing an extension script consists in declaring a class whose name is &amp;lt;tt&amp;gt;mod_ModuleNameInstallerScript&amp;lt;/tt&amp;gt; with these 5 methods. See the comments in the file for more information. In this comments I explain when a method is called.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:156--&amp;gt; In this example, I only use text to show when which method will be executed. In addition, I show you how to check the minimum requirements. Of course you can do much more. For example, you can delete files that are no longer needed in a new version of your module. This can be seen in the file. Another idea for this file is to create sample content, to show a success message with the current installed version number or you can redirect after a successful installation to the page with the module settings.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed script.php ==== &amp;lt;!--T:157--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:158--&amp;gt; The complete &amp;lt;tt&amp;gt;script.php&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;?php&lt;br /&gt;
/**&lt;br /&gt;
 * @package    [PACKAGE_NAME]&lt;br /&gt;
 *&lt;br /&gt;
 * @author     [AUTHOR] &amp;lt;[AUTHOR_EMAIL]&amp;gt;&lt;br /&gt;
 * @copyright  [COPYRIGHT]&lt;br /&gt;
 * @license    GNU General Public License version 2 or later; see LICENSE.txt&lt;br /&gt;
 * @link       [AUTHOR_URL]&lt;br /&gt;
 */&lt;br /&gt;
&lt;br /&gt;
// No direct access to this file&lt;br /&gt;
defined(&#039;_JEXEC&#039;) or die;&lt;br /&gt;
&lt;br /&gt;
use Joomla\CMS\Language\Text;&lt;br /&gt;
use Joomla\CMS\Log\Log;&lt;br /&gt;
&lt;br /&gt;
/**&lt;br /&gt;
 * Script file of Foo module&lt;br /&gt;
 */&lt;br /&gt;
class mod_fooInstallerScript {&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Extension script constructor.&lt;br /&gt;
     *&lt;br /&gt;
     * @return  void&lt;br /&gt;
     */&lt;br /&gt;
    public function __construct() {&lt;br /&gt;
        $this-&amp;gt;minimumJoomla = &#039;4.0&#039;;&lt;br /&gt;
        $this-&amp;gt;minimumPhp = JOOMLA_MINIMUM_PHP;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Method to install the extension&lt;br /&gt;
     *&lt;br /&gt;
     * @param   InstallerAdapter  $parent  The class calling this method&lt;br /&gt;
     *&lt;br /&gt;
     * @return  boolean  True on success&lt;br /&gt;
     */&lt;br /&gt;
    function install($parent) {&lt;br /&gt;
        echo Text::_(&#039;MOD_FOO_INSTALLERSCRIPT_INSTALL&#039;);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Method to uninstall the extension&lt;br /&gt;
     *&lt;br /&gt;
     * @param   InstallerAdapter  $parent  The class calling this method&lt;br /&gt;
     *&lt;br /&gt;
     * @return  boolean  True on success&lt;br /&gt;
     */&lt;br /&gt;
    function uninstall($parent) {&lt;br /&gt;
        echo Text::_(&#039;MOD_FOO_INSTALLERSCRIPT_UNINSTALL&#039;);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Method to update the extension&lt;br /&gt;
     *&lt;br /&gt;
     * @param   InstallerAdapter  $parent  The class calling this method&lt;br /&gt;
     *&lt;br /&gt;
     * @return  boolean  True on success&lt;br /&gt;
     */&lt;br /&gt;
    function update($parent) {&lt;br /&gt;
        echo Text::_(&#039;MOD_FOO_INSTALLERSCRIPT_UPDATE&#039;);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Function called before extension installation/update/removal procedure commences&lt;br /&gt;
     *&lt;br /&gt;
     * @param   string            $type    The type of change (install, update or discover_install, not uninstall)&lt;br /&gt;
     * @param   InstallerAdapter  $parent  The class calling this method&lt;br /&gt;
     *&lt;br /&gt;
     * @return  boolean  True on success&lt;br /&gt;
     */&lt;br /&gt;
    function preflight($type, $parent) {&lt;br /&gt;
        // Check for the minimum PHP version before continuing&lt;br /&gt;
        if (!empty($this-&amp;gt;minimumPhp) &amp;amp;&amp;amp; version_compare(PHP_VERSION, $this-&amp;gt;minimumPhp, &#039;&amp;lt;&#039;)) {&lt;br /&gt;
            Log::add(Text::sprintf(&#039;JLIB_INSTALLER_MINIMUM_PHP&#039;, $this-&amp;gt;minimumPhp), Log::WARNING, &#039;jerror&#039;);&lt;br /&gt;
&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        // Check for the minimum Joomla version before continuing&lt;br /&gt;
        if (!empty($this-&amp;gt;minimumJoomla) &amp;amp;&amp;amp; version_compare(JVERSION, $this-&amp;gt;minimumJoomla, &#039;&amp;lt;&#039;)) {&lt;br /&gt;
            Log::add(Text::sprintf(&#039;JLIB_INSTALLER_MINIMUM_JOOMLA&#039;, $this-&amp;gt;minimumJoomla), Log::WARNING, &#039;jerror&#039;);&lt;br /&gt;
&lt;br /&gt;
            return false;&lt;br /&gt;
        }&lt;br /&gt;
&lt;br /&gt;
        echo Text::_(&#039;MOD_FOO_INSTALLERSCRIPT_PREFLIGHT&#039;);&lt;br /&gt;
        echo $this-&amp;gt;minimumJoomla . &#039; &#039; . $this-&amp;gt;minimumPhp;&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    /**&lt;br /&gt;
     * Function called after extension installation/update/removal procedure commences&lt;br /&gt;
     *&lt;br /&gt;
     * @param   string            $type    The type of change (install, update or discover_install, not uninstall)&lt;br /&gt;
     * @param   InstallerAdapter  $parent  The class calling this method&lt;br /&gt;
     *&lt;br /&gt;
     * @return  boolean  True on success&lt;br /&gt;
     */&lt;br /&gt;
    function postflight($type, $parent) {&lt;br /&gt;
        echo Text::_(&#039;MOD_FOO_INSTALLERSCRIPT_POSTFLIGHT&#039;);&lt;br /&gt;
&lt;br /&gt;
        return true;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing language/en-GB/en-GB.mod_foo.sys.ini === &amp;lt;!--T:159--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:160--&amp;gt; There is not much to explain here. Write the text for the translation into this file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed language/en-GB/en-GB.mod_foo.sys.ini file ==== &amp;lt;!--T:161--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:162--&amp;gt; The complete &amp;lt;tt&amp;gt;language/en-GB/en-GB.mod_foo.sys.ini&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
MOD_FOO=&amp;quot;[PROJECT_NAME]&amp;quot;&lt;br /&gt;
MOD_FOO_XML_DESCRIPTION=&amp;quot;Foo Module&amp;quot;&lt;br /&gt;
MOD_FOO_INSTALLERSCRIPT_PREFLIGHT=&amp;quot;&amp;lt;p&amp;gt;Anything here happens before the installation/update/uninstallation of the module&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;
MOD_FOO_INSTALLERSCRIPT_UPDATE=&amp;quot;&amp;lt;p&amp;gt;The module has been updated&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;
MOD_FOO_INSTALLERSCRIPT_UNINSTALL=&amp;quot;&amp;lt;p&amp;gt;The module has been uninstalled&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;
MOD_FOO_INSTALLERSCRIPT_INSTALL=&amp;quot;&amp;lt;p&amp;gt;The module has been installed&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;
MOD_FOO_INSTALLERSCRIPT_POSTFLIGHT=&amp;quot;&amp;lt;p&amp;gt;Anything here happens after the installation/update/uninstallation of the module&amp;lt;/p&amp;gt;&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Editing mod_foo.xml === &amp;lt;!--T:163--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:164--&amp;gt; You have to add a line, so that the script is called automatically in Joomla.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&amp;lt;scriptfile&amp;gt;script.php&amp;lt;/scriptfile&amp;gt;&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.xml ==== &amp;lt;!--T:165--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:166--&amp;gt; The complete &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;extension type=&amp;quot;module&amp;quot; version=&amp;quot;4.0&amp;quot; client=&amp;quot;site&amp;quot; method=&amp;quot;upgrade&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;MOD_FOO&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;creationDate&amp;gt;[DATE]&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
    &amp;lt;author&amp;gt;[AUTHOR]&amp;lt;/author&amp;gt;&lt;br /&gt;
    &amp;lt;authorEmail&amp;gt;[AUTHOR_EMAIL]&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
    &amp;lt;authorUrl&amp;gt;[AUTHOR_URL]&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
    &amp;lt;copyright&amp;gt;[COPYRIGHT]&amp;lt;/copyright&amp;gt;&lt;br /&gt;
    &amp;lt;license&amp;gt;GNU General Public License version 2 or later; see LICENSE.txt&amp;lt;/license&amp;gt;&lt;br /&gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;MOD_FOO_XML_DESCRIPTION&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;namespace&amp;gt;Joomla\Module\Foo&amp;lt;/namespace&amp;gt;&lt;br /&gt;
    &amp;lt;scriptfile&amp;gt;script.php&amp;lt;/scriptfile&amp;gt;&lt;br /&gt;
    &amp;lt;files&amp;gt;&lt;br /&gt;
        &amp;lt;filename module=&amp;quot;mod_foo&amp;quot;&amp;gt;mod_foo.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;tmpl&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;Helper&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;language&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;filename&amp;gt;mod_foo.xml&amp;lt;/filename&amp;gt;&lt;br /&gt;
    &amp;lt;/files&amp;gt;&lt;br /&gt;
    &amp;lt;config&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&lt;br /&gt;
                    name=&amp;quot;domain&amp;quot;&lt;br /&gt;
                    type=&amp;quot;url&amp;quot;&lt;br /&gt;
                    label=&amp;quot;MOD_FOO_FIELD_URL_LABEL&amp;quot;&lt;br /&gt;
                    filter=&amp;quot;url&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
            &amp;lt;/fieldset&amp;gt;&lt;br /&gt;
            &amp;lt;fieldset name=&amp;quot;advanced&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;layout&amp;quot;&lt;br /&gt;
                    type=&amp;quot;modulelayout&amp;quot;&lt;br /&gt;
                    label=&amp;quot;JFIELD_ALT_LAYOUT_LABEL&amp;quot;&lt;br /&gt;
                    class=&amp;quot;custom-select&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;moduleclass_sfx&amp;quot;&lt;br /&gt;
                    type=&amp;quot;textarea&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_MODULECLASS_SFX_LABEL&amp;quot;&lt;br /&gt;
                    rows=&amp;quot;3&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cache&amp;quot;&lt;br /&gt;
                    type=&amp;quot;list&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_CACHING_LABEL&amp;quot;&lt;br /&gt;
                    default=&amp;quot;0&amp;quot;&lt;br /&gt;
                &amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;JGLOBAL_USE_GLOBAL&amp;lt;/option&amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;0&amp;quot;&amp;gt;COM_MODULES_FIELD_VALUE_NOCACHING&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;/field&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cache_time&amp;quot;&lt;br /&gt;
                    type=&amp;quot;number&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_CACHE_TIME_LABEL&amp;quot;&lt;br /&gt;
                    default=&amp;quot;0&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cachemode&amp;quot;&lt;br /&gt;
                    type=&amp;quot;hidden&amp;quot;&lt;br /&gt;
                    default=&amp;quot;itemid&amp;quot;&lt;br /&gt;
                &amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;itemid&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;/field&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;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Test Your Module == &amp;lt;!--T:167--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:168--&amp;gt; Now you can zip all files and install them via the Joomla Extension Manager.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:169--&amp;gt; Immediately after the installation, you will see the following information. This you had entered in the script so.&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{-}}&lt;br /&gt;
[[File:moduletutorial14-&amp;lt;translate&amp;gt;&amp;lt;!--T:170--&amp;gt; en&amp;lt;/translate&amp;gt;.png|700px|center]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Conclusion == &amp;lt;!--T:171--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:172--&amp;gt; As you can see, Joomla offers you a lot to make your extension easy to use - right from the start.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:173--&amp;gt; You can find boilerplates hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla-extensions/boilerplate/tree/master/module&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:174--&amp;gt; The sample files for this Tutorial can be found hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/astridx/boilerplate/tree/tutorial/tutorial/modules&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Use Joomla Updaterː Adding Auto Update == &amp;lt;!--T:175--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Requirements === &amp;lt;!--T:176--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:177--&amp;gt; You need Joomla! 4.x for this tutorial.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Joomla Updater === &amp;lt;!--T:178--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:179--&amp;gt; The first thing to do is to read the [[S:MyLanguage/J2.5:Managing_Component_Updates|Managing Component Upgrades with Joomla 2.5 - Part 1]] tutorial to give an idea of how the upgrade process works in Joomlaǃ. Whilst written for 2.5 the process hasn&#039;t changed. Also read [[S:MyLanguage/Deploying_an_Update_Server|Deploying an update server]] - this is what we&#039;ll be implementing in this tutorial.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== File Structure === &amp;lt;!--T:180--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:181--&amp;gt; We will create/change the following files:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:182--&amp;gt; * &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; - The only way to update our existing module is to add in a update server - for example &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/foo_update.xml&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; - into the xml file.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:183--&amp;gt; * &amp;lt;tt&amp;gt;foo_update.xml&amp;lt;/tt&amp;gt; - Then we have to create the XML file for the update server at &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/foo_update.xml&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; to let Joomla know an update is available.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Editing mod_foo.xml ==== &amp;lt;!--T:184--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:185--&amp;gt; To add our update server, we need to insert the following lines in your XML-Fileː&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;php&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;updateservers&amp;gt;&lt;br /&gt;
    &amp;lt;server type=&amp;quot;extension&amp;quot; priority=&amp;quot;1&amp;quot; name=&amp;quot;[PROJECT_NAME]&amp;quot;&amp;gt;https://www.example.com/mod_foo.xml&amp;lt;/server&amp;gt;&lt;br /&gt;
&amp;lt;/updateservers&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed mod_foo.xml ==== &amp;lt;!--T:186--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:187--&amp;gt; The complete &amp;lt;tt&amp;gt;mod_foo.xml&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight 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;extension type=&amp;quot;module&amp;quot; version=&amp;quot;4.0&amp;quot; client=&amp;quot;site&amp;quot; method=&amp;quot;upgrade&amp;quot;&amp;gt;&lt;br /&gt;
    &amp;lt;name&amp;gt;MOD_FOO&amp;lt;/name&amp;gt;&lt;br /&gt;
    &amp;lt;creationDate&amp;gt;[DATE]&amp;lt;/creationDate&amp;gt;&lt;br /&gt;
    &amp;lt;author&amp;gt;[AUTHOR]&amp;lt;/author&amp;gt;&lt;br /&gt;
    &amp;lt;authorEmail&amp;gt;[AUTHOR_EMAIL]&amp;lt;/authorEmail&amp;gt;&lt;br /&gt;
    &amp;lt;authorUrl&amp;gt;[AUTHOR_URL]&amp;lt;/authorUrl&amp;gt;&lt;br /&gt;
    &amp;lt;copyright&amp;gt;[COPYRIGHT]&amp;lt;/copyright&amp;gt;&lt;br /&gt;
    &amp;lt;license&amp;gt;GNU General Public License version 2 or later; see LICENSE.txt&amp;lt;/license&amp;gt;&lt;br /&gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;&lt;br /&gt;
    &amp;lt;description&amp;gt;MOD_FOO_XML_DESCRIPTION&amp;lt;/description&amp;gt;&lt;br /&gt;
    &amp;lt;namespace&amp;gt;Joomla\Module\Foo&amp;lt;/namespace&amp;gt;&lt;br /&gt;
    &amp;lt;files&amp;gt;&lt;br /&gt;
        &amp;lt;filename module=&amp;quot;mod_foo&amp;quot;&amp;gt;mod_foo.php&amp;lt;/filename&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;tmpl&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;Helper&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;folder&amp;gt;language&amp;lt;/folder&amp;gt;&lt;br /&gt;
        &amp;lt;filename&amp;gt;mod_foo.xml&amp;lt;/filename&amp;gt;&lt;br /&gt;
    &amp;lt;/files&amp;gt;&lt;br /&gt;
    &amp;lt;updateservers&amp;gt;&lt;br /&gt;
        &amp;lt;server type=&amp;quot;extension&amp;quot; priority=&amp;quot;1&amp;quot; name=&amp;quot;[PROJECT_NAME]&amp;quot;&amp;gt;https://www.example.com/mod_foo.xml&amp;lt;/server&amp;gt;&lt;br /&gt;
    &amp;lt;/updateservers&amp;gt;&lt;br /&gt;
    &amp;lt;config&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&lt;br /&gt;
                    name=&amp;quot;domain&amp;quot;&lt;br /&gt;
                    type=&amp;quot;url&amp;quot;&lt;br /&gt;
                    label=&amp;quot;MOD_FOO_FIELD_URL_LABEL&amp;quot;&lt;br /&gt;
                    filter=&amp;quot;url&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
            &amp;lt;/fieldset&amp;gt;&lt;br /&gt;
            &amp;lt;fieldset name=&amp;quot;advanced&amp;quot;&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;layout&amp;quot;&lt;br /&gt;
                    type=&amp;quot;modulelayout&amp;quot;&lt;br /&gt;
                    label=&amp;quot;JFIELD_ALT_LAYOUT_LABEL&amp;quot;&lt;br /&gt;
                    class=&amp;quot;custom-select&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;moduleclass_sfx&amp;quot;&lt;br /&gt;
                    type=&amp;quot;textarea&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_MODULECLASS_SFX_LABEL&amp;quot;&lt;br /&gt;
                    rows=&amp;quot;3&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cache&amp;quot;&lt;br /&gt;
                    type=&amp;quot;list&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_CACHING_LABEL&amp;quot;&lt;br /&gt;
                    default=&amp;quot;0&amp;quot;&lt;br /&gt;
                &amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;1&amp;quot;&amp;gt;JGLOBAL_USE_GLOBAL&amp;lt;/option&amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;0&amp;quot;&amp;gt;COM_MODULES_FIELD_VALUE_NOCACHING&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;/field&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cache_time&amp;quot;&lt;br /&gt;
                    type=&amp;quot;number&amp;quot;&lt;br /&gt;
                    label=&amp;quot;COM_MODULES_FIELD_CACHE_TIME_LABEL&amp;quot;&lt;br /&gt;
                    default=&amp;quot;0&amp;quot;&lt;br /&gt;
                /&amp;gt;&lt;br /&gt;
                &amp;lt;field&lt;br /&gt;
                    name=&amp;quot;cachemode&amp;quot;&lt;br /&gt;
                    type=&amp;quot;hidden&amp;quot;&lt;br /&gt;
                    default=&amp;quot;itemid&amp;quot;&lt;br /&gt;
                &amp;gt;&lt;br /&gt;
                    &amp;lt;option value=&amp;quot;itemid&amp;quot;&amp;gt;&amp;lt;/option&amp;gt;&lt;br /&gt;
                &amp;lt;/field&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;/extension&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:188--&amp;gt; Now that Joomlaǃ is searching for updates to our extension, let&#039;s create one to test our process. First we need to create the file &amp;lt;tt&amp;gt;foo_update.xml&amp;lt;/tt&amp;gt;. So far we have only described the update server. We do not know yet if there is an update. In the file &amp;lt;tt&amp;gt;foo_update.xml&amp;lt;/tt&amp;gt; we indicate when a new version is published and where it can be downloaded.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Creating foo_update.xml === &amp;lt;!--T:189--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:190--&amp;gt; Now we have to create the XML file at &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/foo_update.xml&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; to let Joomla know an update is available.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Completed foo_update.xml ==== &amp;lt;!--T:191--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:192--&amp;gt; The complete &amp;lt;tt&amp;gt;foo_update.xml&amp;lt;/tt&amp;gt; file is as follows:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; ?&amp;gt;&lt;br /&gt;
&amp;lt;updates&amp;gt;&lt;br /&gt;
    &amp;lt;update&amp;gt;&lt;br /&gt;
        &amp;lt;name&amp;gt;Foo&amp;lt;/name&amp;gt;&lt;br /&gt;
        &amp;lt;description&amp;gt;This is mod_foo 1.0.1&amp;lt;/description&amp;gt;&lt;br /&gt;
        &amp;lt;element&amp;gt;mod_foo&amp;lt;/element&amp;gt;&lt;br /&gt;
        &amp;lt;type&amp;gt;module&amp;lt;/type&amp;gt;&lt;br /&gt;
        &amp;lt;version&amp;gt;1.0.1&amp;lt;/version&amp;gt;&lt;br /&gt;
        &amp;lt;downloads&amp;gt;&lt;br /&gt;
            &amp;lt;downloadurl type=&amp;quot;full&amp;quot; format=&amp;quot;zip&amp;quot;&amp;gt;http://www.example.com/mod_foo_101.zip&amp;lt;/downloadurl&amp;gt;&lt;br /&gt;
        &amp;lt;/downloads&amp;gt;&lt;br /&gt;
        &amp;lt;maintainer&amp;gt;Joomla&amp;lt;/maintainer&amp;gt;&lt;br /&gt;
        &amp;lt;maintainerurl&amp;gt;http://www.example.com&amp;lt;/maintainerurl&amp;gt;&lt;br /&gt;
        &amp;lt;targetplatform name=&amp;quot;joomla&amp;quot; version=&amp;quot;4.0&amp;quot;/&amp;gt;&lt;br /&gt;
        &amp;lt;client&amp;gt;site&amp;lt;/client&amp;gt;&lt;br /&gt;
    &amp;lt;/update&amp;gt;&lt;br /&gt;
&amp;lt;/updates&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:193--&amp;gt; After uploading this file to the address &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;https://www.example.com/mod_foo.xml&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; the update will be displayed in the Joomla Backend.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Test Your Module Update === &amp;lt;!--T:194--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:195--&amp;gt; Create a copy of the module as it is now. Then let&#039;s update the version number to 1.0.1. Now you can zip all files. After that you should load your zip to the URL &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;http://www.example.com/mod_foo_101.zip&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt;. Now you can update your module via the Joomla Updater.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Commercial Modules === &amp;lt;!--T:196--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:197--&amp;gt; Note that in our files we have linked to the extensions updates xml file. And from that xml file we have a location for the zip of the module. This means that if someone was to track this backwards they could find the physical source of your modules zip file. If you don&#039;t do like this, you can find a solution in this PRː https://github.com/joomla/joomla-cms/pull/15185 .&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Conclusion === &amp;lt;!--T:198--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:199--&amp;gt; With the Joomlaǃ updater, you can easily reach all users and tell them that there is a new version. Even the update itself is easy.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:200--&amp;gt; Each extension should use an update server--especially for security reasons.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:201--&amp;gt; You can find boilerplates hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/joomla-extensions/boilerplate/tree/master/module&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:202--&amp;gt; The sample files for this Tutorial can be found hereː&amp;lt;/translate&amp;gt;&lt;br /&gt;
* https://github.com/astridx/boilerplate/tree/tutorial/tutorial/modules&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
[[Category:Beginner Development{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials in a Series{{#translation:}}]]&lt;br /&gt;
[[Category:Development{{#translation:}}]]&lt;br /&gt;
[[Category:Module Development{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.0{{#translation:}}]]&lt;br /&gt;
&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Using_Tag_Manager&amp;diff=1001049</id>
		<title>Using Tag Manager</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Using_Tag_Manager&amp;diff=1001049"/>
		<updated>2023-04-15T18:10:00Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup changes. URL corrections.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==What is the Google Tag Manager?==&lt;br /&gt;
The Google Tag Manager is a way to combine all your tracking and marketing scripts into one, version-controlled container which is inserted into your site, calling a single file instead of multiple files that can slow your site down.&lt;br /&gt;
&lt;br /&gt;
It also allows you to fire specific tags—such as conversion tags—on specific pages, without having to edit the code of the component or extension that powers the page.&lt;br /&gt;
&lt;br /&gt;
==Configuring the Google Tag Manager==&lt;br /&gt;
Before you can use the Google Tag Manager you must [https://marketingplatform.google.com/about/tag-manager/ sign up].&lt;br /&gt;
&lt;br /&gt;
Once you have a Google Tag Manager account, you&#039;ll log in and see the dashboard from which you can create a new account.&lt;br /&gt;
&lt;br /&gt;
Generally you should create a new account for each client you work with. One account can have multiple containers and many users with these levels of access:&lt;br /&gt;
&lt;br /&gt;
# View only&lt;br /&gt;
# View and edit&lt;br /&gt;
# View, edit, delete and publish&lt;br /&gt;
&lt;br /&gt;
==Installing Tag Manager on Your Joomla Website==&lt;br /&gt;
&lt;br /&gt;
Inserting Google Tag Manager into your website requires either editing your template file or using an extension to insert the container in the correct location.&lt;br /&gt;
&lt;br /&gt;
There are pros and cons for both approaches. Inserting into the template requires you to edit the code of the &#039;&#039;index.php&#039;&#039; file. However it means it&#039;s not easy to remove or unpublish accidentally. Using a plugin requires an additional call on page load, and can potentially have compatibility issues if code changes are necessary.&lt;br /&gt;
&lt;br /&gt;
===Google Tag Manager Extensions===&lt;br /&gt;
There are several extensions you can use to embed the Google Tag Manager code. Browse them on the [https://extensions.joomla.org/ Joomla! Extensions Directory™].&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_1.5_to_4.x_Step_by_Step_Migration&amp;diff=999383</id>
		<title>Joomla 1.5 to 4.x Step by Step Migration</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_1.5_to_4.x_Step_by_Step_Migration&amp;diff=999383"/>
		<updated>2023-02-20T19:12:59Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Expanded Migration Tool section.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
The following are step-by-step instructions to migrate your 1.5 site to Joomla 4.x. While there are many ways to migrate your site, this will give you the basic procedure to follow.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Introduction == &amp;lt;!--T:2--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The migration from Joomla! 1.5 to 4.x is a major migration. There are many changes in features and database tables between these two versions. It is &#039;&#039;&#039;not&#039;&#039;&#039; a one-click update. You will be building and installing a fresh Joomla! 4 installation and then migrating (moving) your data into it. If you haven&#039;t already, you may want to start with the [[S:MyLanguage/Migration Step by Step Self Assessment|Self Assessment]] and [[S:MyLanguage/Planning Migration - Joomla 1.5 to 3|Planning]] documents.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
Let’s first distinguish between Joomla Core data and third-party extension data. Joomla Core data (Components) are:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
* Categories&lt;br /&gt;
* Articles&lt;br /&gt;
* Menus&lt;br /&gt;
* Modules (core modules - not third-party)&lt;br /&gt;
* Banners&lt;br /&gt;
* Contacts&lt;br /&gt;
* Messaging&lt;br /&gt;
* News Feeds&lt;br /&gt;
* Redirect&lt;br /&gt;
* Search&lt;br /&gt;
* Smart Search&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Step-by-Step == &amp;lt;!--T:6--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
Moving Joomla core data is fairly straight-forward with the use of a migration tool. Everything else is a third-party extension or a custom built extension. This includes the template. Each third-party extension needs to be researched to determine if it’s ready for Joomla 4.x and has a migration path. You may have done this in the [[S:MyLanguage/Planning Migration - Joomla 1.5 to 3|planning]] process. If not, do it now. Some third-party extensions can be migrated with a third-party tool. Some cannot. Read. Research. Plan.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
Since there are many ways to migrate data and each site is different, the exact steps are going to be slightly different for every site.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Prepare a Location for Joomla 4 === &amp;lt;!--T:9--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt;&lt;br /&gt;
# Make sure your server environment meets the [https://downloads.joomla.org/technical-requirements technical requirements for Joomla! 4] before proceeding.&amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; If your host does not meet the technical requirements, you will need to change hosts. If you need to change hosts, set up a new hosting account on a host that meets the specifications and install your fresh Joomla 4.x site in the root of the server on a temporary domain. This will make it easier when it’s time to go live. Alternatively, you can set up a development location on a local device. (See below.)&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
# {{anchor|new-j3-database}}&amp;lt;translate&amp;gt;&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
Create a new database and new user for your Joomla! 4.x site. Document the database name, database username and database password as you’ll need these when you [[#install-j3|install Joomla 4]]&amp;lt;/translate&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Set Up a Development Location === &amp;lt;!--T:12--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
# Create a testing site or build area to work in with one of the following:&lt;br /&gt;
#* A subdomain&lt;br /&gt;
#* A subdirectory&lt;br /&gt;
#* A local device via [https://www.wampserver.com/en/ WAMP], [https://www.mamp.info/en/windows/ MAMP], [https://sourceforge.net/projects/lampas/ LAMP], [https://sourceforge.net/projects/xampp/ XAMPP].&lt;br /&gt;
#* A new hosting account on a temporary domain in the root (if you would like to change hosts in the process of migration)&lt;br /&gt;
#**Restoring a site on a local device. See [[S:MyLanguage/Installing Joomla locally|Installing Joomla locally]] and [[S:MyLanguage/Setting up your workstation for Joomla development|Setting up your workstation for Joomla development]].&lt;br /&gt;
#**Restoring a site with Akeeba Backup. (Read the developer documentation or videos for how to restore a backup of an Akeeba Backup file.)&#039;&#039;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
# {{anchor|install-j3}}[[S:MyLanguage/J3.x:Installing_Joomla|Install a fresh installation]] of the [https://downloads.joomla.org/ latest version of Joomla 4.x] into your testing site location using your new database name and database credentials. &amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Warning&#039;&#039;&#039; Do &#039;&#039;&#039;not&#039;&#039;&#039; install the sample data.&amp;lt;/translate&amp;gt;|type=serious}}{{-}}{{note|&amp;lt;translate&amp;gt;&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; If you will be migrating any of the core extensions that will be decoupled from Joomla! 3.4+, you will need to install Joomla 4.x &#039;&#039;&#039;and&#039;&#039;&#039; the core supported extension. Core supported extensions will be accessible via the [https://extensions.joomla.org/ Joomla Extensions Directory] and via the Install from web tab of the Extension Manager. Make sure you install any core supported extensions before migrating data. See the [https://developer.joomla.org/roadmap.html Project Roadmap] for more details on what will be decoupled/removed. As of August 2021, only Web Links has been decoupled.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
# Run a backup of your Joomla 4 site. ([[S:MyLanguage/Backup_Basics_for_a_Joomla!_Web_Site|Backup Basics for a Joomla! Web Site]] or see [[#Suggested Tools|Suggested Tools]])&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Prepare Your Current 1.5 Site === &amp;lt;!--T:18--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
# On your 1.5 site, update it to the latest version 1.5.26 after backing it up.&lt;br /&gt;
# Clean up your sections, categories, articles, modules, menu items. Make sure they all have unique aliases.&lt;br /&gt;
# Empty the trash in the content manager (sections, categories, articles), menu manager, module manager.&amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; Sections no longer exist in Joomla 4. Sections become a parent Category. Categories became nested categories of the parent category.&amp;lt;/translate&amp;gt;}}{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
# Notify users that any changes on the current site from this point forward will have to be reentered on the new site. For complex migrations with changing data, see the [https://magazine.joomla.org/all-issues/issue-march-2014/complex-joomla-15-migration-with-minimal-downtime Complex Joomla! 1.5 Migration With Minimal Downtime] magazine article and the [https://www.youtube.com/watch?v=lPwcWaKB6dY&amp;amp;list=UUy6ThiEDnalZOd_pgtpBk1Q&amp;amp;index=7 Complex Migrations video].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Choose a Migration Tool === &amp;lt;!--T:22--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
# There are many migration tools. Some are free, some cost a bit of money. Some only migrate certain data. Some migrate more types of data than others.&lt;br /&gt;
# Migration tools can be found at the [https://extensions.joomla.org/category/migration-a-conversion/ Migration &amp;amp; Conversion category] in the Joomla Extension Directory.&lt;br /&gt;
# Verify that the candidate migration tool has been updated to work with Joomla 4.&lt;br /&gt;
# Each migration tool has its own step-by-step documentation on how to move data. (If they don’t don’t use it.) Some migration tools will require the 1.5 site and 4 site on the same server. If you’re switching hosts, you will want to restore a *subdomain* of your 1.5 site on your new hosting account to pull the data from. Then kill it when you’re done.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
# When you choose a tool, select one that allows you to preserve the ItemIDs. This is necessary to keep your search engine ranking intact or you may have more redirects to do. More information on redirects follow.&lt;br /&gt;
# If you have a small site, you may want to do the migration manually. Create categories and articles and copy the HTML over into your new site. Then copy the image directory over. Keep the &#039;&#039;/stories&#039;&#039; directory (which is no longer the default image directory in Joomla 4.x) or your image links will be broken until you fix each one.&lt;br /&gt;
# One of the migration tools (a free one) allows you to bring articles and only images associated with those articles over. This is helpful if your Media Manager is out of control.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;=== Migration === &amp;lt;!--T:25--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
# Migrate all core data you want to move to Joomla 4.x. If your migration tool asks to move Sections and Categories, definitely do both. The conversion will happen to categories and nested categories automatically.&lt;br /&gt;
# Run the Database Fix by going to {{rarr|Extension Manager,Database}} and click the &#039;&#039;Fix&#039;&#039; button in the top toolbar.&lt;br /&gt;
# Install your new template or converted template so that you can see your content. See more about [[S:MyLanguage/Template_Considerations_During_Migration|Template Considerations]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
# Add new menus if the tool you chose to use didn&#039;t bring over menus. If you want to use [[S:MyLanguage/Split_menus|split menus]], set that up now.&lt;br /&gt;
# Add modules if the tool you chose to use didn&#039;t bring over modules. If the tool you chose to use brought over modules, change the module positions to the positions in your new template if required so that your modules show up and you can see what you’re working with.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:28--&amp;gt;&lt;br /&gt;
# Check for duplicate alias issues and fix them.&lt;br /&gt;
# Check your internal links. If any are broken, fix them.&lt;br /&gt;
# Take a backup.&lt;br /&gt;
# Install other third-party extensions and configure them. (For example editors, Akeeba backup, slideshows, or plugins.)&lt;br /&gt;
# Take a backup.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
# If you have large extensions with data to migrate, do each one according to the developer documentation and then take a backup after each one.&lt;br /&gt;
# If your migration tool didn&#039;t move the images, you will want to move your images from the 1.5 site to the 4.x site. Note: keep the &#039;&#039;/stories&#039;&#039; directory unless you want to relink all your images. You can start a new organisational structure in the &#039;&#039;/images&#039;&#039; directory from here forward if stories is a mess.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
# Recommended but not required unless you have issues: [[S:MyLanguage/Fixing_the_assets_table|Fix asset issues]]. See [[#Suggested_Tools|below for a helpful tool]].&lt;br /&gt;
# If you are going to add anything to your site or use new core features such as Tags or Custom Fields, get them set up and configured at this time.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
# Check your URLs on the Joomla 4 site and compare to the Joomla 1.5 site. If they are different, document each 1.5 URL and what Joomla 4.x URL they will be going to so that you can do redirects and keep your ranking. (An Excel spreadsheet is helpful.) See:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
#*[https://magazine.joomla.org/all-issues/issue-april-2014/migration-seo-tips-series-part-1-planning-your-link-migration-strategy Migration SEO Tips Series - Part 1 - Planning Your Link Migration Strategy]; and&lt;br /&gt;
#*[https://magazine.joomla.org/all-issues/issue-may-2014/migration-seo-tips-series-part-2-monitoring-your-migrated-site-health Migration SEO Tips Series - Part 2 - Monitoring Your Migrated Site&#039;s Health].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
# Take a backup.&lt;br /&gt;
# Check everything.&lt;br /&gt;
# Clean up more.&lt;br /&gt;
# Test everything.&lt;br /&gt;
# Take a backup.&lt;br /&gt;
# Move or change or add updated data from the 1.5 site to the Joomla 4 site.&lt;br /&gt;
# Add Google Analytics to the template or use a third-party plugin.&lt;br /&gt;
# Check the Global Configuration and make sure all is as it should be.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
# Take a final backup of the Joomla 4.x site.&lt;br /&gt;
# Take a final backup of the 1.5 site.&lt;br /&gt;
# Move your 1.5 site from the root to another subdomain or subdirectory or simply delete it. (This is so that you have it again for a brief time if you need to refer to it.)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt;&lt;br /&gt;
# Backup and restore using a suggested tool (below) or simply move files to restore your 4.x site to the root of your hosting.&amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; If you are changing hosts, you can leave your Joomla 4.x site where it is and simply change name servers on the domain to make it live. Make sure you&#039;ve addressed any email issues first.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt;&lt;br /&gt;
# Enable &#039;&#039;.htaccess&#039;&#039; if necessary for Search Engine Friendly URLs.&lt;br /&gt;
# Create a sitemap and submit to Google Webmaster Tools or any other search engine you would like.&lt;br /&gt;
# Do all your redirects from the spreadsheet you created earlier for URLs that changed in the migration process.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt;&lt;br /&gt;
# Make any other changes that needed to wait until the 4.x site was live.&lt;br /&gt;
# Test again.&lt;br /&gt;
# Take another backup.&lt;br /&gt;
# Kill any instance(s) of the 1.5 site as soon as possible.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt;&lt;br /&gt;
# Remove all other development sites you may have been working with or keep them up-to-date if they are running a current version in order to ward off hack attempts on your server.&lt;br /&gt;
# Welcome to Joomla! 4.x!&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;== Suggested Tools == &amp;lt;!--T:40--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
*[https://extensions.joomla.org/extension/access-a-security/site-security/akeeba-backup Akeeba Backup] for backup and restore.&lt;br /&gt;
*[https://extensions.joomla.org/extension/access-a-security/site-access/acl-manager ACL Manager] to fix asset issues in a few clicks.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:42--&amp;gt;&lt;br /&gt;
[[Category:Migration]]&lt;br /&gt;
[[Category:Tutorials]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Smart_Search_quickstart_guide&amp;diff=999361</id>
		<title>Smart Search quickstart guide</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Smart_Search_quickstart_guide&amp;diff=999361"/>
		<updated>2023-02-20T02:16:09Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Markup changes including right arrow markup. Changes for Words2Watch compliance.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{version|2.5}}&lt;br /&gt;
==Enabling the Smart Search Content Plugin==&lt;br /&gt;
Smart Search is not enabled by default. To start using Smart Search, enable the Smart Search content Plugin:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the {{rarr|Extensions,Plugin Manager}} menu item.&lt;br /&gt;
# Filter the Plugin list so that only content Plugins are shown by selecting &#039;&#039;content&#039;&#039; from the &#039;&#039;Select Type&#039;&#039; filter drop-down.&lt;br /&gt;
# Find &#039;&#039;Content - Smart Search&#039;&#039; on the list of Plugins.&lt;br /&gt;
# Click on the red circle icon in the Status column for the Smart Search Plugin. The red circle should change to a green tick indicating that the Plugin is now enabled.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; If you have content items that are not available for public view then the auto-completion feature will still show terms contained in those content items. The content items themselves cannot be viewed and will not be listed in search results, but if revealing the presence of a word or phrase in a restricted content item is of concern you should disable auto-completion. To disable auto-completion:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on {{rarr|Components,Smart Search}}.&lt;br /&gt;
# Click on the &#039;&#039;Options&#039;&#039; toolbar button.&lt;br /&gt;
# Change &#039;&#039;Search Suggestions&#039;&#039; from &#039;&#039;Show&#039;&#039; to &#039;&#039;Hide&#039;&#039;.&lt;br /&gt;
# Click &#039;&#039;Save and Close&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Preparing Smart Search Plugins==&lt;br /&gt;
For content to be displayed in search results it must first be indexed by one of the Smart Search Plugins. Before starting the indexer, it is recommended that you review the available Plugins and disable any that will not be necessary for your site. To review the available Smart Search Plugins use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the {{rarr|Extensions,PluginManager menu item}}.&lt;br /&gt;
# Filter the Plugin list so that only Smart Search Plugins are shown by selecting &#039;&#039;finder&#039;&#039; from the &#039;&#039;Select Type&#039;&#039; filter drop-down.&lt;br /&gt;
# Review the list of Plugins and disable any that will not be necessary for your site by clicking on the green tick icon in the Status column for the Plugin. This should change to a red circle to indicate that the Plugin is disabled.&lt;br /&gt;
&lt;br /&gt;
==Running the Indexer==&lt;br /&gt;
After you have reviewed the search Plugins, it is time to start the Smart Search indexer. This will scan the content on your website and build an index that will enable fast and intelligent searching by your site visitors. To run the indexer use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the {{rarr|Components,Smart Search menu item}}.&lt;br /&gt;
# Click on the Index button in the toolbar to start the indexer. This will cause a modal window to load with some indexer status information and a progress bar. Depending on the size of your site, this can take a few minutes to a few hours to complete. The indexer uses AJAX requests to complete the overall process in small chunks so as to avoid timeouts and memory problems. Indexing is complete when the progress bar disappears and you see a message indicating that it is now safe to close the modal window.&lt;br /&gt;
&lt;br /&gt;
Once the indexer has finished, closing the modal window will cause the Indexed Content screen in the background to refresh with an updated list of all the indexed content. If you would prefer that specific items not be displayed in search results, you can unpublish them from the Smart Search database by selecting the checkbox next to the title of the item and then pressing the Unpublish button. For more information on the Indexed Content screen see the [[Help25:Components Finder Manage Indexed Content|Manage Indexed Content help screen]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; If your site has a large amount of content, or particularly large content items, or has restricted disk space, you should read about [[Smart Search on large sites]].&lt;br /&gt;
&lt;br /&gt;
==Exposing Smart Search to Site Users==&lt;br /&gt;
Now that the Smart Search index is prepared and ready, you need to expose Smart Search to your website&#039;s users. Smart Search offers two ways to do this:&lt;br /&gt;
&lt;br /&gt;
===The Module Interface===&lt;br /&gt;
Smart Search includes a module that can be enabled to display a simple search form on any page in virtually any position. To enable the Smart Search module use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the {{rarr|Extensions,Module Manager menu item}}.&lt;br /&gt;
# Click the New button in the Module Manager toolbar.&lt;br /&gt;
# Select &#039;&#039;Smart Search Module&#039;&#039; from the list of module types shown.&lt;br /&gt;
# Configure the module by (at least) entering a title, selecting the module position, and adjusting the pages for it to display on if desired. Additional module configuration options are described on the [[Help25:Extensions Module Manager Smart Search|Smart Search module help screen]].&lt;br /&gt;
# Click on the Save button in the toolbar to publish the module.&lt;br /&gt;
&lt;br /&gt;
===The Component Interface===&lt;br /&gt;
Smart Search can also be linked to via a Joomla menu item so that users can navigate directly to the main search form. To create a menu item link to Smart Search use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the {{rarr|Extensions,Module Manager menu item}}.&lt;br /&gt;
# Press the New button in the Menu Manager toolbar.&lt;br /&gt;
# Click the Select button next to the Menu Item Type field.&lt;br /&gt;
# Click on &#039;&#039;Search&#039;&#039; under the &#039;&#039;Smart Search&#039;&#039; entry on the list of menu item types shown.&lt;br /&gt;
# Configure the menu item by (at least) entering a Menu Title and adjusting the parent item if desired.&lt;br /&gt;
# Click on the Save button in the toolbar to publish the menu item.&lt;br /&gt;
&lt;br /&gt;
==Testing, Testing, Testing==&lt;br /&gt;
To test Smart Search, navigate to one of the menu items you created and enter a query in the search form or enter a query into one of the instances of Smart Search module. You should be taken to a list of search results if any could be found for the word or phrase you entered. If no results could be found, a message will be displayed indicating no results. If no results could be found and the system has a search suggestion based on your term, the suggested search phrase will display above the message indicating no results.&lt;br /&gt;
&lt;br /&gt;
==Finalizing the Switch==&lt;br /&gt;
To finalize the switch to Smart Search, remove all instances of &#039;&#039;mod_search&#039;&#039; and all menu items linking to &#039;&#039;com_search&#039;&#039;. Smart Search does not interact with the old Joomla search system and exposing both systems may create a negative user experience by giving inconsistent and confusing search results.&lt;br /&gt;
&lt;br /&gt;
==Removing Joomla Search Modules==&lt;br /&gt;
If you have the old Joomla search still available then you will probably want to remove it once you have Smart Search running correctly. To remove old Joomla search modules, use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the desired menu under the Menus menu item.&lt;br /&gt;
# Filter the modules listed so that only search modules are shown by selecting &#039;&#039;Search&#039;&#039; from the &#039;&#039;Select Type&#039;&#039; filter drop-down. If no such modules are listed then there are no instances of the old search available and you can skip this part.&lt;br /&gt;
# Select the checkbox at the top of the table to select all of the items in the list. Once all the instances of the old search have been selected, press the Delete button in the Module Manager toolbar. Be careful that you do not accidentally delete any other modules in the process.&lt;br /&gt;
&lt;br /&gt;
==Removing Joomla Search Menu Items==&lt;br /&gt;
Unfortunately, there is no quick and easy way to remove all links to the old Joomla search system. To remove all the menu items to the old Joomla search system you will have to browse the menu items in each of your site&#039;s menus and manually remove the links. To make this process somewhat quicker, adjust the order of the table to list menu items by type in reverse alphabetical order. Now scroll down and look for links with type &#039;&#039;Search &amp;gt;&amp;gt; Search&#039;&#039;. Delete those menu items by checking the checkbox to the left of the title and then pressing the Delete button in the Menu Manager toolbar.&lt;br /&gt;
&lt;br /&gt;
[[Category:Smart Search]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Smart_Search_quickstart_guide&amp;diff=999360</id>
		<title>Smart Search quickstart guide</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Smart_Search_quickstart_guide&amp;diff=999360"/>
		<updated>2023-02-19T16:57:11Z</updated>

		<summary type="html">&lt;p&gt;Cmb: /* Enabling the Smart Search content plug-in */ Words2Watch and markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{version|2.5}}&lt;br /&gt;
==Enabling the Smart Search Content Plugin==&lt;br /&gt;
Smart Search is not enabled by default. To start using Smart Search, enable the Smart Search content Plugin:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the {{rarr|Extensions,Plugin Manager}} menu item.&lt;br /&gt;
# Filter the Plugin list so that only content Plugins are shown by selecting &#039;&#039;content&#039;&#039; from the &#039;&#039;Select Type&#039;&#039; filter drop-down.&lt;br /&gt;
# Find &#039;&#039;Content - Smart Search&#039;&#039; on the list of Plugins.&lt;br /&gt;
# Click on the red circle icon in the Status column for the Smart Search Plugin. The red circle should change to a green tick indicating that the Plugin is now enabled.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Note&#039;&#039;&#039; If you have content items that are not available for public view then the auto-completion feature will still show terms contained in those content items. The content items themselves cannot be viewed and will not be listed in search results, but if revealing the presence of a word or phrase in a restricted content item is of concern you should disable auto-completion. To disable auto-completion:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on {{rarr|Components,Smart Search}}.&lt;br /&gt;
# Click on the &#039;&#039;Options&#039;&#039; toolbar button.&lt;br /&gt;
# Change &#039;&#039;Search Suggestions&#039;&#039; from &#039;&#039;Show&#039;&#039; to &#039;&#039;Hide&#039;&#039;.&lt;br /&gt;
# Click &#039;&#039;Save and Close&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==Preparing Smart Search plug-ins==&lt;br /&gt;
For content to be displayed in search results it must first be indexed by one of the Smart Search plug-ins. Before starting the indexer, it is recommended that you review the available plug-ins and disable any that will not be necessary for your site. To review the available Smart Search plug-ins use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the Extensions → Plug-in Manager menu item.&lt;br /&gt;
# Filter the plug-in list so that only Smart Search plug-ins are shown by selecting &amp;quot;finder&amp;quot; from the &amp;quot;Select Type&amp;quot; filter drop-down.&lt;br /&gt;
# Review the list of plug-ins and disable any that will not be necessary for your site by clicking on the green tick icon in the Status column for the plug-in. This should change to a red circle to indicate that the plug-in is disabled.&lt;br /&gt;
&lt;br /&gt;
==Running the Indexer==&lt;br /&gt;
After you have reviewed the search plug-ins, it is time to start the Smart Search indexer. This will scan the content on your Website and build an index that will enable fast and intelligent searching by your site visitors. To run the indexer use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the Components → Smart Search menu item.&lt;br /&gt;
# Click on the Index button in the toolbar to start the indexer. This will cause a modal window to load with some indexer status information and a progress bar. Depending on the size of your site, this can take a few minutes to a few hours to complete. The indexer uses AJAX requests to complete the overall process in small chunks so as to avoid timeouts and memory problems. Indexing is complete when the progress bar disappears and you see a message indicating that it is now safe to close the modal window.&lt;br /&gt;
&lt;br /&gt;
Once the indexer has finished, closing the modal window will cause the Indexed Content screen in the background to refresh with an updated list of all the indexed content. If you would prefer that specific items not be displayed in search results, you can unpublish them from the Smart Search database by selecting the checkbox next to the title of the item and then pressing the Unpublish button. For more information on the Indexed Content screen see the [[Help25:Components Finder Manage Indexed Content|Manage Indexed Content help screen]].&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;IMPORTANT NOTE&#039;&#039;&#039;: If your site has a large amount of content, or particularly large content items, or has restricted disk space, you should read about [[Smart Search on large sites]].&lt;br /&gt;
&lt;br /&gt;
==Exposing Smart Search to Site Users==&lt;br /&gt;
Now that the Smart Search index is prepared and ready, you need to expose Smart Search to your Website&#039;s users. Smart Search offers two ways to do this:&lt;br /&gt;
&lt;br /&gt;
===The Module Interface===&lt;br /&gt;
Smart Search includes a module that can be enabled to display a simple search form on any page in virtually any position. To enable the Smart Search module use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the Extensions → Module Manager menu item.&lt;br /&gt;
# Click the New button in the Module Manager toolbar.&lt;br /&gt;
# Select &amp;quot;Smart Search Module&amp;quot; from the list of module types shown.&lt;br /&gt;
# Configure the module by (at least) entering a title, selecting the module position, and adjusting the pages for it to display on if desired. Additional module configuration options are described on the [[Help25:Extensions Module Manager Smart Search|Smart Search module help screen]].&lt;br /&gt;
# Click on the Save button in the toolbar to publish the module.&lt;br /&gt;
&lt;br /&gt;
===The Component Interface===&lt;br /&gt;
Smart Search can also be linked to via a Joomla menu item so that users can navigate directly to the main search form. To create a menu item link to Smart Search use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the Extensions → Module Manager menu item.&lt;br /&gt;
# Press the New button in the Menu Manager toolbar.&lt;br /&gt;
# Click the Select button next to the Menu Item Type field.&lt;br /&gt;
# Click on &amp;quot;Search&amp;quot; under the &amp;quot;Smart Search&amp;quot; entry on the list of menu item types shown.&lt;br /&gt;
# Configure the menu item by (at least) entering a Menu Title and adjusting the parent item if desired.&lt;br /&gt;
# Click on the Save button in the toolbar to publish the menu item.&lt;br /&gt;
&lt;br /&gt;
==Testing, Testing, Testing==&lt;br /&gt;
To test Smart Search, navigate to one of the menu items you created and enter a query in the search form or enter a query into one of the instances of Smart Search module. You should be taken to a list of search results if any could be found for the word or phrase you entered. If no results could be found, a message will be displayed indicating that no results could be found. If no results could be found and the system has a search suggestion based on your term, the suggested search phrase will display above the message indicating no results could be found.&lt;br /&gt;
&lt;br /&gt;
==Finalizing the Switch==&lt;br /&gt;
To finalize the switch to Smart Search, you should remove all instances of mod_search and all menu items linking to com_search. Smart Search does not interact with the old Joomla search system and exposing both systems may create a negative user experience by giving inconsistent and confusing search results.&lt;br /&gt;
&lt;br /&gt;
==Removing Joomla Search Modules==&lt;br /&gt;
If you have the old Joomla search still available then you will probably want to remove it once you have Smart Search running correctly. To remove old Joomla search modules, use the following procedure:&lt;br /&gt;
&lt;br /&gt;
# Log in to the Administrator.&lt;br /&gt;
# Click on the desired menu under the Menus menu item.&lt;br /&gt;
# Filter the modules listed so that only search modules are shown by selecting &amp;quot;Search&amp;quot; from the &amp;quot;Select Type&amp;quot; filter drop-down. If no such modules are listed then there are no instances of the old search available and you can skip this part.&lt;br /&gt;
# Select the checkbox at the top of the table to select all of the items in the list. Once all the instances of the old search have been selected, press the Delete button in the Module Manager toolbar. Be careful that you do not accidentally delete any other modules in the process.&lt;br /&gt;
&lt;br /&gt;
==Removing Joomla Search Menu Items==&lt;br /&gt;
Unfortunately, there is no quick and easy way to remove all links to the old Joomla search system. To remove all the menu items to the old Joomla search system you will have to browse the menu items in each of your site&#039;s menus and manually remove the links. To make this process somewhat quicker, adjust the order of the table to list menu items by type in reverse alphabetical order. Now scroll down and look for links with type &amp;quot;Search &amp;gt;&amp;gt; Search&amp;quot;. Delete those menu items by checking the checkbox to the left of the title and then pressing the Delete button in the Menu Manager toolbar.&lt;br /&gt;
&lt;br /&gt;
[[Category:Smart Search]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Creating_a_Smart_Search_plug-in&amp;diff=999359</id>
		<title>Creating a Smart Search plug-in</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Creating_a_Smart_Search_plug-in&amp;diff=999359"/>
		<updated>2023-02-19T15:41:49Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some changes for Word2Watch compliance and other markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt; &amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
Smart Search Plugins are gathered together for convenience into a Plugin group called &amp;quot;finder&amp;quot;. Take a look in the &#039;&#039;plugins/finder&#039;&#039; directory and you will see the Plugins that support the core Joomla content types. It is best to create your own Plugin by taking a copy of one of these Plugins and adapting it to meet your needs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
All Smart Search Plugins extend the &#039;&#039;FinderIndexerAdapter&#039;&#039; class which contains many methods to deal with maintaining the index. For most of custom content requirements you only need to override a few of these methods.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
There is [https://magazine.joomla.org/issues/issue-feb-2012/item/671-Developing-a-Smart-Search-Plugin some additional information] on writing a Smart Search Plugin.&lt;br /&gt;
&lt;br /&gt;
==The Principal Properties== &amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
Before looking at the methods, there are a few properties that need to be set up correctly:&lt;br /&gt;
* $context&lt;br /&gt;
*: This should be a unique identifier for the Plugin and establishes the context that the Plugin will respond to (e.g. &amp;quot;Content&amp;quot;).&lt;br /&gt;
* $extension&lt;br /&gt;
*: The name of the extension (component) that handles the content type (e.g. &amp;quot;com_content&amp;quot;).&lt;br /&gt;
* $layout&lt;br /&gt;
*: The sublayout to use when rendering search results. For example, of $layout is set to &amp;quot;article&amp;quot; then the default view will look for a layout file called &#039;&#039;default_article.php&#039;&#039; when it needs to render a search result of this type. If no such file is found then the layout file called &#039;&#039;default_result.php&#039;&#039; will be used instead.&lt;br /&gt;
* $table&lt;br /&gt;
*: The name of the table to retrieve data from (e.g. &amp;quot;#__content&amp;quot;).&lt;br /&gt;
* $state_field&lt;br /&gt;
*: The database field in your table that the published state of an item is stored in. Defaults to &amp;quot;state&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
==The Principal Methods== &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
The first methods you will want to override when developing a new Smart Search Plugin are the &#039;&#039;setup&#039;&#039;, &#039;&#039;index&#039;&#039; and &#039;&#039;getListQuery&#039;&#039; methods. In the majority of cases those three methods will be enough to get your content indexed, although the Plugin will not be complete as there are other methods that must be implemented to deal with issues such as updating the index when the content changes. But those three methods are the working core of the Plugin.&lt;br /&gt;
* setup&lt;br /&gt;
*: This method is called by the indexer once before an indexing run begins. It can be used to load libraries or initialise variables for the Plugin. Must return true.&lt;br /&gt;
* index&lt;br /&gt;
*: This is the main method called by the indexer. It is called once for each content item that is to be indexed (or the index updated). The index method essentially describes the content to the indexer by telling the indexer which fields to parse for terms/phrases and their relative weights, which fields to map into branches of the content map and what data to include in the index as &amp;quot;payload&amp;quot;. This method is described in more detail later.&lt;br /&gt;
* getListQuery&lt;br /&gt;
*: This method must return a JDatabaseQuery object that will form the basis of a query that will return a list of objects of the given content type. There are constraints on this query to ensure that it is compatible with other methods used by the indexer. This method is described in more detail later.&lt;br /&gt;
&lt;br /&gt;
==Some Other Methods== &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
For a complete Smart Search Plugin there are other methods you may need to override.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
* translateState&lt;br /&gt;
*: Given a content item this method translates the native state of the content item into a state that the indexer can use. It must return an integer 0 if the content item is not to appear in search results, or an integer 1 if the content item can appear in search results.&lt;br /&gt;
* getURL&lt;br /&gt;
*: Returns the non-SEF URL for an item.  The default return, using &#039;&#039;plg_finder_content&#039;&#039; for example, is &#039;&#039;index.php?option=com_content&amp;amp;view=article&amp;amp;id=1&#039;&#039;.&lt;br /&gt;
* getStateQuery&lt;br /&gt;
*: This method is used to build a generic query for checking the access and state of items and their parent categories. This method uses the &#039;&#039;$table&#039;&#039; and &#039;&#039;$state_field&#039;&#039; properties to select the correct data.&lt;br /&gt;
&lt;br /&gt;
==Event Methods== &amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
The following methods are called via the Smart Search content Plugin in response to specific trigger events in Joomla.&lt;br /&gt;
* onFinderBeforeSave&lt;br /&gt;
*: Called in response to an onContentBeforeSave event.&lt;br /&gt;
* onFinderAfterSave&lt;br /&gt;
*: Called in response to an onContentAfterSave event.&lt;br /&gt;
* onFinderAfterDelete&lt;br /&gt;
*: Called in response to an onContentDelete event.&lt;br /&gt;
* onFinderChangeState&lt;br /&gt;
*: Called in response to an onContentChangeState event.&lt;br /&gt;
* onFinderCategoryChangeState&lt;br /&gt;
*: Called in response to an onCategoryChangeState event.&lt;br /&gt;
&lt;br /&gt;
==Methods in More Detail== &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===getListQuery=== &amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
This method must return a JDatabaseQuery object that will form the basis of a query that will return a list of objects of the given content type. There are constraints on this query to ensure that it is compatible with other methods used by the indexer. If the following conditions are not true you will need to override other methods in the FinderIndexerAdapter class.&lt;br /&gt;
* The primary database table that is being indexed must have an alias of &amp;quot;a&amp;quot;.&amp;lt;ref&amp;gt;If this condition is not true you will also have to override the getItem, getUpdateQueryByTime and getUpdateQueryByIds methods&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Index=== &amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
This method is called whenever a content item needs to be indexed (or re-indexed). It is passed an object of type FinderIndexerResult and its purpose is to make adjustments to that object and to add metadata before handing control to FinderIndexer::index method to do the indexing proper.&lt;br /&gt;
&lt;br /&gt;
===Setup=== &amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
This method is called prior to the index method and is used to set up the index process. This method is where you would typically include any externally-required classes to allow for proper indexing.&lt;br /&gt;
&lt;br /&gt;
==FinderIndexerResult Properties== &amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
* url&lt;br /&gt;
* route&lt;br /&gt;
* title&lt;br /&gt;
* description&lt;br /&gt;
* published&lt;br /&gt;
* state&lt;br /&gt;
* access&lt;br /&gt;
* language&lt;br /&gt;
* publish_start_date&lt;br /&gt;
* publish_end_date&lt;br /&gt;
* extension (only used in core for com_categories plugin)&lt;br /&gt;
&lt;br /&gt;
==Testing== &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
Testing a finder plugin can be difficult due to the fact that it is typically run using an Ajax process, so you don&#039;t tend to actually see any results from the process.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
As such, one way to test is to use the command line indexer.&amp;lt;ref&amp;gt;[http://docs.joomla.org/Setting_up_automatic_Smart_Search_indexing Setting up automatic Smart Search Indexing]&amp;lt;/ref&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
Open a command prompt/SSH session on the server and go to the root directory of the website.  &lt;br /&gt;
From there, you can run the indexer and errors and log messages will go to the screen.&lt;br /&gt;
&#039;&#039;php cli/finder_indexer.php&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Notes== &amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Category:Smart Search]]&lt;br /&gt;
[[Category:Plugin Development]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Planning_Migration_-_Joomla_1.5_to_4&amp;diff=999357</id>
		<title>Planning Migration - Joomla 1.5 to 4</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Planning_Migration_-_Joomla_1.5_to_4&amp;diff=999357"/>
		<updated>2023-02-18T18:12:47Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup and phrasing changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
Going from Joomla! 1.5 to 4.x is considered a major migration. This means that considerable changes in how Joomla works, tables, technology have occurred that require a migration instead of an upgrade or update. Both Joomla core extensions and any third-party extensions will need to migrate to Joomla 4.x. This includes the site template. Every single thing needs to be looked at, planned, decided upon, and executed. You will need to be diligent with staying organized throughout the process.&lt;br /&gt;
&lt;br /&gt;
== Intro == &amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The fabulous thing about migration is that it is a great time to reassess goals, create a new look and feel (template), clean up, and develop other areas/elements of your site. The more organized you can be with your ideas/thoughts/plans, the better. Planning makes execution easier.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
Start planning by asking the following questions or doing the tasks listed below. You may have more items to plan for depending on the complexity of your site. Sadly, there is no way we can list every possible scenario. &lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
{{dablink|&amp;lt;translate&amp;gt;&amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
You can ask specific questions on the [[jforum:808|Joomla 4.x General Questions/New to Joomla 4.x Forum]].&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Planning Action Items == &amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== General === &amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
# Assess your original site goals. Migration is an opportunity to get back into focus with your goals or change direction.&lt;br /&gt;
# Does your server meet the minimum [http://www.joomla.org/about-joomla/technical-requirements.html technical requirements] for Joomla 4? If not, you will need to change hosts. No better time to change hosts than during a migration.&lt;br /&gt;
# What kind of development environment will you use? A development environment on your local device? A subdomain or subdirectory on your server? A new server/hosting account due to technical specifications?&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Joomla Core === &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
# Clean-up your current site. Take a look at your Sections, Categories, and Articles. Sections are converted to higher level categories from Joomla 2.5 on. Is there clean-up that needs to be done so that you don’t migrate unnecessary content? Document what you want to delete. Alternatively, you may want to document what you want to bring over depending on quantity.&lt;br /&gt;
# Organize your content on the current site. Do the Categories you have still apply? Document new categories you may want to add in your new site.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
# Do you have any articles in the trash? If so, delete them (and any applicable media that may be associated with them if not in use elsewhere on the site). Articles (categories and menu items too) left in the trash can cause duplicate alias issues once migrated.&lt;br /&gt;
# The Media Manager: Decide whether you want to bring your entire &#039;&#039;/images&#039;&#039; directory over or just part of it. If your Media Manager has become a disaster, you may decide to bring over specific images via FTP or cPanel instead of migrating the entire directory. In the future, organize folders in the Media Manager so you don’t end up with a big mess.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
# If you are using core components like Joomla Contacts, Web Links, or News Feeds, document this as you will need to bring those over.&lt;br /&gt;
# Check your menus and determine if you will bring them all over or only specific menus and menu items. Delete any menu items from the trash to prevent duplicate aliases.&lt;br /&gt;
# If you redesign or make changes to your site design or navigation, will you have obsolete pages that will require a redirect? Track all URLs that need redirects on a spreadsheet or notepad.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
# Did you “hack the core” of your 1.5 site? If so, those changes will not migrate to Joomla 4. You will want to find alternatives to hacking the core in Joomla 4 ([[S:MyLanguage/Understanding Output Overrides|Understanding Output Overrides]], [[S:MyLanguage/Layout Overrides in Joomla|Layout Overrides in Joomla]]).&lt;br /&gt;
# Check your User Manager. Are you intending to bring them all over? Is there clean up required? Perhaps Super Users that no longer should have access or spam users that need to be deleted? Are you using some kind of third-party extension to enhance User Profiles? This part needs careful planning especially if the user data changes frequently.&lt;br /&gt;
# Are there new features of Joomla that you wish to use, such as Access Control Levels (ACLs), tags, workflows, or custom fields? Start planning for that now. Planning ACLs is cautious business. Being thorough is very important.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Third-party Extensions === &amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
# Make a list of all third-party extensions in use. This includes components, modules, plugins, languages, and templates. You may copy/paste them from the Manage page into a document for reference if you’d like. A piece of paper and a pen will suffice. Include if these extensions are used heavily, moderately, hardly ever, or not at all.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
# Determine whether the third-party extensions you rely on are ready for Joomla 4.&lt;br /&gt;
# Determine if you really need all the extensions you are using. Perhaps Joomla 4 has built-in features that could eliminate the third-party extension.&lt;br /&gt;
# What about your site template? If you purchased your template from a third-party source, is there a 4.x version released for it? Would you like to continue using it? Is there a migration path published by the developer? Is the new version of it responsive? Is your template a custom template? Or was it heavily customized from a third-party template? For an expansion of Template-based considerations, see [[S:MyLanguage/Template Considerations During Migration|Template Considerations During Migration]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
# If you are changing your template for a new one, will it require any new images? For example, if your current site has a white background and your logo or other images are &#039;&#039;.jpg&#039;&#039; images with a white background, it won’t look very nice against a new template with an off-white or coloured background.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Basic button|Joomla 1.5 to 4.x Step by Step Migration|&amp;lt;translate&amp;gt;&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
Joomla! 1.5 to 4.x Step by Step Migration&amp;lt;/translate&amp;gt;|class=expand}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
[[Category:Migration]]&lt;br /&gt;
[[Category:Tutorials]]&amp;lt;/translate&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_do_I_use_Gmail_as_my_mail_server%3F&amp;diff=999295</id>
		<title>How do I use Gmail as my mail server?</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_do_I_use_Gmail_as_my_mail_server%3F&amp;diff=999295"/>
		<updated>2023-02-11T23:04:27Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Several markup changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;If you have a working Gmail account you can use Gmail as your mail server by setting it in the Global Configuration.&lt;br /&gt;
&lt;br /&gt;
On the server tab set the following:&lt;br /&gt;
&lt;br /&gt;
*Mailer: SMTP&lt;br /&gt;
*SMTP Host: smtp.gmail.com&lt;br /&gt;
*SMTP Port 465&lt;br /&gt;
*SMTP Security: SSL/TLS&lt;br /&gt;
*SMTP Authentication: Yes&lt;br /&gt;
*Set the next two lines with your information. Use an app-specific password (ASP), described below.&lt;br /&gt;
*SMTP Username: your Gmail username&lt;br /&gt;
*SMTP Password: the app-specific password (ASP) you generated, described below.&lt;br /&gt;
&lt;br /&gt;
The following are also working combinations:&lt;br /&gt;
*SMTP Port 587&lt;br /&gt;
*SMTP Security: STARTTLS&lt;br /&gt;
&lt;br /&gt;
*SMTP Port 25&lt;br /&gt;
*SMTP Security: STARTTLS&lt;br /&gt;
&lt;br /&gt;
The SSL module does not need to be enabled in Apache. &lt;br /&gt;
&lt;br /&gt;
The OpenSSL extension needs to be enabled in PHP. The details can be found at the [https://www.php.net/manual/en/openssl.installation.php php.net Installation page]. &lt;br /&gt;
&lt;br /&gt;
If you are using WAMP on Windows, the &#039;&#039;openssl&#039;&#039; module is not enabled by default and you need to enable it:&lt;br /&gt;
# Open the &#039;&#039;php.ini&#039;&#039; file and uncomment the line &amp;lt;code&amp;gt;extension=php_openssl.dll&amp;lt;/code&amp;gt; by removing the semicolon ; from the beginning of the line.&lt;br /&gt;
# Save the &#039;&#039;php.ini&#039;&#039; file and restart the Apache service.&lt;br /&gt;
&lt;br /&gt;
{{tip|title=Note|Note that if you use 2-step verification in Gmail, add a new password in Settings - Accounts - Change accounts settings - Other Google Account settings - Security - 2-step verification - Manage your application specific passwords.}}&lt;br /&gt;
&lt;br /&gt;
When the new Application-Specific Password (ASP) is presented in groups of four characters separated by spaces, make sure that you do &#039;&#039;&#039;not&#039;&#039;&#039; enter the spaces into the SMTP password in the mail server settings in Joomla.&lt;br /&gt;
&lt;br /&gt;
* Application Specific Passwords (ASPs): See the Google Support [https://support.google.com/accounts/answer/185833 Sign in with App Passwords] page.&lt;br /&gt;
* 2-Step Verification: See the Google Support [https://support.google.com/accounts/answer/185839 Turn on 2-Step Verification] page.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;noinclude&amp;gt;[[Category:FAQ]][[Category:Server configurations]]&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=How_do_you_report_a_bug%3F&amp;diff=999285</id>
		<title>How do you report a bug?</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=How_do_you_report_a_bug%3F&amp;diff=999285"/>
		<updated>2023-02-07T18:44:14Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup changes. Words2Watch corrections.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Reporting bugs ==&lt;br /&gt;
&lt;br /&gt;
To report a bug in the Joomla! bug trackers, create a tracker item. Once the tracker item is created, the developers will check the validity of it and act accordingly.&lt;br /&gt;
&lt;br /&gt;
=== Register an Account at &#039;&#039;issues.joomla.org&#039;&#039; ===&lt;br /&gt;
[https://issues.joomla.org Register]with Github account.&lt;br /&gt;
&lt;br /&gt;
=== Access the Joomla! Development Bug Tracker. ===&lt;br /&gt;
&lt;br /&gt;
*Once registered it will take you to the tracker directly. This tracker contains all issues reported for all supported versions of Joomla!&lt;br /&gt;
&lt;br /&gt;
=== Check to See If the Bug is Already Reported. ===&lt;br /&gt;
&lt;br /&gt;
There will be no filters set by default but you can use the provided search filters to narrow your search. If the issue you are experiencing is not already reported, click on the top-left Button &amp;quot;New Item&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
A new screen will display and there, the more information you give, the easier it is for the developers. Fill as many fields as you can.&lt;br /&gt;
&lt;br /&gt;
* [[Priority]] : Use the default &amp;quot;Medium&amp;quot; except if you know the code enough to make another choice.&lt;br /&gt;
* PHP : Choose the version you are testing on.  You can find this information by clicking the Menu {{rarr|Help,System Info}} in the Administrator Backend of Joomla!.&lt;br /&gt;
* Estimated Time : Leave this blank.&lt;br /&gt;
* Build : Type here the #SVN number if you know it, or Nightly Build date, or Version used if using a Released version.&lt;br /&gt;
* Browser : Self-explanatory.&lt;br /&gt;
* Database : The version of MySQL is also available in {{rarr|Help,System Info}}.&lt;br /&gt;
* Status : Leave this to &amp;quot;Open&amp;quot;.&lt;br /&gt;
* Percent Complete : Leave this blank.&lt;br /&gt;
* Category : This one is more tricky. Use &amp;quot;Administration&amp;quot; if you do not know better.&lt;br /&gt;
* Customer : Use &amp;quot;User&amp;quot; if the issue is in Frontend, &amp;quot;Developer&amp;quot; if the issue concerns an extension you are developing, &amp;quot;Administrator&amp;quot; in other cases.&lt;br /&gt;
* Web Server : The version/server type is also available in {{rarr|Help,System Info}}.&lt;br /&gt;
 &lt;br /&gt;
=== Provide a Summary ===&lt;br /&gt;
&lt;br /&gt;
Describe in a few words the issues you are having. It is a good idea to use existing tracker items as examples if this is your first time reporting a bug.&lt;br /&gt;
&lt;br /&gt;
Examples:&lt;br /&gt;
&lt;br /&gt;
* Frontend: Warning such and such.&lt;br /&gt;
* Backend: Unable to save article when &amp;quot;nameofplugin&amp;quot; is published.&lt;br /&gt;
&lt;br /&gt;
Note: Take care to be descriptive in your summary as this is the first thing the developers will see when they are perusing the tracker for something to fix.&lt;br /&gt;
 &lt;br /&gt;
=== Provide Details About the Bug ===&lt;br /&gt;
&lt;br /&gt;
This is the most important part of reporting the bug. Describe here step by step how you got the error you are noticing. Include all of the information that someone will need to re-trace your steps and see the problem. Remember: Your bug will not be fixed unless others can see the problem, so you want to be as clear and detailed as possible. You do not need to know anything about programming to write a great bug report. But if you do understand the code and think you know how to fix the bug, please include this in the report.&lt;br /&gt;
&lt;br /&gt;
The general format should be something like:&lt;br /&gt;
# &amp;quot;Here is &#039;&#039;exactly&#039;&#039; what I did.&amp;quot;&lt;br /&gt;
# &amp;quot;This is what happened.&amp;quot;&lt;br /&gt;
# &amp;quot;This is what I think should have happened.&amp;quot; &lt;br /&gt;
# &amp;quot;Other information, possible solution, proposed code patch.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The more details, the better. Also, it is important to reproduce the bug using the sample Joomla! website or with easy, clear instructions for how to set it up. Remember that others will not have access to your site&#039;s database, so you will need to be able to tell someone how to see the bug with data that is readily available -- the sample site.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example A&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
; What I did : Started with sample website. Everything was ok. I enabled &amp;quot;nameofplugin&amp;quot;. Try to save any article from Backend.&lt;br /&gt;
; What happened : I get a blank screen and article is not saved. &lt;br /&gt;
; What should have happened : Articles should save correctly.&lt;br /&gt;
; Other information : These are the plugins enabled at the same time. SEF is on (or Off). My site is in a sub-folder. I also remark that... etc. Files such and such are the issues IMHO (if you know what you are talking about).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Example B&#039;&#039;&#039; &lt;br /&gt;
&lt;br /&gt;
; What I did : Navigate to Backend. Click on &amp;quot;menu_name&amp;quot; Menu. &lt;br /&gt;
; What happened: Page opened is blank. &lt;br /&gt;
; What should have happened : Menu should have opened correctly.&lt;br /&gt;
; Other information : Any other menu works OK. etc.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Real-Life Example&#039;&#039;&#039;&lt;br /&gt;
; What I did &lt;br /&gt;
: Started with the sample website. &lt;br /&gt;
: Added an unpublished article from the Backend, with Section=FAQ, Category=General. &lt;br /&gt;
: In the advanced parameters for the article, set Show Title to &amp;quot;No&amp;quot; and Print, PDF, and Email Icons to &amp;quot;Hide&amp;quot;. &lt;br /&gt;
: Save the article and navigate to Frontend. Login to the Frontend as admin and navigate to the Example Pages -&amp;gt; Category Blog menu item. &lt;br /&gt;
; What happened : The newly added article shows but there is no edit icon for the Frontend user to click on.&lt;br /&gt;
; What should have happened : The edit icon should show, allowing a Frontend user to edit this article.&lt;br /&gt;
; Other information : This only happens with the &#039;&#039;rhuk_milkyway&#039;&#039; template. By changing this code [code proposed] in file [name and hierarchy of file], line(s) #, the issue looks solved on my settings.&lt;br /&gt;
&lt;br /&gt;
=== Add an Attachment to Your Report ===&lt;br /&gt;
&lt;br /&gt;
To better describe the issue or/and propose a fix, you can add attachments to the tracker item you are creating by using the &amp;quot;Browse&amp;quot; buttons at the bottom of the screen.&lt;br /&gt;
A screen capture of the page(s) concerned helps a lot. If you can, try to optimise the size of the image through an image editor.&lt;br /&gt;
If you know what part(s) of the code base to change, a patch [patches] or a full file where your changes are &#039;&#039;&#039;well&#039;&#039;&#039; shown will help the developers to solve the problem quicker.&lt;br /&gt;
&lt;br /&gt;
=== Finish and Send in the Report ===&lt;br /&gt;
&lt;br /&gt;
You will receive an email confirming that you posted the tracker item. When someone comments or asks for supplementary details or solves the issue, you will receive a notification email and may reply if needed.&lt;br /&gt;
&lt;br /&gt;
=== Extra Tips and Tricks ===&lt;br /&gt;
&lt;br /&gt;
Well-written bug reports are incredibly helpful. However, there&#039;s a certain amount of overhead involved in working with any bug tracking system, so your help in keeping our ticket tracker as useful as possible is appreciated. In particular:&lt;br /&gt;
&lt;br /&gt;
* Do read the [http://docs.joomla.org/FAQs FAQ] to see if your issue might be a well-known question.&lt;br /&gt;
* Do search [https://issues.joomla.org the tracker] to see if your issue has already been filed.&lt;br /&gt;
* Do ask on [http://forum.joomla.org/index.php/board,199.0.html testing forums] first if you&#039;re not sure if what you&#039;re seeing is a bug.&lt;br /&gt;
* Do write complete, reproducible, specific bug reports. Include as much information as you possibly can, complete with code snippets, test cases, etc. A minimal example that illustrates the bug in a nice small test case is the best possible bug report.&lt;br /&gt;
* Don&#039;t use the tracker system to ask support questions. Use the [http://forum.joomla.org/ Joomla! forums], or the [irc://irc.freenode.net/joomla #joomla] IRC channel on freenode for that.&lt;br /&gt;
* Don&#039;t use the trackers to make large-scale feature requests. We like to discuss any big changes to Joomla!&#039;s core on the [http://forum.joomla.org/index.php#6 developers forums] before actually working on them.&lt;br /&gt;
* Don&#039;t reopen issues that have been marked &amp;quot;not a bug&amp;quot;. This mark means that the decision has been made that we can&#039;t or won&#039;t fix this particular issue. If you&#039;re not sure why, please ask on developer forums.&lt;br /&gt;
* Don&#039;t use the tracker for lengthy discussions, because they&#039;re likely to get lost. If a particular tracker item is controversial, please move discussion to [http://forum.joomla.org/index.php#6 developer forums].&lt;br /&gt;
&lt;br /&gt;
== Reporting Security Issues ==&lt;br /&gt;
&lt;br /&gt;
Report security issues to security [at] joomla [dot] org. This is a private list only open to long-time, highly trusted Joomla! developers, and its archives are not publicly readable.&lt;br /&gt;
&lt;br /&gt;
In the event of a confirmed vulnerability in Joomla! itself, we will take the following actions:&lt;br /&gt;
&lt;br /&gt;
* Acknowledge to the reporter that we&#039;ve received the report and that a fix is forthcoming. We&#039;ll give a rough timeline and ask the reporter to keep the issue confidential until we announce it.&lt;br /&gt;
* Halt all other development as long as is needed to develop a fix, including patches against the current and two previous releases.&lt;br /&gt;
* Determine a go-public date for announcing the vulnerability and the fix. To try to mitigate a possible &amp;quot;arms race&amp;quot; between those applying the patch and those trying to exploit the hole, we will not announce security problems immediately.&lt;br /&gt;
* Publicly announce the vulnerability and the fix on the pre-determined go-public date. This will probably mean a new release of Joomla! but in some cases it may simply be patches against current releases.&lt;br /&gt;
&lt;br /&gt;
[[Category:Development]] [[Category:Bug_Squad]]&lt;br /&gt;
[[Category:Joomla! Resources]]&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
	<entry>
		<id>https://docs.sandbox.joomla.org/index.php?title=Joomla_3.x_to_4.x_Step_by_Step_Migration&amp;diff=999282</id>
		<title>Joomla 3.x to 4.x Step by Step Migration</title>
		<link rel="alternate" type="text/html" href="https://docs.sandbox.joomla.org/index.php?title=Joomla_3.x_to_4.x_Step_by_Step_Migration&amp;diff=999282"/>
		<updated>2023-02-06T22:37:04Z</updated>

		<summary type="html">&lt;p&gt;Cmb: Some markup, phrasing and Words2Watch changes.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;noinclude&amp;gt;&amp;lt;languages /&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;br /&gt;
{{warning|title=&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:34--&amp;gt;&lt;br /&gt;
Warning!&amp;lt;/translate&amp;gt;|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:1--&amp;gt;&lt;br /&gt;
This guide assumes you are starting on Joomla 3.10.x. If you are on a earlier version make sure you upgrade to Joomla 3.10 first before moving to Joomla 4. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--T:59--&amp;gt;&lt;br /&gt;
There is no rush. Make sure all your extensions are ready for Joomla 4.x. Joomla 3.10.x will be supported until 16 August 2023.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:2--&amp;gt;&lt;br /&gt;
The following are step-by-step instructions to migrate your 3.10.x site to Joomla! 4.x. While there are different scenarios, this will give you the basic procedure to follow. Complex migrations will likely be a result of installed third-party extensions. You are encouraged to contact the developers of third-party extensions installed on your Joomla site for their suggested migration path.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Intro == &amp;lt;!--T:3--&amp;gt;&lt;br /&gt;
The migration from Joomla! 3.10.x to 4.x is considered a mini-migration. This is because the Joomla core extensions will upgrade with a “one-click” upgrade via the Joomla! Update component in the Backend (Administrator) of Joomla. Many third-party extensions are a one-click upgrade too. Some are not. Look at each one and determine what path the extension needs to follow to get from 3.10 to 4.x. If you haven&#039;t already, read the [[S:MyLanguage/Migration Step by Step Self Assessment|Self Assessment]] and [[S:MyLanguage/Planning for Mini-Migration - Joomla 3.10.x to 4.x|Planning for 3.10 to 4.x Migration]] prior to following the steps below.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:4--&amp;gt;&lt;br /&gt;
&amp;lt;/br&amp;gt;Joomla! Core Extensions are:&lt;br /&gt;
* Categories&lt;br /&gt;
* Articles&lt;br /&gt;
* Menus&lt;br /&gt;
* Modules (core modules - not third-party)&lt;br /&gt;
* Action Logs&lt;br /&gt;
* Banners&lt;br /&gt;
* Fields&lt;br /&gt;
* Content History&lt;br /&gt;
* Contacts&lt;br /&gt;
* Messaging&lt;br /&gt;
* Newsfeeds&lt;br /&gt;
* Redirect&lt;br /&gt;
* Search (decoupled in 4.x. Existing 3.x sites will still migrate it. However we recommend using Smart Search going forward. See Notes under Assess Each Extension)&lt;br /&gt;
* Smart Search&lt;br /&gt;
* Tags&lt;br /&gt;
* Weblinks (decoupled but your site may be using it and it will migrate. See Notes under Assess Each Extension.)&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Step by Step == &amp;lt;!--T:5--&amp;gt;&lt;br /&gt;
=== Set Up a Development Location ===&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:6--&amp;gt;&lt;br /&gt;
# Make sure you are running the latest Joomla 3.10.x version before proceeding.&lt;br /&gt;
# Take a backup of your live 3.10.x site. You can use a suggested tool (see the &#039;&#039;Suggested Tools&#039;&#039; at the bottom of page) or you can do this manually.&lt;br /&gt;
#*[[S:MyLanguage/Backup_Basics_for_a_Joomla!_Web_Site|Backup Basics for a Joomla! Web Site]]&lt;br /&gt;
#*[[S:MyLanguage/What_are_the_best_practices_for_site_backups%3F|What are the best practices for site backups?]]&lt;br /&gt;
# Make sure your environment meets the [https://downloads.joomla.org/technical-requirements technical requirements for Joomla 4].&lt;br /&gt;
# Create a new database and new user to restore your 3.10.x site to. &lt;br /&gt;
# Create a testing site or build area to work in and restore the backup copy of your 3.10.x site in one of the following places:&lt;br /&gt;
#* A subdomain.&lt;br /&gt;
#* A subdirectory.&lt;br /&gt;
#* A local device. Joomla has a detailed tutorial on installing [https://sourceforge.net/projects/xampp/ XAMPP] at [[XAMPP]]. However [https://www.wampserver.com/en/ WAMP], [https://www.mamp.info/en/windows/ MAMP], [https://sourceforge.net/projects/lampas/ LAMP] are all suitable alternatives.&lt;br /&gt;
#* A new hosting account on a temporary domain in the root. (If you would like to change hosts in the process of migration.)&lt;br /&gt;
#** Restoring a site on a local device. See [[S:MyLanguage/Installing Joomla locally|Installing Joomla locally]] and [[S:MyLanguage/Setting up your workstation for Joomla development|Setting up your workstation for Joomla development]].&lt;br /&gt;
#** Restoring a site with a tool listed at the bottom of the page. (Read the developer documentation.)&lt;br /&gt;
# In your test location, update your Joomla! 3.10.x instance to the latest maintenance release.&lt;br /&gt;
# Make sure you have the latest database schema updated to the latest version 3.10.x version by going to {{rarr|Extension Manager,Database}} tab. If your schema is not up to date as in the following image, click the &#039;&#039;&#039;Fix&#039;&#039;&#039; button:&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-extension-database-fix-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:7--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:8--&amp;gt;&lt;br /&gt;
# Empty trash: Do you have any articles in the trash? Delete them (and any associated media if not in use elsewhere on the site). Articles (categories and menu items too) left in the trash can cause migration issues.&lt;br /&gt;
# Test.&lt;br /&gt;
# Backup again.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Assess Each Extension === &amp;lt;!--T:9--&amp;gt;&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:10--&amp;gt;&lt;br /&gt;
In your [[S:MyLanguage/Planning_for_Mini-Migration_-_Joomla_3.10.x_to_4.x|planning]], you determined that third-party extensions were staying or going and how they migrate. For this portion of the Step by Step, you’ll be using two different sections of the site extensively; The Pre-Update Check in {{rarr|Components,Joomla! Update}} and {{rarr|Extensions,Manage,Manage}}. You are going to be looking at every single extension installed on your site. You will be determining if they need to be updated to the latest version or uninstalled. More details in [[Special:MyLanguage/:Pre-Update_Check|Pre-Update Check]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:30--&amp;gt;&lt;br /&gt;
# Using the &#039;&#039;&#039;Pre-Update Check&#039;&#039;&#039;: in order to use the Pre-Update Check, you will need to set the Joomla! Update component to Joomla 4. To do this follow:&lt;br /&gt;
# Go to {{rarr|Components,Joomla Update}}. (It should say no updates found. If it doesn’t, update Joomla to the latest version (must be 3.10.x) and test. Then do another backup.) Click on the Options button at the top right corner.&lt;br /&gt;
# Select &#039;&#039;Joomla Next&#039;&#039; from the drop-down for Update Channel.&amp;lt;/translate&amp;gt;{{-}}[[File:Migration_J3toJ4_update_channel-&amp;lt;translate&amp;gt;&amp;lt;!--T:35--&amp;gt; en&amp;lt;/translate&amp;gt;.png|border|800px]]{{-}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:36--&amp;gt;&lt;br /&gt;
# Click Save &amp;amp; Close&lt;br /&gt;
# You will then see your Installed Joomla Version, the latest Joomla! version and the URL for the update package. Joomla will show you the requirements again for Joomla 4. If it flags that you have either an incompatible system or extensions it will tell you here. Take a moment to review this page.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-update_to_4-pre_update_check-&amp;lt;translate&amp;gt;&amp;lt;!--T:60--&amp;gt; en&amp;lt;/translate&amp;gt;.png|border|800px]]&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:31--&amp;gt;&lt;br /&gt;
{{amboxNew|image=notice|style=notice|title={{{title|Important Notice}}}|text=&#039;&#039;&#039;Do NOT update to Joomla! 4 right now. This is only to prepare your third-party extensions and get the site compatible with Joomla! 4.&#039;&#039;&#039;}}&lt;br /&gt;
# Look at the Pre-Update Check and the Extension Pre-Update Check in the Pre-Update Check tab of the Joomla Update component. If any extension that isn’t in your planning is listed here, add it to your list of extensions to investigate.&lt;br /&gt;
# If you migrated from Joomla! 2.5 to 3.x in the past, there may be some leftover extensions that need to be cleaned up. The following are older 2.5 or 3.x extensions that need to be uninstalled before updating to Joomla 4:&lt;br /&gt;
#;* plg_content_geshi&lt;br /&gt;
#;* Bluestork Administrator Template&lt;br /&gt;
#;* Beez_20&lt;br /&gt;
#;* Beez5&lt;br /&gt;
#;* Atomic&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:37--&amp;gt; ## When it comes to templates, uninstall all core Frontend or Backend templates except Protostar and Beez3 (site templates) and Isis or Hathor (Administrator templates). &#039;&#039;&#039;Note&#039;&#039;&#039; Protostar is &#039;&#039;&#039;not&#039;&#039;&#039; compatible with Joomla 4. Upon migration it will disappear. You&#039;ll need to have one template selected as &amp;quot;default&amp;quot; and you can use Protostar or Beez3. Protostar will disappear upon migration to Joomla 4.x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:38--&amp;gt; ## If you come across other files that need to be uninstalled, please add them to this page. This is a wiki so anyone can add to the page. Thank you in advance for your service.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:39--&amp;gt; # You will notice the tags for whether an extension is compatible or not. These tags generally tell a true story if they say No or Yes. If they say “Missing Compatibility Tag” it means that the extension developer didn’t use a tag in their extension so we don’t know if it is or isn’t compatible with Joomla 4. Talk to the developer to verify.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:40--&amp;gt; # &#039;&#039;&#039;Update Extensions&#039;&#039;&#039;: update any extensions that you will keep in your website. In Joomla! 3.10.x you can go to {{rarr|Extension Manager,Update tab}} and click &#039;&#039;&#039;Find Updates&#039;&#039;&#039; that will add a tooltip in the Version column, under the Manage tab, giving some compatibility information from the Backend. This functionality only supports extensions that update via the Extension Manager Update tab. If you have extensions installed that do not use the Joomla extension update they need to be assessed manually as detailed below. The same goes for those extensions that have a tooltip. You will still need to check the type of package and migration path with the extension developer to verify how to upgrade/migrate.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:41--&amp;gt;&lt;br /&gt;
# Investigate and Uninstall Extensions Extensions: go to {{rarr|Extension Manager,Manage}}&lt;br /&gt;
# Click the Button &#039;&#039;Search Tools&#039;&#039; to show the filter options&lt;br /&gt;
# Select Package from the &#039;&#039;Select Type&#039;&#039; drop-down.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-admin-extension-manage-package-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:11--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|800px]]{{-}}{{note|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:12--&amp;gt;&lt;br /&gt;
Selecting Package first is recommended because if there is something you need to uninstall in a package, it will automatically uninstall the associated Modules, Plugins, or anything else in the package at one time.&amp;lt;/translate&amp;gt;}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:13--&amp;gt;&lt;br /&gt;
# Uninstall any Packages that are no longer needed or will not be migrating to Joomla 4.&lt;br /&gt;
# Repeat this process of going through the Manage tab for all Types in the drop-down: Component, File, Language, Library, Module, Plugin and Template. If the Author states Joomla! Project, then leave those extensions alone. For all others, make sure that you uninstall those not in use or not compatible with Joomla!&amp;amp;nbsp;4.x.&amp;lt;/translate&amp;gt;{{-}}{{note|&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:14--&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;NOTE!&#039;&#039;&#039; You will not be able to uninstall any template that is set as default. Select a Core supported template such as Beez3 or Protostar and then uninstall the template if you need to do so. &amp;lt;br /&amp;gt;&#039;&#039;Another reminder:&#039;&#039; &#039;&#039;&#039;Protostar is not compatible with Joomla 4.x&#039;&#039;&#039;. Upon migration it will disappear. Selecting it as default simply gets you to Joomla 4.x.&amp;lt;/translate&amp;gt;|type=serious}}&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:15--&amp;gt;&lt;br /&gt;
# Make a note of any versions of Packages and Components currently running that you will be keeping on your site. You can copy/paste them into a document for reference.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:42--&amp;gt; # For any extensions you are keeping but don&#039;t use the Extension Manager to one-click update ({{rarr|Extensions,Manage,Update}}) update all extensions to the latest versions.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:43--&amp;gt; # Before and as you update, note if the extensions have both 3.10.x &amp;amp; 4.x versions in the same package. If so, they will be fine to &amp;quot;one-click update.&amp;quot; If not, and 3.10 and 4.x have different packages, look at them case by case. They will normally fall into one of the following scenarios:&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:44--&amp;gt; #* The extension has separate packages but upon upgrading to 4.x, they automatically detect this and still work. Make sure the developer confirms this.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:45--&amp;gt; #* The extension has separate packages that need to be uninstalled in 3.10.x and then installed with the Joomla 4.x version once the site is migrated. An example of this might be a content plugin. It is simple to uninstall it in 3.10.x and then install it again in 4.x.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:46--&amp;gt; #* See [[S:MyLanguage/Template_Considerations_During_Migration|Template Considerations]] for more specific information on templates and [[S:MyLanguage/J3.x:Converting_A_Previous_Joomla!_Version_Template|Converting a previous Joomla! Version template]]&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Search (com_search) ==== &amp;lt;!--T:32--&amp;gt;&lt;br /&gt;
Search (com_search) will be decoupled in Joomla 4.x. Search (com_search) will migrate to Joomla 4. After migration, you&#039;ll need to update it to the Joomla 4.x version via com_installer. It will continue to be maintained, but more the same way a third-party extension is by receiving updates via com_installer. It is recommended to use Smart Search (com_finder) going forward. Search will still be available at https://extensions.joomla.org/category/official-extensions/.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Weblinks ==== &amp;lt;!--T:33--&amp;gt;&lt;br /&gt;
Weblinks was decoupled back in Joomla 3.4. If it was in use on a 2.5 site, the migration process would note this and migrate the Weblinks component and data. For the migration from 3.10.x to 4.x, it will be the same. It is still available and maintained on the JED at [https://extensions.joomla.org/category/official-extensions/ Official Extensions].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==== Notes on Legacy Routing ==== &amp;lt;!--T:64--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:65--&amp;gt; Legacy routing will not be available in Joomla 4.x. Only Modern will be available. When you do the migration, if you are using Legacy routing, the system will automatically change them to Modern routing. You will want to run a broken link checker on your site after migrating to Joomla 4.x and &#039;&#039;before you go live&#039;&#039;.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Going to Joomla! 4.x === &amp;lt;!--T:16--&amp;gt;&lt;br /&gt;
Once you have either updated or uninstalled your third-party extensions so that only those compatible with Joomla! 4 remain in your installation, continue with the following steps:&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:17--&amp;gt;&lt;br /&gt;
# Go to {{rarr|System,Global Configuration,Server tab}} and turn Error Reporting from System Default to Maximum. Make sure to Save &amp;amp; Close.&amp;lt;/translate&amp;gt;{{-}} [[File:J310-system-global-config-server-tab-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:18--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|500px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:19--&amp;gt;&lt;br /&gt;
# Take another backup.&lt;br /&gt;
# Go to {{rarr|Components,Joomla Update}}. (It should say no updates found. If it doesn’t, update Joomla to the latest version and test. Then do another backup.) Click on the Options button at the top right corner.&lt;br /&gt;
# Select &#039;&#039;Joomla Next&#039;&#039; from the drop-down for Update Channel.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-component-joomla-update-select-support-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:20--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|500px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:21--&amp;gt;&lt;br /&gt;
# Click Save &amp;amp; Close.&lt;br /&gt;
# You will then see your Installed Joomla Version, the Latest Joomla! version and the URL for the update package. Joomla will show you the requirements again for Joomla 4. If it flags that you have either an incompatible system or extensions it will tell you here. Take a moment to review this page.&amp;lt;/translate&amp;gt;{{-}}[[File:J310-to-j4-dev-update-found-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:22--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:23--&amp;gt;&lt;br /&gt;
# If the update is not showing up, go to {{rarr|Extension manager,Update}} and press Purge Cache from the toolbar. Now the update to Joomla! 4 should show up.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:47--&amp;gt; # Cross your fingers, and make sure you have that backup available in case.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:48--&amp;gt; # Click the Install the Update button.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:49--&amp;gt; # Make tea whilst the status bar loads to fully green. The amount of time this takes is dependent on your site, Internet connection and server speed. The process takes about two minutes. When the update is finished, you will probably be logged out of the Administrator. Sign in again. Twice.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:50--&amp;gt; # If all goes well, you will get to a totally new look to the Backend panel.&amp;lt;/translate&amp;gt;{{-}}[[File:j4-administrator-overview-&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:24--&amp;gt;&lt;br /&gt;
en&amp;lt;/translate&amp;gt;.png|border|800px]]&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:51--&amp;gt; # Go to {{rarr|System,Maintenance,Database}} and click &#039;&#039;Fix&#039;&#039; if any errors show.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:52--&amp;gt; # In {{rarr|System,Install,Discover}} see if there are any extensions to install. (There shouldn&#039;t be any!)&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:53--&amp;gt; # Go to the Frontend of your site and see if it shows up even if it’s not the right template. If so, continue. If not, see [[S:MyLanguage/Joomla 3.10 to 4.x Common Migration Errors|common errors during migration]].&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:54--&amp;gt; # Take a backup.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:55--&amp;gt; # Install your new template or other extensions if you have them to install. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:56--&amp;gt; # Configure them. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:61--&amp;gt; # Run a broken link checker and fix any broken links.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:57--&amp;gt; # Test everything. Back up often.&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:58--&amp;gt;&lt;br /&gt;
# If everything works as expected, turn Error Reporting back to System Default ({{rarr|System,Global Configuration,Server tab}}). Make sure to Save &amp;amp; Close.&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
=== Going Live with Your Joomla! 4.x Site === &amp;lt;!--T:26--&amp;gt;&lt;br /&gt;
# When you’re ready to go live, back up your 3.10 site for the last time. Restore it in a subdirectory or subdomain if you would like to.&lt;br /&gt;
# Back up your Joomla! 4.x site and move or restore your Joomla! 4.x site to the root (or change nameservers if you were building on a temporary domain at a new hosting account root).&lt;br /&gt;
# Test again.&lt;br /&gt;
# &#039;&#039;&#039;If&#039;&#039;&#039; you have made security changes to &#039;&#039;.htaccess&#039;&#039; file in the past, you may need to change a line (or lines) in it to update to Joomla 4. Please go to [https://docs.joomla.org/Htaccess_changes_after_joomla4.0.4 Htaccess changes after joomla4.0.4] to determine if you need to change your file. &lt;br /&gt;
# Remove the Joomla! 3.10 site from the server within a couple of days unless you have edited your &#039;&#039;robots.txt&#039;&#039; file to block the search engine spiders and disabled the Frontend of the site.&lt;br /&gt;
# Remove all development sites you have been working with or keep them up-to-date if they are running a current version in order to ward off hack attempts on your server. &amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:27--&amp;gt;&lt;br /&gt;
If you had data change on the 3.10 site while you were migrating to 4.x, you will want to get that data moved over to the 4.x site before going live. You can do this manually (make sure you keep the same user IDs - go in order) or by using a [https://extensions.joomla.org/category/migration-a-conversion/data-import-a-export%20transfer%20tool/third-party%20extension/ third party extension].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
== Suggested Tools == &amp;lt;!--T:28--&amp;gt;&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&amp;lt;!--T:66--&amp;gt;&lt;br /&gt;
* [http://extensions.joomla.org/extensions/access-a-security/site-security/backup/1606 Akeeba Backup] is popular for backup and restore. See more [https://extensions.joomla.org/tags/backup/ backup tools].&lt;br /&gt;
&amp;lt;/translate&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
==Related information== &amp;lt;!--T:62--&amp;gt; &amp;lt;/translate&amp;gt;&lt;br /&gt;
[[Special:MyLanguage/:Pre-Update_Check|&amp;lt;translate&amp;gt;&amp;lt;!--T:63--&amp;gt; Pre-Update_Check&amp;lt;/translate&amp;gt;]]&lt;br /&gt;
&amp;lt;noinclude&amp;gt;&lt;br /&gt;
&amp;lt;translate&amp;gt;&lt;br /&gt;
&amp;lt;!--T:29--&amp;gt;&lt;br /&gt;
[[Category:Migration{{#translation:}}]]&lt;br /&gt;
[[Category:Tutorials{{#translation:}}]]&lt;br /&gt;
[[Category:Joomla! 4.x{{#translation:}}]]&lt;br /&gt;
&amp;lt;/translate&amp;gt;&amp;lt;/noinclude&amp;gt;&lt;/div&gt;</summary>
		<author><name>Cmb</name></author>
	</entry>
</feed>