- Issue created by @pdureau
- 🇫🇷France pdureau Paris
First commit: https://git.drupalcode.org/issue/ui_patterns_settings-3345071/-/commit/3...
Already working well. Tested with:
- ui_pattern_settings 2.x
- ui_suite_bootstrap 4.0.x
- layout_builder 10.0.x
- ui_patterns_pattern_block (with a change in info.yml)
Next steps:
- Inetgration with breadcrumb
- Do we need
$this->handleInput([$form_id], $def, $form_type);
- Why the pattern preview doesn't work anymore?
- 🇫🇷France pdureau Paris
Is it possible to also manage pager (pagination) components with this plugin?
Like menu and breadcrumb, pagers have a strict structure of links and labels, so they belongs to props but are still managed as slots.
Sub-sub elements: items.first, items.previous, items.next, items.last, and each item inside items.pages contain the following elements:
- href: URL with appropriate query parameters for the item.
- attributes: A keyed list of HTML attributes for the item.
- text: The visible text used for the item link, such as "‹ Previous" or "Next ›".
Source: https://api.drupal.org/api/drupal/core!modules!system!templates!pager.ht...
Other: https://api.drupal.org/api/drupal/core!modules!views!templates!views-min...Example: https://git.drupalcode.org/project/ui_suite_bootstrap/-/blob/5.0.x/templ...
Only one field with a 2 level structure:
fields: items: type: "array" label: "Pagination items." preview: first: href: "#" text: "« First" previous: href: "#" text: "‹ Previous" next: href: "#" text: "Next ›" last: href: "#" text: "Last »" pages: 1: href: "#" text: "1" 2: href: "#" text: "2" 3: href: "#" text: "3"
Example: https://git.drupalcode.org/project/ui_suite_material/-/blob/2.0.x/templa...
One field for each first level, a flat structure inside each:
fields: first: type: array label: First description: "Item for the first page; not present on the first page of results." preview: null previous: type: array label: Previous description: "Item for the previous page; not present on the first page of results." preview: null next: type: array label: Next description: "Item for the next page; not present on the last page of results." preview: href: "#" text: Page 5 last: type: array label: Last description: "Item for the last page; not present on the last page of results." preview: href: "#" text: Page 10
Example: https://git.drupalcode.org/project/ui_suite_dsfr/-/blob/1.0.x/templates/...
Same as Bootstrapfields: items: type: array label: Items description: "Pagination items. The list is keyed by the following elements: - first: Item for the first page. - previous: Item for the previous page. - next: Item for the next page. - last: Item for the last page. - pages: List of pages, keyed by page number." preview: pages: 1: href: '#page1' 2: href: '#page2' 3: href: '#page3' 4: href: '#page4' 5: href: '#page5' first: href: '#first' last: href: '#last' next: href: '#next' previous: href: '#prev'
- 🇫🇷France Grimreaper France 🇫🇷
Hi,
About pager, if the structure is ok, why not. But I am surprised of that.
Also will the plugin will not be too complicated and would it not be better to split into 3 plugins (also to have different settings options)?
- menus
- depth of items shown
- starting level
- breadcrumb
- add home link?
- display current page as title?
- pager
- number of items displayed?Because also technically when loading the links it is 3 different services:
- menu
- breadcrumb builder
- pager manager - 🇫🇷France pdureau Paris
I would prefer to try without splitting the plugin first. I know it will be complicated, but it seems better to keep complexity here, in a stable generic codebase, and offer to the templates builder a single data structure.
This data structure will be a list of link items, optionally multi-levels. In a perfect world, they make their templates with this single structure, without overthinking, and the site builder decide which components they use for menus, breadcrumbs and pagers.
- Status changed to Needs work
over 1 year ago 10:15am 4 May 2023 - 🇫🇷France Grimreaper France 🇫🇷
Hi,
Thanks both for the work done here, code and review.
I have added my comments.
pager part not implemented yet or did I miss something?
I hope to be able to help @pdureau with the implementation if needed (not only for pager, I mean).
- Issue was unassigned.
- Status changed to Needs review
over 1 year ago 10:05pm 21 June 2023 - 🇫🇷France pdureau Paris
"menu" setting type is renamed "links" because it targets also breadcrumbs and pagers
- Status changed to Needs work
over 1 year ago 2:35pm 5 September 2023 - 🇫🇷France pdureau Paris
Some news about the current work
Pierre's proposal
MR: https://git.drupalcode.org/project/ui_patterns_settings/-/merge_requests...
Naming
The setting type is called "menu" but we want "links"
Data structure
We followed the Drupal menu structure https://api.drupal.org/api/drupal/core!modules!system!templates!menu.htm...
With addition of link_attributes property (extracted from Url::getOptions()):
attributes: HTML attributes for the menu item.
below: The menu item child items.
title: The menu link title.
link_attributes: HTML attributes for the link
url: The menu link URL as string
localized_options: Menu link localized options.
is_expanded: TRUE if the link has visible children within the current menu tree.
is_collapsed: TRUE if the link has children within the current menu tree that are not currently visible.
in_active_trail: TRUE if the link is in the active trail.Same data structure for menus, links (for example language switcher), breadcrumb & pagers (system and views)
The plugin is doing the conversion. We took menu as base because it is the more capable.Challenge
Cache management was tricky but we did it successfully with: PatternSettingBase::alterElement()
Twig filter
The controversial part. We introduced |convertToMenu() (TODO: rename to |normalizeLinks()) filter to do the conversion from presenter templates.
IMHO, it is OK to have such a filter because never used in components templates
Christian's rewrite
Branch: https://git.drupalcode.org/project/ui_patterns_settings/-/tree/ISSUE-334...
Naming
The setting type is called "link_lists", it is better than "menu" but IMHO "links" is even better.
New plugin type: SettingDataProvider
https://git.drupalcode.org/project/ui_patterns_settings/-/tree/ISSUE-334...
breadcrumb and menu are implemented with this plugin type, so the SettingType plugin is lighter
That's great because it is kind of similar to the target architecture of Ui Patterns 2 (source plugins more powerful and compatible with props) .
Issues
Where is the code related to pagers and links ? Maybe we need to add them as SettingDataProvider and add an optional context mechanism in this plugin type (like UI Patterns Source plugins)
The Twig filter is missing. I know it is not nice but we need to find a way to accomodate presenter template. Maybe we can introduce a public static method in the setting type plugin, which will be easy to use in preprocess hooks inside each theme.
- Assigned to pdureau
- @pdureau opened merge request.
- Status changed to Needs review
about 1 year ago 4:36pm 20 October 2023 - 🇫🇷France pdureau Paris
A new MR based on Christian's rewrite: https://git.drupalcode.org/project/ui_patterns_settings/-/merge_requests/16
The Twig filter is not here anymore, so front developers will need to do preprocess in order to convert the links structure.
Examples:
use Drupal\ui_patterns_settings\Plugin\UiPatterns\SettingType\LinksSettingType; function ui_suite_bootstrap_preprocess_breadcrumb(array &$variables): void { $variables["breadcrumb"] = LinksSettingType::normalize($variables["breadcrumb"]); } function ui_suite_bootstrap_preprocess_pager(array &$variables): void { $variables["items"] = LinksSettingType::normalize($variables["items"]); } function ui_suite_bootstrap_preprocess_links(array &$variables): void { $variables["links"] = LinksSettingType::normalize($variables["links"]); } ...
I think it is OK to have such preprocess because they are:
- one line only, no business
- not targeting patterns
- 🇫🇷France pdureau Paris
Before we merge, I would like to discuss a bit about the links data structure.
We decided, and implemented, that:
- this data structure will be the same as the one in menu.html.twig, with only one property more:
link_attributes
, because it is the more capable - we transform pager, mini pager, links and breadcrumb structure to the expected data structure
However, #3227824: Move the linkset functionality from the decoupled menus contributed module to core's system module → tell us about an IETF's proposed linkset format already used by JSON API to avoid creating too many drupalism.
Example:
{ "linkset": [ { "anchor": "http://example.net/bar", "next": [ {"href": "http://example.com/foo", "type": "text/html", "hreflang": [ "en" , "de" ], "title": "Next chapter", "title*": [ { "value": "nachstes Kapitel" , "language" : "de" } ] } ] } ] }
However, expected properties are not easily mappable:
- attributes: HTML attributes for the menu item. >> ???
- below: The menu item child items. >> The linkset media type is not hierarchical. LinksetController::toLinkTargetObjects is creating a weird
hierarchy
structure instead - title: The menu link title. >>
title
- link_attributes: HTML attributes for the link >> All properties except the ones defined. See LinksetController::processCustomLinkAttributes
- url: The menu link URL as string >>
href
And additional properties, sometimes used by components authors, are not mappable at all:
- localized_options: Menu link localized options. >> ???
- is_expanded: TRUE if the link has visible children within the current menu tree. >> ???
- is_collapsed: TRUE if the link has children within the current menu tree that are not currently visible. >> ???
- in_active_trail: TRUE if the link is in the active trail. >> ???
- this data structure will be the same as the one in menu.html.twig, with only one property more:
- 🇩🇪Germany Christian.wiedemann
Christian.wiedemann → made their first commit to this issue’s fork.
-
Christian.wiedemann →
committed de191f7c on 8.x-2.x authored by
pdureau →
Resolve #3345071 "Pierre proposal"
-
Christian.wiedemann →
committed de191f7c on 8.x-2.x authored by
pdureau →
- Status changed to Fixed
about 1 year ago 1:14pm 27 October 2023 - Issue was unassigned.
- Status changed to Needs work
about 1 year ago 3:32pm 3 November 2023 - 🇫🇷France pdureau Paris
hi,
We have a little issue with previews, so i am reopening the ticket.
In this setting type, the data we are storing in the config is not the same as the data we are sending to the component.
For example:
We have a the PatternSettingTypeInterface::settingsPreprocess() method which is doing this job of converting.
However, sometimes, we don't want this conversion. We want the raw data. For example, when we take it from the preview in the definition YML file.
Today, there is no data returned, empty array, so I am proposing this fix:
--- a/src/Plugin/ComplexSettingTypeBase.php +++ b/src/Plugin/ComplexSettingTypeBase.php @@ -95,7 +95,7 @@ abstract class ComplexSettingTypeBase extends PatternSettingTypeBase implements $this->provider = $instance; return $instance->getData($value['configuration'][$provider_id]['config'] ?? []); } - return []; + return $value; } /**
Is it too naive?
- 🇫🇷France pdureau Paris
Other issue.
Those 2 imports are missing from LinksSettingType :
use Drupal\Core\Url; use Drupal\Core\Template\Attribute;
So, this hook is not working properly:
function template_preprocess_menu(array &$variables): void { $variables["items"] = LinksSettingType::normalize($variables["items"]); }
- Assigned to pdureau
- 🇫🇷France pdureau Paris
Other feedback.
While working on 📌 Bootstrap 5: Convert menu, breadcrumb and pagers to the links prop type Needs review , we found some changes to do useful for https://www.drupal.org/project/menu_link_attributes → integration (but not specific to this module, those changes may also be useful for other menu API integration).
I will propose a MR
- 🇫🇷France pdureau Paris
Other subject.
To define out links data structure, we have added
link_attributes
property to the Drupal menu data structure (see menu.html.twig).$item["options"] = $url->getOptions(); if (isset($options["attributes"])) { $item["link_attributes"] = new Attribute($options["attributes"]); }
Why not injecting directly
options
property? There are some stuff which can be useful in a template:'query': An array of query key/value-pairs (without any URL-encoding) to append to the URL.
'fragment': A fragment identifier (named anchor) to append to the URL. Do not include the leading '#' character.
'absolute': Defaults to FALSE. Whether to force the output to be an absolute link (beginning with http:). Useful for links that will be displayed outside the site, such as in an RSS feed.
'attributes': An associative array of HTML attributes that will be added to the anchor tag if you use the \Drupal\Core\Link class to make the link.
'language': An optional language object used to look up the alias for the URL. If $options['language'] is omitted, it defaults to the current language for the language type LanguageInterface::TYPE_URL.
'https': Whether this URL should point to a secure location. If not defined, the current scheme is used, so the user stays on HTTP or HTTPS respectively. TRUE enforces HTTPS and FALSE enforces HTTP.language
object must be resolved as a string - Issue was unassigned.
- Status changed to Needs review
about 1 year ago 7:13pm 16 November 2023 - 🇫🇷France pdureau Paris
Hello @christian, let's talk about this MR: https://git.drupalcode.org/project/ui_patterns_settings/-/merge_requests/18
- 🇫🇷France pdureau Paris
Tested with:
- UI Suite Bootstrap: 📌 Bootstrap 5: Convert menu, breadcrumb and pagers to the links prop type Needs review >> OK
- UI Suite DSFR: 📌 [beta6] Replace PHP hooks by more themer-friendly solutions Needs review >> OK
- UI Suite Material : 📌 [beta1] Props must be settings instead of fields Fixed >> OK
- Status changed to Fixed
about 1 year ago 8:44am 15 December 2023 Automatically closed - issue fixed for 2 weeks with no activity.