|
21 | 21 | use Joomla\Database\DatabaseAwareTrait; |
22 | 22 | use Joomla\Database\DatabaseInterface; |
23 | 23 | use Joomla\Database\Exception\DatabaseNotFoundException; |
| 24 | +use Joomla\Filesystem\Path; |
24 | 25 | use Joomla\Registry\Registry; |
25 | 26 | use Joomla\String\Normalise; |
26 | 27 | use Joomla\String\StringHelper; |
@@ -398,6 +399,14 @@ abstract class FormField implements DatabaseAwareInterface, CurrentUserInterface |
398 | 399 | */ |
399 | 400 | protected $renderLabelLayout = 'joomla.form.renderlabel'; |
400 | 401 |
|
| 402 | + /** |
| 403 | + * Additional layout paths to look for layout files |
| 404 | + * |
| 405 | + * @var array |
| 406 | + * @since __DEPLOY_VERSION__ |
| 407 | + */ |
| 408 | + protected $layoutPaths = []; |
| 409 | + |
401 | 410 | /** |
402 | 411 | * The data-attribute name and values of the form field. |
403 | 412 | * For example, data-action-type="click" data-action-type="change" |
@@ -474,6 +483,7 @@ public function __get($name) |
474 | 483 | case 'validationtext': |
475 | 484 | case 'showon': |
476 | 485 | case 'parentclass': |
| 486 | + case 'layoutPaths': |
477 | 487 | return $this->$name; |
478 | 488 |
|
479 | 489 | case 'input': |
@@ -591,6 +601,10 @@ public function __set($name, $value) |
591 | 601 | $this->$name = (int) $value; |
592 | 602 | break; |
593 | 603 |
|
| 604 | + case 'layoutIncludePath': |
| 605 | + $this->layoutPaths = \is_array($value) ? $value : explode(',', (string) $value); |
| 606 | + break; |
| 607 | + |
594 | 608 | default: |
595 | 609 | // Detect data attribute(s) |
596 | 610 | if (str_starts_with($name, 'data-')) { |
@@ -658,7 +672,7 @@ public function setup(\SimpleXMLElement $element, $value, $group = null) |
658 | 672 | $attributes = [ |
659 | 673 | 'multiple', 'name', 'id', 'hint', 'class', 'description', 'labelclass', 'onchange', 'onclick', 'validate', 'pattern', 'validationtext', |
660 | 674 | 'default', 'required', 'disabled', 'readonly', 'autofocus', 'hidden', 'autocomplete', 'spellcheck', 'translateHint', 'translateLabel', |
661 | | - 'translate_label', 'translateDescription', 'translate_description', 'size', 'showon', ]; |
| 675 | + 'translate_label', 'translateDescription', 'translate_description', 'size', 'showon', 'layoutIncludePath']; |
662 | 676 |
|
663 | 677 | $this->default = isset($element['value']) ? (string) $element['value'] : $this->default; |
664 | 678 |
|
@@ -1060,7 +1074,13 @@ public function renderField($options = []) |
1060 | 1074 |
|
1061 | 1075 | $data = array_merge($this->collectLayoutData(), $data); |
1062 | 1076 |
|
1063 | | - return $this->getRenderer($this->renderLayout)->render($data); |
| 1077 | + $renderer = $this->getRenderer($this->renderLayout); |
| 1078 | + |
| 1079 | + if (isset($options['layoutIncludePath']) && is_dir(Path::check($options['layoutIncludePath']))) { |
| 1080 | + $renderer->addIncludePaths($options['layoutIncludePath']); |
| 1081 | + } |
| 1082 | + |
| 1083 | + return $renderer->render($data); |
1064 | 1084 | } |
1065 | 1085 |
|
1066 | 1086 | /** |
@@ -1372,7 +1392,13 @@ protected function getLayoutPaths() |
1372 | 1392 | { |
1373 | 1393 | $renderer = new FileLayout('default'); |
1374 | 1394 |
|
1375 | | - return $renderer->getDefaultIncludePaths(); |
| 1395 | + $paths = $renderer->getDefaultIncludePaths(); |
| 1396 | + |
| 1397 | + foreach ($this->layoutPaths as $path) { |
| 1398 | + array_unshift($paths, JPATH_ROOT . '/' . ltrim((string) $path, '/')); |
| 1399 | + } |
| 1400 | + |
| 1401 | + return $paths; |
1376 | 1402 | } |
1377 | 1403 |
|
1378 | 1404 | /** |
|
0 commit comments