RTC PR-6.0-dev Pending

User tests: Successful: Unsuccessful:

avatar bembelimen
bembelimen
7 Dec 2024

Summary of Changes

Currently the usage of form field layouts is very encapsulated in the FormField class, which means that it's not possible to change/add additional layout include paths via e.g. plugins.

There are two ways to add an alternative path

  1. via XML attribute "layoutIncludePath"
  2. via the $option attribute in the ->renderField(...) or ->renderFieldset(...) methods

Testing Instructions

There are several ways to test this PR, one would be to create a plugin and manipulate the form with the onContentPrepareForm event.

But to the test the raw functionality you can do the following:

  • Create a folder "otherlayouts" in your Joomla! root
  • Add the following folder structure joomla/form to the "otherlayouts" folder
  • Copy the file layouts/joomla/form/renderfield.php to the new path
  • Change this file somehow to see the difference when it's loaded (e.g. add some output like "Hello World" somewhere in the file)
  • We will test now at the frontend registration, so open the form

Option 1:

  • Open components/com_users/forms/registration.xml
  • Add after line 17 the following attribute: layoutIncludePath="otherlayouts" (it should be in the "name" field)
  • Refresh registration, now you should see the "Hello World" from above at the "name" field

Option 2:

  • Open components/com_users/tmpl/registration/default.php
  • Change line 44 to: <?php echo $this->form->renderFieldset($fieldset->name, ['layoutIncludePath' => JPATH_ROOT . '/otherlayouts/']); ?>
  • Refresh registration, now you should see the "Hello World" from above at each field
- Refresh registration, now you should see the "Hello World" from above at a "name" field

### Actual result BEFORE applying this Pull Request
- No alternative layout path possible


### Expected result AFTER applying this Pull Request
- Alternative layout path possible
avatar bembelimen bembelimen - open - 7 Dec 2024
avatar bembelimen bembelimen - change - 7 Dec 2024
Status New Pending
avatar joomla-cms-bot joomla-cms-bot - change - 7 Dec 2024
Category Libraries
avatar bembelimen bembelimen - change - 7 Dec 2024
The description was changed
avatar bembelimen bembelimen - edited - 7 Dec 2024
avatar bembelimen bembelimen - change - 7 Dec 2024
The description was changed
avatar bembelimen bembelimen - edited - 7 Dec 2024
avatar bembelimen bembelimen - change - 7 Dec 2024
Labels Added: PR-5.3-dev
avatar brianteeman
brianteeman - comment - 7 Dec 2024

