Joomla 3 & 4 Compatibility
These are the ways we’ve found to provide extensions that are compatible with both Joomla 3.8+ and Joomla 4.
Administration Templates
We have implemented view classes in our Joomlashack Framework that can choose templates based on the Joomla version. For example, in list views, default.j3.php
will be loaded in Joomla 3 while default.php
will be loaded by Joomla 4.
Note that subtemplate names for Joomla 3 may seem a bit odd, but do make a certain kind of sense: default.j3_subtemplate.php
Admin view classes should inherit from one of these two framework classes:
- Alledia\Framework\Joomla\View\Admin\AbstractList
- Alledia\Framework\Joomla\View\Admin\AbstractForm
Form Fields
Versioned layouts
If you need versioned layouts for a custom form field, you can add a trait from the framework. For example:
class OsmapFormFieldMenus extends FormField
{
use \Alledia\Framework\Joomla\Form\Field\TraitLayouts;
protected $layout = 'osmap.menus';
}
This will automatically look for either osmap/menus_j3.php
or osmap/menus.php
in a layouts
folder in the same directory as the class file defining the custom form field.
Joomla 4 layout attribute
Joomla 4 now implements special layouts via the ‘layout’ attribute of the <field> tag. To provide the same behaviors in Joomla 3 and Joomla 4, use the following markup that will work in both Joomlas.
Field Type | Markup |
---|---|
Radio 0/1, Yes/No | <field type="radio" class="btn-group btn-group-yesno" layout="joomla.form.field.radio.switcher"> <option value="0">JNO</option> <option value="1">JYES</option> </field>Note that the '0' value option MUST be first |
List 0/1, colorized | <field type="list" class="chzn-color chzn-color-state form-select-color-state"> <option value="0">zero text</option> <option value="1">one text</option> ... </field>Note that the '0' value option MUST be first |
Advanced Lists | These were automatic in Joomla 3. To get the same display/behavior in Joomla 4, the following works for both:<field type="list" layout="joomla.form.field.list-fancy-select"/>For grouped lists: <field type="list" layout="joomla.form.field.groupedlist-fancy-select"/> |
Sliders, Tabs, Tooltips and Modals
Structure | Joomla 3 | Joomla 4 |
---|---|---|
Sliders | HTMLHelper::_('bootstrap.startAccordion') HTMLHelper::_(‘bootstrap.addSlide’) HTMLHelper::_(‘boostrap.endSlide’) | |
Tabs | HTMLHelper::_(‘bootstrap.startTabSet’) HTMLHelper::_(‘bootstrap.addTab’) HTMLHelper::_(‘bootstrap.endTab’) HTMLHelper::_(‘bootstrap.endTabSet’) | HTMLHelper::_('uitab.startTabSet') HTMLHelper::_('uitab.addTab') HTMLHelper::_('uitab.endTab') HTMLHelper::_('uitab.endTabSet') |
Tooltips | HTMLHelper::_('bootstrap.tooltip', '.hasTooltip') J4 does not default the selector. Our framework provides a simpified way to build tooltips that does all the common work: HTMLHelper::_('alledia.tooltip') | |
Modal Popups | There are numerous differences between J3 and J4. We've created a Joomla version agnostic modal helper: HTMLHelper::_('alledia.renderModal') See the code for recognized option settings. |
Sortable Tables
Given an array:
$items = ['ONE', 'TWO', 'THREE', 'FOUR'];
Joomla 3
To initialize the table:
HTMLHelper::_(
'sortablelist.sortable',
'table-sort',
'form-test',
'asc',
Joomla\CMS\Uri\Uri::current()
);
For this table markup:
<form id="form-test">
<table id="table-sort">
<tbody>
<?php foreach ($items as $row => $item) : ?>
<tr sortable-group-id="<ID>">
<td>
<span class="sortable-handler">
<i class="icon-menu"></i>
</span>
</td>
<td>
<?php echo $item; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</form>
Notes:
- sortablelist requires the ajax url for saving order changes. We've used the current url in this example, which would be entirely useless in a real implementation.
- No additional markup is required in the table beyond the sortable-handler element.
- Optionally use sortable-group-id="<ID>" attribute on <tr> tags to limit sorting to a subset of the table rows.
Joomla 4
The setup:
HTMLHelper::_('draggablelist.draggable');
The table:
<table>
<tbody class="js-draggable"
data-url="<Ajax Ordering url>"
data-direction="asc"
data-nested="true">
<?php foreach ($items as $row => $item) : ?>
<tr data-draggable-group="<ID>">
<td>
<span class="sortable-handler">
<i class="icon-menu"></i>
</span>
</td>
<td>
<?php echo $item; ?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
Notes:
- The only markup required to make this work is the addition of js-draggable to the <tbody> element of the table.
- The sortable-handler element is only needed as a convenience. The entire row becomes the handler.
- data-url and data-direction are required for saving changes after dropping a moved element
- data-nested and data-draggable-group are only needed when dragging/sorting need to be limited to a subgroup. e.g. items in the same category.