Meta issue: #1980004: [meta] Creating Dream Markup
Issue based on: #1939102: Convert theme_indentation() to Twig
The motivation is to get rid of empty div's being used for indenting (which clearly is not good markup). Instead, the space should be applied to the table elements, originally proposed in the tr tags but after a semantical-technical discussion at Barcelona, the target was shifted to the first td of the row, containing the title / label content.
However, implementation of the data-indent attribute in the td of only draggable tables, it will be necessary to adjust the template of the whole table. Hence in this issue, there is a patch provided to reduce the redundant markup to only one div (a better-than-nothing approach), and a proposal to consider a new issue towards creating the "table-draggable" template.
Also, the patch removes theme_indentation()
(which only inserted markup via PHP) in favour of equivalent Twig template.
Target markup proposal:
<table>
<tr><td data-indent="1">1</td></tr>
<tr><td data-indent="2">2</td></tr>
<tr><td data-indent="3">3</td></tr>
<tr><td data-indent="4">4</td></tr>
<tr><td data-indent="5">5</td></tr>
<tr><td data-indent="6">6</td></tr>
<tr><td data-indent="7">7</td></tr>
<tr><td data-indent="8">8</td></tr>
<tr><td data-indent="9">9</td></tr>
</table>
<style>
td[data-indent="1"] { padding-left: 1em; }
td[data-indent="2"] { padding-left: 2em; }
td[data-indent="3"] { padding-left: 3em; }
td[data-indent="4"] { padding-left: 4em; }
td[data-indent="5"] { padding-left: 5em; }
td[data-indent="6"] { padding-left: 6em; }
td[data-indent="7"] { padding-left: 7em; }
td[data-indent="8"] { padding-left: 8em; }
td[data-indent="9"] { padding-left: 9em; }
</style>
Comments
Comment #1
oresh CreditAttribution: oresh commentedmoving issue to core.
Comment #2
ry5n CreditAttribution: ry5n commentedIs there a good reason this is done in markup? Like, a really good reason? Otherwise it seems obvious this should be removed in favor of CSS.
Comment #3
LewisNymanAgreed. We could easily add a
indent-x
oris-indented-x
to the relevant element instead of inserting multiple divs. I guess this was done so we could multiply indentation without writing multiple lines of CSS. I'd much prefer control in CSS. Let's write this function out of core and do a happy dance.http://api.drupal.org/api/drupal/includes!theme.inc/function/theme_inden...
Comment #4
LewisNymanHere's a quick demo, for the taxononmy admin page only.
Not sure if this feels right. Maybe we can do something a bit better using data attributes and :before pseudo selectors?
Comment #5
ry5n CreditAttribution: ry5n commentedHmmm… the situation here is such that the current solution isn’t bad, even though it’s pretty gross. Having a bunch of .is-indented--n classses is the only way I can think to do it with just CSS, but I agree is not so hot. I kind of like the idea of using data-* and :before, say like this:
That just puts one em space character in front of the table cell content, and makes sure it uses a font that has an actual em space in the character set. PHP or JS just needs to change the data-indent property to however many em spaces, so for 3 indent levels, data-indent="\2003\2003\2003".
Honestly though, it’s not any better than what’s in the summary, except possibly for JS performance (JS has to update the indent value during tabledrag).
Comment #6
joelpittetKinda repurposing this issue to get data attributes as @ry5n mentioned in #5
Comment #7
ry5n CreditAttribution: ry5n commentedRe-reading this right now, this seems like it should just be set as an inline style. JS can trivially convert an indent level integer into an em value for padding. No complicated attributes or byte-heavy stylesheets needed.
Comment #8
joelpittet@ry5n one plan that seems to be taking hold strongly at the conference and slightly before is to create data-attributes wherever CSS classes were used to help the distinction between a class that is for style and a class that is for function (the latter being converted to a data attribute). This gives a good distinction and allows for themes to remove classes with less fear they will break functionality.
Ideally we could do:
but of course that doesn't work. Though this is a hard limit for the nesting level at 9, so the extra CSS would be trivial to meet this goal.
Thoughts?
Comment #9
joelpittetAlso the idea got a sporadic applause from the audience in MortenDK's talk last Tuesday so I'm assuming it's going in the right direction with the data-attributes. Implementation details may say other wise...
Also I prefer DRY by all means, but settle for limited duplication in this case.
Comment #10
ry5n CreditAttribution: ry5n commentedI’m not up to date on community consensus re: those particulars, but yeah if there’s a hard limit on nesting then classes or data-attributes mapping to styles seems sensible. I suspect that the data-attributes thing is about preventing unrelated CSS and JS from depending on the same class (accidentally introducing coupling). If that’s the case a class may be preferable since it’s applying styles; but again I’m not up to speed on consensus.
Comment #11
LewisNymanComment #12
mortendk CreditAttribution: mortendk commentedconsensus (no banana) is that prefixing with .js- is an ok solution, but to make it even "harder" to mess up with css we should really use data- instead
Comment #13
star-szrComing back to this now, any thoughts on @ry5n's idea in #7 to just set this inline with JS? Or would we rather keep the theme function :)
Comment #14
davidhernandezDo we not need this, because of this issue? #2449445: Add "indentation" class back to indentation theme hook, use it for styling
Comment #15
star-szrStill relevant I think, just related.
Comment #16
Adrian Richardson CreditAttribution: Adrian Richardson commentedStarted working on this issue in mentored sprints, DrupalCon Barcelona
Comment #17
holist CreditAttribution: holist commentedtheme_indentation()
is called from:Comment #18
Adrian Richardson CreditAttribution: Adrian Richardson commentedIn addition to the theme_indentation() function, we're currently working on core/misc/tabledrag.js, core/modules/system/css/components/tabledrag.module.css
Comment #19
dark-o CreditAttribution: dark-o commentedThis will need to be tested manually on all places where it takes effect. Places where this can be tested:
Menu items:
admin/structure/menu/manage/main
Edit content type form
admin/structure/types/manage/article/form-display
admin/structure/types/manage/article/display
List taxonomy terms:
admin/structure/taxonomy/manage/tags/overview
Book hierarchy
admin/structure/book/4
Comment #20
kiwimind CreditAttribution: kiwimind at Torchbox commentedOur current thinking is to allow a single div to be added with a data attribute attached to it.
Optimally this div would be removed and the data attribute added to its parent td. This may follow.
Comment #21
holist CreditAttribution: holist commentedA partial patch towards the goal outlined by @kiwimind for creating only single div in the
theme_indentation()
and Twig templateindentation.html.twig
.JS and CSS parts still needed.
Comment #22
kiwimind CreditAttribution: kiwimind at Torchbox commentedFurther to the patch provided by @holist, this patch now includes the CSS for this update.
JS to follow.
Comment #23
kiwimind CreditAttribution: kiwimind at Torchbox commentedAmended previous patch to use pixel spacing to allow consistent rendering of the png tree.
Comment #24
rachel_norfolkYou guys have done some epic work on this today - make sure you have a plan how you are going to keep up the momentum till completion before you leave.
THANKYOU!!
Comment #25
holist CreditAttribution: holist commentedRemoved
theme_indentation()
in favour ofindentation.html.twig
. CSS changes by @kiwimind included.Comment #26
holist CreditAttribution: holist commentedSuggestion for follow-up:
Once we have reduced the div's to only one and removed
theme_indentation()
(JS solution still pending), the next step should be to include the data-indent attribute in the td instead of an empty div.A good solution (as discussed with @rteijeiro) would be to create own template called, say,
table-draggable.html.twig
, and relevant preprocess for that. This would then be triggered from the form builders etc. depending on whether the table is marked draggable. The current implementation makes it very complicated to add attributes to td tags, because only generictable.html.twig
is used.This approach needs to be evaluated and the implementation outlined by someone with the bigger picture in mind.
Comment #27
Adrian Richardson CreditAttribution: Adrian Richardson commentedHere's the updated tabledrag.js file to drive the indentation using data-indent attribute and only one div.
Comment #28
kiwimind CreditAttribution: kiwimind at Torchbox commentedTo-do:
- redo CSS and background images for tree-child classes that display on mousedown
Comment #29
akalata CreditAttribution: akalata commentedAll of the awesome work by sprinters at Barcelona (from comment #16) should be consolidated into an issue summary update!
Comment #30
Adrian Richardson CreditAttribution: Adrian Richardson commentedI've done some work on the background images for the tree hierarchy display when dragging. I've worked around using the CSS background-position edge offsets, since Safari 6.1 and before don't support them. This somewhat complicates the right alignment needed for rtl displays - it has to be handled in tabledrag.js per group row.
Anyway I think this is ready for review now.
Comment #33
nod_I really, really hate to add more code to the tabledrag script. Also the current version has been battle-tested and I don't feel like breaking it a week before RC.
Is it possible to add the divs in the js instead of the theme_function and keep the code as-is?
Comment #34
Adrian Richardson CreditAttribution: Adrian Richardson commentedUnfortunately, tabledrag.js currently needs a div.js-indentation per level to function. So to move to cleaner markup without all the extra divs, we do have to make changes to tabledrag.js.
This patch gets close to the clean markup: theme_indentation and is now removed completely. BookAdminEditForm, EntityDisplayFormBase, MenuForm and OverviewTerms have been changed accordingly.
Still to do: properly test all four of the forms affected - I've been concentrating on MenuForm in development; plus we should only insert div.tree on drag start when needed for displaying the structure of the group being dragged and remove it on drop to keep the markup clean. The test in TaxonomyTermIndentation (and possibly other tests) also needs updating to use the new markup.
I'll be able to look at this further this evening.
Comment #35
holist CreditAttribution: holist commentedI updated the issue summary to reflect our thinking in BCN sprint.
Comment #36
Adrian Richardson CreditAttribution: Adrian Richardson commentedMarkup should now match initial proposal. tabledrag.js adds a temporary div to show the tree structure on the child elements being dragged. Taxonomy term indent test also updated for the new markup.
Comment #38
nod_Keyboard can't be used to do everything, and when trying to use the mouse to fix the problem, things go even wronger. I haven't tried touch (for the record this is why i didn't want to change the JS. It's a pain to test and it look like it'll be a pain to fix).
I'd prefer if
data-indent
wasdata-drupal-indent
to conform to the rest of our attributes and avoid naming collisions. data-indent sounds like it could be used by some scripts out there.Since you're renaming vars, might as well follow naming standards. If the variable hold a jquery object, it's name need to start with
$
.or something like that. we can avoid duplication the whole Math.abs(parseInt…
Need descriptions. No idea what ox is. y or dx is fairly clear but might want to be verbose for ox. It's not an existing math convention. (and everything needs description anyway).
Seems fishy. is there a reason why we don't have true/false or 1/0 ? we shouldn't be mixing the two.
don't need to jquery it. just
.prepend(menuDisplay);
Naming. Should be
$el
.Don't see why it's on 2 separate lines.
I get why we need to do that but it's a little bit of code smell.
Naming.
it doesn't need to be that verbose.
why is it called backgroundX? nowhere a background is involved, just margin, width and all.
indentPixel is not a good name. It really doesn't help, I forgot what it was and expected a number, not an object.
indentInfos
or something would be more accurate.There are eslint errors, needs to be fixed.
Comment #39
nod_umm I guess the keyboard has the same capabilities before and after. It's just that using the mouse on something we moved with the keyboard result in funky stuff where is was working as expected before.
Comment #40
star-szrPerhaps it's worth re-profiling to see where we stand if we just removed the theme function at this point. Really the numbers at #1939102-20: Convert theme_indentation() to Twig don't look too terrible. Then we can maybe evaluate further refactoring at a later time.
Comment #41
star-szrGoing to profile and see what we're looking at.
Comment #42
rachel_norfolkI would really appreciate if you can describe how you go about that, Cottser. A few people were involved in this issue as first entry to contribution at Drupalcon Barcelona so everything is a good learning experience.
(Okay, I want to know, too!)
Comment #43
star-szr@rachel_norfolk there are some slightly outdated but mostly accurate docs at https://www.drupal.org/contributor-tasks/profiling and I'm willing to help in IRC but probably not over the next 7 days or so.
See #2578567: Remove theme_indentation() and use Twig template only for an issue to rip out theme_indentation() because the performance is reasonable. I think this is still worth pursuing (and thank you everyone who jumped in!) but I do tend to agree with @nod_ that it's risky this close to release to refactor the JS. If we can get the Stable base theme into core we can still pursue this after 8.0.0.
Comment #44
davidhernandezYesCT also blogged herself going through the process of setting up profiling recently. It might be more updated and specific.
http://yesct.net/
Comment #45
star-szr