Problem/Motivation
Add a new FieldFormatter plugin to output text fields as a <details> / <summary> group.
Initial use case for Standard profile: in #3002770: Provide authors with tools to manage transcripts and captions/subtitles for local video and audio there is a plan to add a transcript field to some media bundles. A details element is a compact, unintrusive way to present the transcript close to the video. See a demonstration in comment #4.
Aside from that, it's a general purpose formatter to help authors make good use of a standard HTML element. A few other potential uses:
- Events - a "venue address" field.
- Commerce products - a "size info" field.
- User profiles - a "contact details" field.
- A long-text-with-summary could populate the
<summary>using token replacement from the sub-field. - Paragraphs - a question-and-answer paragragh type, with two fields for the question and answer. The answer field would use the details/summary formatter, configured to show the question as the
<summary>via token replacement. (See comment #10 for a demo.) - Long accessible descriptions for complex images. A flowchart accompanied by a rich text alternative in a collapsed details element. Comment #5 elaborates.
Proposed resolution
The FieldFormatter plugin will have some relevant settings:
- A checkbox setting controls whether it is should be open or closed initially, i.e. the
<details open>attribute. - Text of the
<summary>element. will follow this order:- Custom text specified by the site-builder.
- The field label if no custom text specified
Others? Maybe leave that possibility open for contrib.Maybe could be follow-up
- As a highly desirable bonus, the summary text can support token replacements from the parent entity. Patch #3 included this, and there is a demo in comment #10. Deferred, needs follow-up issue.
Remaining tasks
- Implement the formatter.
- Needs follow-up issue to add token support (and tests) for the summary text.
- Tests.
User interface changes
TODO place screenshots
API changes
None.
Data model changes
Just the necessary addition to config schema for the new formatter settings.
| Comment | File | Size | Author |
|---|---|---|---|
| #45 | 3062136-44.patch | 10.59 KB | smustgrave |
| #45 | interdiff-41-44.txt | 4.36 KB | smustgrave |
| #42 | afterpatch.jpg | 11.91 KB | gaurav-mathur |
| #42 | beforepatch.jpg | 15.96 KB | gaurav-mathur |
| #32 | 3062136-32-formatter-settings-UI-screenshot.png | 27.24 KB | andrewmacpherson |
Comments
Comment #2
andrewmacpherson commentedComment #3
andrewmacpherson commentedFirst draft of a patch. The basic settings are working, including token replacement in custom text setting for
<summary>.Comment #4
andrewmacpherson commentedA few screenshots using patch #3.
detailselement, and the "transcript" field name is the<summary>.Comment #5
andrewmacpherson commentedI thought up a new use-case. I knew they'd start flowing soon enough.
RIch text contained in a
<details>element could also be used to provide long descriptions of complex images. Flow charts, maps, and the like. The image media entity bundle could have a rich text field, and the rendered media entity would be an image with a collapsed details just afterwards.With a small bit of
hook_preprocess_FOO(), a themer could set up a longdesc or aria-details relationship. That could be a good recipe for the drupal.org handbook page.Or, we could set up the image media bundle in Standard profile up that way. When editors can embed media using a choice of display modes, an entity view display with a long description will be feasible thing to provide for all Drupal sites,
This idea needs a spin-off issue :-)
Comment #7
phenaproxima@andrewmacpherson demoed this to the UX team this past Tuesday, June 18th, and it went over incredibly well. This patch would allow us to fix A-level WCAG violations that we currently ship in the Standard profile's included media types. So, I'm tagging this as accessibility-related and bumping its priority.
Comment #8
phenaproximaNice work! I like how simple this is. I'm tagging it for tests as well.
I think we should rename this parameter to 'open'.
We probably don't need these to be two distinct settings. Maybe we could just default summary_custom_text to the field label, and let site builders change it if they want.
We should be using $this->t() throughout the class.
Nit: Should be 'Xss::filterAdmin'.
I think we might want to do the token stuff in a follow-up issue, because we'll want to add some inline help to the configuration form explaining what tokens are available. Removing the tokens, for now, would make this patch easier to commit (with less test coverage needed).
If we continue to do it here, then we'll certainly want to inject the token service into this class.
This should always be boolean, for example:
'#open' => (bool) $this->getSetting('details_open');Comment #9
andrewmacpherson commentedRe. #8 - thanks for the review. Most of those points are easy to fix address.
Re. #8.5:
The part about test coverage makes sense to me. I agree that we can move token support to a follow-up.
The other part about UI text is a fuzzier problem, because we don't currently have a lot of UI text to describe available tokens. Most configuration fields that accept tokens don't actually tell you that you can use tokens. Views and User module are outliers here.
For example, the "Title" field on blocks accepts tokens, but the field doesn't have a
#description(seeBlockBase::buildConfigurationForm()). Instead, the token module in contrib adds a description and a token browser dialog (seetoken_form_block_form_alter()).I think it's worth improving the UI descriptions for fields that accept tokens, but I don't think that should be a blocker to adding token support to this formatter itself. It would be good to see something like the contrib token browser in core eventually.
Comment #10
andrewmacpherson commentedMeanwhile, here's a demo what the token replacement can achieve.
I got this working! It was as easy as I expected.
[paragraph:field_question:value].Comment #11
andrewmacpherson commentedComment #12
andrewmacpherson commentedNew patch addresses most of the points in #8.
8.1 - Fixed.
8.2:
I tried this but ran into a snag. Removing the
summary_sourceradio options was easy enough. The problem was in providing useful default value for the summary text.FormatterBase::defaultSettings()is a static method, so there isn't any object context to get the field definition out of$this.I don't know how we can get around this, so I have left the
summary_sourceradio buttons in place for now.8.3 - Fixed.
8.4 - Fixed.
8.5 - I removed the token replacement for now, noted the need for follow-up in the issue summary. I think tokens will be important for scenarios like the paragraph bundle in #10, and the usefulness of this formatter isn't so great without them.
8.6 - Fixed.
Comment #13
phenaproximaThanks, @andrewmacpherson!
In defaultSettings(), we can just have it be an empty string or NULL, I think. Then, in the non-static settingsForm() method, we should have access to $this->fieldDefinition->getLabel(), which would be a good default value.
I'm kicking this back for tests, but this is getting close to ready, IMHO.
Comment #14
andrewmacpherson commentedRight, I get you. I'll try that.
Comment #15
andrewmacpherson commentedFixed the test failure from #3 and #12. There was a test which expected a specific list of available formatters, and the presence of the new formatter broke that assumption.
Attempted to address #8.2. Removed the
summary_sourceradio buttons. Now there's just asummary_textformatter setting.Now there's another problem: when you first select the details/summary formatter, there isn't a value saved for the
summary_textsetting. The field label is pre-filled in the formatter settings form, but it isn't actually stored until you:If you don't all of these steps, the stored setting will be empty, and that results in a
<details>without a<summary>. Technically, that's allowed in HTML, but the browser fallback isn't very good. I think we should avoid that situation.Maybe we can check for an empty value in
viewElements(), and fill in the field label as a fallback when we render the field. The settingsSummary() is another place where the empty value can be addressed in a similar way. Is this a sane approach though? It feels very hacky pretending there is a stored setting when there isn't.Comment #16
andrewmacpherson commentedForgot to upload the patch :-(
Comment #17
phenaproximaI think that is a perfectly sane approach. We don't have to "pretend" there's a stored value; we simply use the stored value if one exists, or the field label if not. I think that is easy to understand for a developer, and acceptable from a site builder/user perspective (it "just works" even if you don't bother doing any configuring). But if you really don't like it, perhaps we could set the #placeholder text in the settings form, and make it non-required, so that it's clearer that we have a fallback value.
Comment #18
andrewmacpherson commentedWow, that's a rare use of placeholder that is quite useful!
One of the main accessibility/usability objections to the placeholder attribute is that users sometimes don't fill the field in, because they think it already has a value. In this case that would actually be OK, because it's the value that will be used if you don't provide one yourself.
It would be good to use it in combination with a #description which explains that it defaults to the field label. Don't rely on placeholder to provide instructions.
Comment #19
phenaproximaAgreed!
Comment #20
andrewmacpherson commentedThis brings in the ideas discussed in #17-19.
I think this is feature-complete now, except for the token support follow-up. The settings are greatly simplified since #3.
TODO:
Tests. I'll root around in the tests for other formatters to see how they are done.
Update screenshots for issue summary.
Comment #21
andrewmacpherson commentedI see that the hook_help() for text module documents the existing formatters, so it might be good to describe the details formatter there too.
Comment #22
andrewmacpherson commentedFix silly syntax mistake.
Comment #25
andrewmacpherson commentedTagging for the bug-smash initiative. When we get this over the line, it will unblock the related plan for audio and video transcripts,, so we can meet TWO level-A success criteria in WCAG and ATAG.
Needs test coverage for the formatter settings and output.
No previous accessibility experience needed!
Comment #26
phenaproximaWrote a nice kernel test of the formatter settings, and verified that they affect the output as we expect, and did a touch of refactoring to prevent repetition of logic.
Comment #27
andrewmacpherson commentedThanks! I tried writing a unit test for this a while back, but it kept being fussy about line breaks. I never really understood when to use kernel test, but this one is easy enough to follow, and the test bots say green.
'summary_text' => 'Alas, poor Yorick'Uber-nitpick: Shakespeare thought highly enough of Yorick to finish that with an exclamation mark :-)
I've updated hook_help() to mention the details formatter.
Comment #28
andrewmacpherson commentedForgot the interdiff on the last patch
Comment #29
andrewmacpherson commentedComment #30
andrewmacpherson commentedI manually tested the formatter after the little refactoring in #26
Comment #31
gábor hojtsyFirst, this is great, thanks for working on it. I think this is getting really close and is simple and well contained and could be really useful as a transcription field formatter indeed for audio or as a long description field for figures, etc.
I was wondering about this bit. How does this operate with a text field that in itself has a summary part? You have a "Summary" setting on the field settings but then you have a summary on the field value itself too. That is not really handled in the code, and I don't know what would users expect either.
Comment #32
andrewmacpherson commentedI realized the screenshots in #10 are out of date. We simplified the formatter settings, so here's a screenshot of what they currently look like using patch #27.
There's a checkbox called "Open details by default", and a textbox called "Summary text".
Re. #31 - Thanks Gábor, that's a good question about the
text_with_summaryFieldType. I've thought about this too, and there are a few approaches we could take. I don't know if the question should be treated as a blocker here, or suitable for a follow-up.text_defaultandtext_trimmedformatters don't have any special treatment for the summary sub-field when used with atext_with_summaryfield.text_with_summarysub-fields with that, so it's possible to use a token like[node:field_biography:summary]. Comment #10 has a similar demo, but using tokens from a separate field. This has super-power potential, but the downside is that tokens have a significant learning curve. I'd still like to have token support in there eventually.<summary>. An earlier version of this patch used radio buttons for choosing between the field label, or custom text. My original idea is that Form API#optionsare an extensible way for modules to add third-party settings. You can see what that looked like in comment #10. We simplified the settings since then, but we could revisit that as a way to offer thetext_with_summarysummary sub-field as a source? PerhapssettingsForm()method could inspect the field type configuration first.It's unfortunate that the word "summary" is overloaded here. One use is a HTML element name, the other is a long-established Drupalism. That could make it awkward to find nice UI text for the formatter settings, but we'd think of something.
Common use case: being able to use the summary sub-field for the
<summary>means you could use a multi-valuetext_with_summaryfield to build a collapsible FAQ, with configuration only! We'd need to fix #2817081: Show 'Edit summary' links on multi-value long text field with summary too though.Comment #34
volkswagenchickAdding
NorthAmerica2021tag for visbility.DrupalCon NA is April 12-16 with a focus on EOOTB on Wednesday, April 14.
Thanks
Comment #39
smustgrave commentedD10 version needed
At this time we would need a D10.1.x patch or MR for this issue.
Also if someone could address the follow-up ticket please.
Looks real interesting too!
Comment #40
ayush.khare commented10.1.x Reroll for #27
Comment #41
smustgrave commented@ayush.khare thank you for the patch unfortunately during the reroll you left out a change for one of the files.
Also The last patch doesn't pass commit checks, could you make sure to run
./core/scripts/dev/commit-code-check.shbefore uploading a patch to make sure there are no issues with code formatting. see https://www.drupal.org/docs/develop/development-tools/running-core-devel...Also removing quickedit as that's removed in D10
Comment #42
gaurav-mathur commentedApplied patch #41 successfully works fine.
Comment #43
quietone commentedI started a review by reading the issue summary. First off, I think this is a very useful feature to add. The proposed resolution lists 3 items. The second one is still a point of discussion. If that has been resolved, add it to the Issue Summary. I am adding the tag for an IS update.
This issue has user interface changes and there are no screenshots linked to in the IS. This needs up to date screenshots.
The 'User interface changes' sections says that there are UI changes but there are no up to date screenshots. The section also states that this is using an existing template that is styled for Bartik/Seven. Surely that is out of date. I then searched the issue to see if this has had a usability review. I do not see that so I am adding the tag.
I did not read the comments, instead I then applied the patch and tested it. I added some text fields to the article content type. It appears to work just fine but the text does need to be reviewed. I noticed the following;
I skimmed the patch and this jumped out at me.
Although a nice reference, let's use another test string so we can avoid this.
Comment #44
smustgrave commentedUpdated IS
Before adding screenshots want to make sure we get the language correct.
"Open by default" is no longer a full stop
Changed "Details/Summary" to "Details with Summary tag" - thoughts?
Removed the cspell:ignore Yorick
If language looks good we can add screenshots.
Comment #45
smustgrave commentedComment #46
quietone commentedI applied the patch and looked at the help page. Then looked at the patch, making the following points.
No period at the end, like the others on the page.
This will need work. I don't think we can expect an admin to know what an 'element' is. I suspect that 'but this can be customized' needs to be changed to actual instructions. But this is not for me to decide this is for the UX folks.
I used the new formatter and the supporting text is better, but this needs a Usability review to get all the strings to conform to Drupal standards. That is not something I can do.
Finally, I skimmed the issue summary and see that the remaining tasks is out of date. It states that the formatter needs to be implemented and so do tests. Can that be updated to show the work still to do?
I hope to start a code review tomorrow.
Comment #47
mgiffordTagging for WCAG SC 1.3.1
Comment #48
quietone commentedThis time I looked at the code in conjunction with testing the patch and running the tests.
This should be sorted to ease readability.
The ux folks will give feedback but this should be sentence case.
Why is this shown only when open? As a user I need to click to find the state. Would it not be better to inform the user of the state?
In \Drupal\text\Plugin\Field\FieldFormatter\TextDefaultFormatter::viewElements there is a comment that the ProcessedText elements handles the cache. So, I think this is not necessary.
Labels do not have full stops.
Let's make this something helpful. Something along the lines of 'Use the user text for the summary. If not supplied then use the field label." This block is in two methods, so both should be changed.
Can be removed when the comment is changed.
Sort the use statements.
As I read this, this tests is testing multiple text formatters. Let's update the comment to reflect that this is testing a specific text formatter.
This test has the same setup as TextFormatterTest, does it make sense to extend from that?
This can be inheritdoc.
Let's be more descriptive. Use an item list to describe the array values.
Why is there no case with 'open' set to TRUE?
This is a heading and does not need a full stop.
Finally, I think that this new formatter should be added to the list being tested in \Drupal\Tests\text\Kernel\TextFormatterTest.
I want to take another look at TextDetailsFormatterTest.
Comment #50
kopeboyI would also consider allowing the end user to input the summary text, and even supporting the existing "Text with summary" field type when the summary is required (in this case, check current bug at #3115978: After enabling Require Summary on a field can't save the field).
Comment #51
kopeboyWe can take inspiration from the details_summary_field_formatter module.