PoC: https://www.drupal.org/sandbox/vaplas/contextual_outside.
Problem/Motivation
When the links are inside of context, it leads to a number of problems:
Problem 1. Unpleasant html
For example:
Possible html for such block:
<div class="animals">
<div class="animal">🦊</div>
.....
</div>
<style>
.animals { display: flex; }
.animal { /* cool border */ }
</style>
What Drupal does (not show a lot other wrappers, which can be remove via templates):
<div class="animals" [contextual-region-1]>
<div class="contextual-links" [contextual-id-1]></div>
<div class="wrapper">
<div class="animal" [contextual-region-2]>
<div class="contextual-links" [contextual-id-2]></div>
<div class="wrapper">🦊</div>
</div>
.....
</div>
</div>
Contextual links - it's great. And it's great that they are separated from the content (because their mix - leads to terrible results). But what do we pay for using them?
- Money, time, and health to port the layout from the non-drupal-world (and updates after each changes).
- Potential flaws after port (which we can not immediately notice).
- Overall complexity of the layout.
- Negative mood from such a boring work.
Problem 2. Tag limitation.
It is impossible to wrap item by tags like a, img, iframe, video, ...
. Either you need to complicate the html/css again, even to output simple image item, or item that is link.
Few issues about this:
- #2430901: Contextual links not working when wrapped in an <a> element
- and like an attempt to prevent negative results #2898875: Contextual links should not be added inside another link
But so many cases, where the item is full link (<a>
), or cannot have any child (<img>
).
Problem 3. Conflicts of styles.
I remember the issue (#2773431: Please make Contextual link 8 independent on block <a> color) where I was trying to explain, that using #id
and !important
in css rules is a bad practice. But you know, even correct styles can be problem for contextual links.
Example, this rule not contains any #id
.path-frontpage .main-content .region-content .node--type-article a {
font-size: 2em;
}
But it has a higher priority than rule from contextual module, like:
.free-contextual-link.contextual .contextual-links a {
font-size: small;
}
Also what about parameters that are not specified in the css rules of contextual module, and therefore can be redefined by any custom rules.
Proposed resolution
Move contextual links out of context.
So, what will change after the patch?
After the patch, the example from problem1 will take the following form:
<div class="animals" [contextual-region-1]>
<div class="wrapper">
<div class="animal" [contextual-region-2]>
<div class="wrapper">🦊</div>
</div>
.....
</div>
</div>
.....
<div class="contextual-links" [contextual-id-1]></div>
<div class="contextual-links" [contextual-id-2]></div>
Therefore, after manually changing the templates, it will take the following form:
<div class="animals" [contextual-region-1]>
<div class="animal" [contextual-region-2]>🦊</div>
.....
</div>
.....
<div class="contextual-links" [contextual-id-1]></div>
<div class="contextual-links" [contextual-id-2]></div>
🎉
What about Backwards Compatibility?
No problems. Just make it optional:
- Checkbox1: Enable new regim. Works only if html does not contain "traditional" contextual links. For example, after removing
{{ title_suffix }}
, or unsetcontextual_links
viahook_preprocess
. - Checkbox2: Aggressive mode. Used when enabled new regim (checkbox1 checked). Removes all links via
contextual_preprocess
. It is convenient if you do not want to change templates, but want to switch to the outside contextual links.
Hard JS dependency?
Yes. But contextual module is already in hard dependence from JS, and does not work without it.
Of course, we will need to work out positioning and hovering. Since now it can not rely on the nesting css-rules. But I am sure, that by joint efforts we will be able to achieve results no worse, or even better, than current.
What about Quickedit and other
Perhaps more work is needed to enable quickedit for wrapper like <a>
. Maybe via preventing links behavior, while the quickedit mode on. Or via side panel, as Settings Tray does.In any case, even the basic set of contextual links ('edit', 'delete', 'translate') will be more useful than nothing.
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#6 | interdiff-views-RegionView.es6_.js_.patch.txt | 895 bytes | Anonymous (not verified) |
#6 | interdiff-contextual.es6_.js_.patch.txt | 4.52 KB | Anonymous (not verified) |
#6 | contextual_outside.zip | 13.11 KB | Anonymous (not verified) |
#6 | contextual_outside_markup.png | 20.51 KB | Anonymous (not verified) |
#2 | 2933695-2.patch | 16.12 KB | Anonymous (not verified) |
Comments
Comment #1
Anonymous (not verified) CreditAttribution: Anonymous commentedvaplas created an issue. See original summary.
Comment #2
Anonymous (not verified) CreditAttribution: Anonymous commentedThe patch just to demonstrate the idea.
Comment #5
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commentedCan you elaborate on where they would go? Will they be moving far away, like the end of the HTML document, or stay close to the block wrapper?
For accessibility I'm concerned about where the contextual links will be in the keyboard tabbing order for (a) the page as a whole, and (b) in relation to the block.
Comment #6
Anonymous (not verified) CreditAttribution: Anonymous commented@andrewmacpherson, great thanks for your interest in this issue!
#5.1: Yes, the principle position is the move countextual links outside the main markup of site, ie to the
</body>
(I think I read somewhere that soon the technical tools can be located even outside the body 🎉, or maybe the Shadow DOM will seize power in this direction).#5.2: Yes, this contextual pencil was not as simple as I thought:
So some kind of regression is likely to happen. But since this can be implemented as an optional configuration, each user will be able to voluntarily decide on this regression.
However, it may be a good first step to test this as a contrib module. I already made his draft version, and I plan to post it in the near week. If you're interested, here's the archive. The module override a pair of js-files from
core/contextual
, so also attached the interdiff between them.The module is not perfect yet, but I already get incredible enjoyment with the theming thanks to it!
As a preparatory step to integration, we can also weaken the current relationship in core/contextual, if we add the identifiers to the regions, and replace the search by the
closest()
, by search by$('[contextual-region-id="id1"'])
.PS:
Oh, somewhere, my cool picture from IS disappeared 😧. Perhaps https://www.drupal.org/project/infrastructure/issues/2853070
Comment #7
Anonymous (not verified) CreditAttribution: Anonymous commentedThe sandbox is ready: https://www.drupal.org/sandbox/vaplas/contextual_outside
Comment #15
larowlanGiven how difficult it is to make contextual and layout builder play nice with things like flex layout, I think this is at least major
Comment #16
larowlan