Update J3 component to J4

From Joomla! Documentation

Revision as of 11:18, 6 May 2022 by MarkRS (talk | contribs) (Created page with "{{inprogressbyuser}} = Helpful Notes = Joomla 4 has been out long enough that I'm feeling guilty about not upgrading my (in-house) component. These are the notes i wish I'd h...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Helpful Notes[edit]

Joomla 4 has been out long enough that I'm feeling guilty about not upgrading my (in-house) component. These are the notes i wish I'd had as I work through this project. Hopefully they'll be helpful. Feel free (in fact, feel obliged) to let me know if there are errors, ommission, or... errr... anything else that should cause a change. I've been developing in Joomla for a long time, but I'm only just starting with J4.

General Points[edit]

It appears you can get away with making very minimal changes (eg see the MCE structure once it’s installed). This guide tries to go the whole way, making the component fully compliant to J4 standards.

Judging by the disparity between the documents I've found and what's actually in the released (core) code, it seems that things are still evolving, so a) it’s sometimes not clear what the current recommended usage is and b) this may become outdated as J4 evolves.

Again, let me know if something is (perhaps "no longer") correct.

Namespacing[edit]

Namespacing is very central to the new philosophy.

While it can be a little tedious, particularly during conversion, this is really helpful and "A Good Thing"(TM). If you need to know more details than I've got here, look at the docs.

Every file that declares a class should be namespaced. Put very simply, it allows us to ensure the correct classes are loaded, even if there are several that have the same name. We just specify the full path to pick the one we want. With our own code, it means we can use the same names that are in other places and still get the right one.

Allowing the same names to be used in different contexts means that you have to specify the name space that you want. That then means that whenever you want to use classes in your code that aren’t in the current namespace, you have to use its full name.

You can either write out its whole path at each point in the code that you use it, which makes for long code, or you can employ the “use” statement. At some point, normally at the top of your code, you write a use statement for the class you want and then whenever you refer to it you simply use the class name. For example to use the Factory class, at the head of your code include ```use Joomla\CMS\Factory;``` and then you can write Factory::{whatever-you-want} without needing to include the full path. This is equivalent to the previous use of JLoader, but simpler.

If you use two (or more) classes that have the same name but are from different namespaces, you can still use them by setting up aliases. For example



Get rid of “J” Lots of J3 entities have been called “J”-something, for example “Jfactory”. This is not longer the case. The example given becomes simply “Factory”. This doesn’t (seem to) hold for core language string naming though. Flip it! The previous rule for naming core entities often went (J){Type}{Client}, for example JcontrollerAdmin. The new naming goes, according to the previous note remove the J, and then flip those elements, so we have AdminController. Filesystem The new structure is (show it?) Most src files are now {unit}{type}, where previously they were {mything}{type}{unit}eg what was MythingControllerMyunit is now MyunitController. On case sensitive platforms (?), the case of file names needs to reflect the case of the class name. A spin off of this is that table classes and their files cannot have upper case letters anywhere except the first letter, so you can’t have a table clase like CompoundTableNameTable, it has to be CompoundtablenameTable.

Controller getModel $prefix now needs to reflect the “client” for this controller, either “Administrator” or “Site”(?) Form controllers (as opposed to list controllers) now extend the core class FormController rather than JcontrollerAdmin. Form controller same name as model helps => tables should be named in the singular (?)

Model Form models now extend the AdminModel class. The getTable method is no longer required (or valid).

Field (code implementing form field types used (eg) in form xml definitions) Class naming is brought in line with other classes, ie it doesn’t need to be preceded by “JformField”, simply followed by “Field”. Ie the old JformFieldMyType becomes MyTypeField. Extending the core class “ListField” means that JformHelper::loadFieldClass('list'); is now redundant. (?)

View Class naming Previous setup {UnitRef}{fill this in}. It’s now HtmlView! Convert the previous “JerrorRaiseError(500, implode('
', $errors); return false” to throw new GenericDataException(implode("\n", $errors), 500); (There’s that ol’ “switcheroo” thang again.) The sidebar thing is gone. Toolbar structure is now different. The ToolbarHelper still exists, without its previous J prefix of course, but it’s used for many fewer things, typically now just the title. Create a toolbar (actually get an instance of it) and use its methods to set it up. There are specific methods now rather than passing multiple parameters to the helper. Creating your own toolbar buttons is now “regular” not “custom”. Creating a modal is now a popupButton and not in “customButton”

Templates New filesystem position – to facilitate moving code away from the webserver root in future.

Changes due to new style / standard General Remove the message that goes with the ubiquitous “defined('_JEXEC') or die()”

Debugging notes The error “Call to a member function getGroup() on null” may mean the xml filter definition file is not present. Custom field types don’t work? Need to add the namespace prefix in the form definition file.

Specific changes Core classes to overload Type Old New List controller JControllerAdmin AdminController List mode JmodelAdmin ListModel List view (html) JViewLegacy (?) HtmlView Form controller JControllerForm FormController Form model JModelAdmin FormModel Form view (html) JViewLegacy (?) HtmlView