If I understand this correctly (and I'm not certain that I do) this will add a layout in a location that cannot be overriden by the template

avatar Fedik
Fedik - comment - 8 Dec 2024

I am not sure what you trying to do, but when you need such thing you doing something wrong πŸ˜‰

Developers already can set differemy layout per field with $field->layout = 'potato.input'
When you want custom renderLayout then it need something like I tried in past #42648 (can reopen), it is more inline with our general API.

avatar bembelimen
bembelimen - comment - 9 Dec 2024

If I understand this correctly (and I'm not certain that I do) this will add a layout in a location that cannot be overriden by the template

I guess the only missing area is the xml, so there a template call could be added. The other two options can be added by the plugin author.

I am not sure what you trying to do, but when you need such thing you doing something wrong πŸ˜‰

Load a form via com_ajax and a plugin. There is no way to provide any layout via the plugin when you add a new field by your own, because Joomla looks into com_ajax and the template, that's it.

avatar brianteeman
brianteeman - comment - 9 Dec 2024

If I understand this correctly (and I'm not certain that I do) this will add a layout in a location that cannot be overriden by the template

I guess the only missing area is the xml, so there a template call could be added. The other two options can be added by the plugin author.

A plugin author should not need to do anything in order for a template to create and use an override. There should be no dependence in the relationship

avatar Fedik
Fedik - comment - 9 Dec 2024

Load a form via com_ajax and a plugin. There is no way to provide any layout via the plugin when you add a new field by your own, because Joomla looks into com_ajax and the template, that's it.

For this case need to set Component and Client

public function setComponent($option)

However we cannot expose every possible options of the Layout Class to the Field class, it will be just bad.
For this we have FormField::getRenderer()

protected function getRenderer($layoutId = 'default')

Which developer can overdie in its field class, and set required options.
So if you have your own custom field, you can do exactly this πŸ˜‰

The approach suggested in the PR have other drawbacks and will not work in all cases, but that is to much to write :)

e6ee243 13 Dec 2024 avatar bembelimen CS
avatar LadySolveig
LadySolveig - comment - 17 Dec 2024

To be honest, I have exactly this particular problem. It feels much cleaner to me personally to be able to insert my Web Component directly into renderField as a wrapper around the standard fields instead of having to inherit every single standard field and then just overwrite the layout path. I don't want to reinvent the wheel, but simply extend the existing one. But then I'm probably doing something wrong. @Fedik πŸ˜‰

avatar Fedik
Fedik - comment - 18 Dec 2024

To solve the issue with renderField it better that way #42648 (comment) , or override the field layout.

The Form Field class should only recieve the layout ID, nothing else. And how it going to be rendered is defined by renderer inside getRenderer method. (Would be nice to think a way to define a global renderer per form, but that another topic)

Addittionaly, the getField() method always return new field instance, and so if you do $field->getField()->potato = 1 in the plugin, then in the rendering proces in View layout this value still will be default one, not what you have set in plugin.

avatar bembelimen bembelimen - change - 18 Apr 2025
Title
[5.3] Allow adding additional layout base path to form fields
[6.0] Allow adding additional layout base path to form fields
avatar bembelimen bembelimen - edited - 18 Apr 2025
avatar joomla-cms-bot joomla-cms-bot - change - 18 Apr 2025
Category Libraries Administration com_installer com_joomlaupdate com_media NPM Change Repository Installation Language & Strings
avatar bembelimen bembelimen - change - 18 Apr 2025
Labels Added: Language Change NPM Resource Changed PR-6.0-dev
avatar bembelimen bembelimen - change - 23 Apr 2025
Labels Removed: PR-5.3-dev
avatar joomla-cms-bot joomla-cms-bot - change - 23 Apr 2025
Category Administration com_installer com_joomlaupdate com_media NPM Change Repository Installation Language & Strings Libraries
avatar HLeithner HLeithner - test_item - 30 Jun 2025 - Tested successfully
avatar HLeithner
HLeithner - comment - 30 Jun 2025

I have tested this item βœ… successfully on 4615028

Since I had the same use case and came up with a similar solution, I tested it with my code and this PR works as expected. thanks.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/44590.

avatar bembelimen bembelimen - change - 31 Jul 2025
Labels Removed: Language Change NPM Resource Changed
avatar Fedik
Fedik - comment - 14 Aug 2025

@bembelimen here still need few fixes.

Remove following

$app = Factory::getApplication();
if ($app->isClient('site') || $app->isClient('administrator')) {
// Try to get a default template
$template = $app->getTemplate(true);
// Use unshift to use a lower priority
array_unshift($this->layoutPaths, JPATH_THEMES . '/' . $template->template . '/html/' . ltrim((string) $value, '/'));
if (!empty($template->parent)) {
array_unshift($this->layoutPaths, JPATH_THEMES . '/' . $template->parent . '/html/' . ltrim((string) $value, '/'));
}
}
// Use unshift to use a lower priority
array_unshift($this->layoutPaths, JPATH_ROOT . '/' . ltrim((string) $value, '/'));

And replace it with:

$this->layoutIncludePaths = explode(',', (string) $value);

Also add a getter for this property.

Remove addLayoutPath method.
As we talked this not going to work reliable. The configuration should be done via attribute.

public function addLayoutPath(string $path): bool

Then it should be workable solution and probably even will pass the tests πŸ˜‰

avatar bembelimen bembelimen - change - 15 Aug 2025
The description was changed
avatar bembelimen bembelimen - edited - 15 Aug 2025
avatar bembelimen
bembelimen - comment - 15 Aug 2025

@Fedik thanks!

avatar Fedik
Fedik - comment - 15 Aug 2025

Thanks, that looks better.
Few more things.

What is needed to achieve that User can do:

$layouts = $field->layoutPaths;
$layouts[] = 'path1';
$layouts[] = 'path2';
$field->layoutPaths = $layouts;

For this still need few more changes.
Do not use array_unshif and JPATH_ROOT in the setter

case 'layoutIncludePath':
$this->layoutPaths = [];
$values = explode(',', (string) $value);
foreach ($values as $path) {
// Use unshift to use a lower priority
array_unshift($this->layoutPaths, JPATH_ROOT . '/' . ltrim((string) $path, '/'));
}
break;

Just do:

$this->layoutPaths = is_array($value) ? $value : explode(',', (string) $value);

Add JPATH_ROOT in getLayoutPaths() where you actually add these paths to defaults.

protected function getLayoutPaths()

avatar bembelimen
bembelimen - comment - 15 Aug 2025

$this->layoutPaths = is_array($value) ? $value : explode(',', (string) $value);

Now it makes sense for me :-) Changed + Thanks again

avatar LadySolveig LadySolveig - test_item - 15 Aug 2025 - Tested successfully
avatar LadySolveig
LadySolveig - comment - 15 Aug 2025

I have tested this item βœ… successfully on 5e52ced


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/44590.

avatar exlemor exlemor - test_item - 15 Aug 2025 - Tested successfully
avatar exlemor
exlemor - comment - 15 Aug 2025

I have tested this item βœ… successfully on 2a11f1e

I have successfully tested this! Thank @bembelimen @LadySolveig @softforge @Bodge-IT


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/44590.

avatar exlemor exlemor - alter_testresult - 15 Aug 2025 - @LadySolveig: Tested successfully
avatar exlemor exlemor - change - 15 Aug 2025
Status Pending Ready to Commit
avatar exlemor
exlemor - comment - 15 Aug 2025

RTC


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/44590.

avatar Bodge-IT Bodge-IT - change - 15 Aug 2025
Status Ready to Commit Fixed in Code Base
Closed_Date 0000-00-00 00:00:00 2025-08-15 15:39:26
Closed_By Bodge-IT
Labels Added: RTC
avatar Bodge-IT Bodge-IT - close - 15 Aug 2025
avatar Bodge-IT Bodge-IT - merge - 15 Aug 2025
avatar Bodge-IT
Bodge-IT - comment - 15 Aug 2025

Thanks @bembelimen for this work and thanks @LadySolveig and @exlemor for testing.

avatar dgrammatiko
dgrammatiko - comment - 15 Aug 2025

So this adheres to the override mechanism for layouts? I hope it does because if the dev should dictate the front end code then something is really wrong…

Add a Comment

Login with GitHub to post a comment