User tests: Successful: Unsuccessful:
Pull Request for Issue #NULL .
Add a way to have the templateDetails.xml drive the entirety (basically the menu_assignment tab) of the style view.
So, right now the style edit layout has a hardcoded sub layout for the users to select the menus that the template style should be applied. If a developer/template author needs to roll their own menu selecting logic/UI/UX they have to create a plugin, observe the option/view, etc and override the layout. This is way too painful and limiting. Thus this PR, building on the fundamentals of Joomla (basically form fields) allows a way simpler way for devs to roll their own UI/UX (obviously as this is based on form fields it will require AJAX functionality but then again who's not building AJAX first UI in 2023?)
administrator/index.php?option=com_templates&view=styles
Cassiopeia - Default
link (or any other style-template in the list)Menu Assignment
</fields>
(line 221) add:<fields name="assigned">
<fieldset name="assigned" addfieldprefix="Joomla\Component\Templates\Administrator\Field">
<field name="assigned" type="menus" />
</fieldset>
</fields>
Also create a file administrator/components/com_templates/src/Field/MenusField.php
with the following contents
<?php
namespace Joomla\Component\Templates\Administrator\Field;
use Joomla\CMS\Factory;
use Joomla\CMS\Form\Field\TextField;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Layout\LayoutHelper;
use Joomla\Component\Menus\Administrator\Helper\MenusHelper;
// phpcs:disable PSR1.Files.SideEffects
\defined('_JEXEC') or die;
// phpcs:enable PSR1.Files.SideEffects
class MenusField extends TextField
{
protected $type = 'Menus';
public function setup(\SimpleXMLElement $element, $value, $group = null)
{
// Make sure there is a valid FormField XML element.
if ((string) $element->getName() !== 'field'){
return false;
}
// Reset the input and label values.
$this->input = null;
$this->label = null;
// Set the XML element object.
$this->element = $element;
// Set the group of the field.
$this->group = $group;
$attributes = [
'multiple', 'name', 'id', 'hint', 'class', 'description', 'labelclass', 'onchange', 'onclick', 'validate', 'pattern', 'validationtext',
'default', 'required', 'disabled', 'readonly', 'autofocus', 'hidden', 'autocomplete', 'spellcheck', 'translateHint', 'translateLabel',
'translate_label', 'translateDescription', 'translate_description', 'size', 'showon'];
$this->default = isset($element['value']) ? (string) $element['value'] : $this->default;
// Set the field default value.
$this->value = $value;
// Lets detect miscellaneous data attribute. For eg, data-*
foreach ($this->element->attributes() as $key => $value) {
if (strpos($key, 'data-') === 0) {
// Data attribute key value pair
$this->dataAttributes[$key] = $value;
}
}
foreach ($attributes as $attributeName) {
$this->__set($attributeName, $element[$attributeName]);
}
// Allow for repeatable elements
// $repeat = (string) $element['repeat'];
// $this->repeat = ($repeat === 'true' || $repeat === 'multiple' || (!empty($this->form->repeat) && $this->form->repeat == 1));
// Set the visibility.
$this->hidden = ($this->hidden || strtolower((string) $this->element['type']) === 'hidden');
$this->parentclass = isset($this->element['parentclass']) ? (string) $this->element['parentclass'] : $this->parentclass;
// Add required to class list if field is required.
if ($this->required) {
$this->class = trim($this->class . ' required');
}
// Hide the label
$this->hiddenLabel = true;
$this->hidden = true;
return true;
}
public function getInput() {
// Initialise related data.
$menuTypes = MenusHelper::getMenuLinks();
$user = $this->getCurrentUser();
$app = Factory::getApplication();
$currentId = $app->input->getInt('id');
/** @var Joomla\CMS\WebAsset\WebAssetManager $wa */
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
$wa->useScript('com_templates.admin-template-toggle-assignment');
$html = '<label id="jform_menuselect-lbl" for="jform_menuselect">'. Text::_('JGLOBAL_MENU_SELECTION') . '</label>'
. '<div class="btn-toolbar">'
. '<button class="btn btn-sm btn-secondary jform-rightbtn" type="button" onclick="Joomla.toggleAll()">'
. '<span class="icon-square" aria-hidden="true"></span> ' . Text::_('JGLOBAL_SELECTION_INVERT_ALL') . '</button>'
. '</div>'
. '<div id="menu-assignment" class="menu-assignment">'
. '<ul class="menu-links">';
foreach ($menuTypes as &$type) {
$html .= '<li>'
. '<div class="menu-links-block">'
. '<button class="btn btn-sm btn-secondary jform-rightbtn mb-2" type="button" onclick=\'Joomla.toggleMenutype("' . $type->menutype . '")\'>'
. '<span class="icon-square" aria-hidden="true"></span> ' . Text::_('JGLOBAL_SELECTION_INVERT') . '</button>'
. '<h5>' . $type->title ?: $type->menutype . '</h5>';
foreach ($type->links as $link) {
$html .= '<label class="checkbox small" for="link' . (int) $link->value . '" >'
. '<input type="checkbox" name="jform[assigned][]" value="'
. (int) $link->value . '" id="link' . (int) $link->value . '"'
. (($link->template_style_id == $currentId) ? ' checked="checked"' : '')
. (($link->checked_out && $link->checked_out != $user->id) ? ' disabled="disabled"' : ' class="form-check-input chk-menulink menutype-' . $type->menutype . '"')
. '/>';
$html .= LayoutHelper::render('joomla.html.treeprefix', ['level' => $link->level]) . $link->text;
$html .='</label>';
}
$html .= '</div></li>';
}
$html .= '</ul></div>';
return $html;
}
}
administrator/index.php?option=com_templates&view=styles
Cassiopeia - Default
linkMenu Assignment
. Now you should have the same menus as beforeToo much code needed for such an easy task and too complicated for template authors
Please select:
Documentation link for docs.joomla.org:
No documentation changes for docs.joomla.org needed
Pull Request link for manual.joomla.org: joomla/Manual#222
No documentation changes for manual.joomla.org needed
@HLeithner could yo have a look at this one? Thanks
Category | ⇒ | Administration com_templates |
Status | New | ⇒ | Pending |
Yay - adding another option - always a popular decision.
Where did you see that another option
? I'm just making devs life easier: instead having to roll a plugin with a template now they could do it through the XML with a simple field.
What is the real world use case for adding this option
Obviously I have a use case thus the PR...
As far as I can see, adding the new option happens only in the testing instructions and is only for testing.
Maybe I misread the option part. I still think this needs to be justified with a real world use case. There is only one I am aware of and that was handled by the ext dev with documentation without any issue
I still think this needs to be justified with a real world use case
Yootheme are definitely overriding the menu assignment (at least they did last time I used one of their templates). Probably also JoomShaper and many other template studio out there. This is NOT an edge case...
You still dont explain why they are doing it. And presumably if they are then they have no problem that this pr is solving. /me confused
@brianteeman there's a why
section in the description explaining why I did this PR and what it solves (dropping a side plugin just to have this part of the UI overridden and allow the whole form/view be driven by the XML). Is there something more you want me to explain here?
I read the why - it doesnt really explain the usecase
Ok, let me try again.
So the route /administrator/index.php?option=com_templates&view=style&layout=edit&id=11
(where id is the style id) is just a render of the form driven from the <config>
part of the templateDetails.xml
of a template:
joomla-cms/templates/cassiopeia/templateDetails.xml
Lines 48 to 166 in 7957282
The only part that IS NOT driven by the XML and it is hardcoded is the menu assignment tab:
joomla-cms/administrator/components/com_templates/tmpl/style/edit.php
Lines 101 to 110 in 7957282
For a developer to roll their own UI/UX/Logic for the menu selection of a template style there is a requirement to write a plugin that will override the entirety of the layout just to have a rendering of the Menu Assignment
tab.
This PR just enables the Menu Assignment
tab to be rendered using the XML, in short devs don't have to roll a plugin anymore. That's all, 4 lines added all and all but an easier path to override something that is very hard to override in the current state!
Labels |
Added:
PR-5.0-dev
|
Basically I'm open for this change, but the way is too limited, normally we would render the complete fieldset and not a single field in a tab, like in joomla.edit.params or joomla.edit.fieldset so making this more generic would make more sense too me.
@HLeithner code (testing instructions) updated so now the XML could have a new fields
section and a fieldset named assigned
. All the fields in the mentioned fieldset would be rendered at the menu assignment tab.
Besides all I have a question regarding the title of this PR: What does “DX” stand for?
What does “DX” stand for
Developer eXperience
I tested this and see the Menu Assignment panel replaced with It works Yes/No panel. But I am left wondering how I would select a menu item for this particular template style. It seems I have to write code to render and process whatever form fields I use instead of the Menu Assignment stuff. And perhaps I might add another panel to keep the Menu Assignment and do something else as well. I don't really have enough experience to say any more.
This pull request has been automatically rebased to 5.1-dev.
Labels |
Added:
Feature
|
Labels |
Added:
PR-5.1-dev
|
I have tested this item ✅ successfully on 9f231fd
Tested still successfully regarding the description of the pr. I see the benefit, so it would be good if one from the template clubs can test here as well.
I have tested this item ✅ successfully on 5fd67e9
Status | Pending | ⇒ | Ready to Commit |
RTC
@dgrammatiko Please fix conflict. Thanks.
Labels |
Added:
RTC
Removed: PR-5.0-dev |
Done
@Razzo1987 can I have a decision here if this is gonna be merged for 5.1?
Thanks
@dgrammatiko Not yet, but we will give you an update in the next few days
Thank you for your work
Status | Ready to Commit | ⇒ | Fixed in Code Base |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2024-02-27 12:46:16 |
Closed_By | ⇒ | Razzo1987 |
Thank you very much @dgrammatiko !
Yay - adding another option - always a popular decision.
What is the real world use case for adding this option