Problem/Motivation
This is a follow-up to #2994702: Allow editors to alter embed-specific metadata, as well as `data-align` and `data-caption`.
Right now there is no way for a user to set the view mode without the 'source' button enabled in the CKEditor. Right now, one must
1) Press source.
2) Edit the view mode manually.
3) Press source again to re-enable the CKEditor WYSIWYG to view the new view mode.
We should allow selecting the view mode in the EditorMediaDialog, with possibly a select list, or possible radio buttons.
We should also allow a configuration for limiting the allowed view modes, but I think there may be a separate issue for that.
Phenaproxima writes:
[We should have a] separate issue to discuss exposing the available view modes as a set of checkboxes, and allowing the user to choose which one to use per-embed if more than one view mode is enabled. For MVP purposes, though, having this in contrib is fine.”
Proposed resolution
1) Allow per bundle configuration for view modes available to select in the EditorMediaDialog
2) Make the feature optional.
3) This should be separate from the media embed filter's default view mode.
Here's a video of this in action from comment #45:
Video:
https://www.drupal.org/files/issues/2019-09-14/view-mode-dialog-select-w...
Remaining tasks
User interface changes
- New configuration option on the
MediaEmbed
filter to set allowed view modes for embeds (allowed_view_modes
) that is configurable through the text format configuration UI: - New field in
EditorMediaDialog
(depending on aforementionedallowed_view_modes
setting):
API changes
No changes, only an addition: the media_embed
filter now has a allowed_view_modes
setting. If multiple choices are allowed, EditorMediaDialog
allows the user to make a decision.
This configuration was added to the filter, rather than the DrupalMedia CKEditor plugin that opens the dialog, because this should be text editor-agnostic.
Data model changes
No changes, only an addition: config schema for filter_settings.media_embed
.
Release notes snippet
Comment | File | Size | Author |
---|---|---|---|
#86 | 3074608-86.patch | 22.35 KB | oknate |
#86 | 3074608-interdiff--84-86.txt | 1.47 KB | oknate |
#84 | 3074608-84.patch | 23.82 KB | oknate |
#84 | 3074608--interdiff-81-84.txt | 3.33 KB | oknate |
#82 | 3074608-81.patch | 26.21 KB | oknate |
Comments
Comment #2
Wim LeersSome sites will not want this, so it should be optional. By default, the author should not be able to choose a view mode other than the default one, because view modes are a very abstract concept that on many sites authors do not know nor need to know.
Comment #3
Wim LeersComment #4
oknateComment #5
oknateAdding "Needs tests" tag.
Comment #6
oknateComment #7
oknateAdding validation for the HTML filter allowed value data-view-mode.
@todo, there should be a note on the settings form to check the allowed values.
Comment #8
oknateAdding test coverage.
Comment #9
oknateI was missing commits in the branch I was diffing against, so rerolling.
Comment #10
Wim Leers🤔 The
dialog
in thedialog_view_modes
seems weird. How aboutallowed_view_modes
?🤓 Nit: should use strict comparison.
👍
🤔 "contextual dialog"
Comment #11
oknateRerolling and addressing #10:
1. ✅Changed dialog_view_modes to allowed_view_modes.
2. ✅Added strict comparison.
4. ✅Dropped the word “contextual”. It’s not a contextual menu, you’re right. I don’t know why I used that word.
Comment #12
oknateI feel that per media type settings are better than one set of view mode options for all media types. The configuration form is more complex, but I think there is a strong justification for it. There will be cases where for one media type, such as the image media type, you'd want to be able to select from three or four options, but for all other media types, you'd want no options, you'd just want to use the default. This allows for that.
Configuration for view modes by media type:
Comment #13
oknateComment #14
Wim LeersI am not convinced by #12. Obviously it makes the configuration UI a lot more complicated. But more importantly, it does not match the concept/the architecture of entity view modes: view modes are created for an entity type, not for a bundle. All bundles for the same entity type by definition have the same view modes. So it's up to the site builder to ensure that each view mode has a sensible configuration for every bundle.
Comment #15
oknateBut whether those view modes are enabled with entity display configurations is unique per bundle.
On a recent project, in the WYSIWYG, we had a full-width inline image embed and a half-width image embed. In this situation it would be useful to have two options in the dialog "Full-width Inline Image" and "Half-width Inline Image", which would correspond to entity display configurations.
But this would not be something i want to show for the document media type. I think a per media type configuration would be something a lot of sites would want. Therefore I think it would be valuable to allow the customization of view modes per bundle.
Perhaps that should be left to contrib?
Comment #16
phenaproximaI think I'm leaning towards Wim's point of view. This seems like quite a complex configuration option that I'm not sure will benefit the 80% use case.
My preference would be to simply allow the selected view modes for all media types, and leave type-specific fine tuning to contrib.
Comment #17
oknateAlright, then let's move forward reviewing #11 and ignore #12, leave that for contrib.
Comment #18
oknateReroll of #11 only.
Comment #19
oknateFixing an error when config isn't set, and test failure because I failed to update a test.
Comment #20
Wim Leers#15:
-
-
-
No, it is expected if an entity type has a view mode X that every entity can be viewed in view mode X — regardless of bundle.
What you describe is something you can do on your project, but it violates the architecture that core has established. Whether that architecture is flawed or not is a different matter. But we should just comply with the existing architecture, not change or challenge it here.
These comments are documenting trivialities. Let's remove them.
I'd have expected to be able to use
array_intersect_key()
here.s/change/choose/
s/an embed/a media embed/
Comment #21
oknateAddressing #20:
1. ✅ Removed comments.
2. ✅ I was able to use array_intersect_key in one place. I doesn’t really help make it less verbose, because we also have to check the status on view mode (don't we?) and grab the label for it.
Should I be passing the label to a new TranslatableMarkup object?
3. ✅ Made the text changes.
Comment #22
oknateRemoving "Needs tests" tag. I added the tag in #5 and test coverage was added in #8.
Comment #23
Wim LeersRE: checking a view mode's status: this is an excellent question! I actually think you should not have to do that, because there are dozens of calls to
\Drupal\Core\Entity\EntityDisplayRepository::getViewModeOptions()
in core. If thestatus
needs to be checked, it's up to that method to do it. So I think the code can be simplified toarray_intersect_key($repository->getViewModeOptions('media'), $editor_settings['plugins']['drupalmedia']['allowed_view_modes']);
Comment #24
oknateUn-postponing this. Needs a reroll and to address #23.
Comment #25
oknateComment #26
oknateRerolling and Addressing #23:
I changed it to this:
And it seems to work fine.
No interdiff this time, sorry, it was messed up and includes more changes than just this one.
Comment #27
Wim LeersAll values listed here also need to trigger dependencies on the listed
ViewMode
config entities.We can consider adding a
onDependencyRemoval()
implementation to ensure that the list of allowed view modes is updated when view modes are deleted.Comment #28
phenaproximaI didn't read the tests yet...
I think the sequence itself also needs a label, like so:
We don't need $filter_media_embed to be its own variable.
The in_array() call should be array_key_exists().
Same here.
I think this needs a comment. What's it here for?
Ah, I see it's used in submitForm(). If that's the case, I don't think this should be a hidden field. We can just store it in $form_state directly with $form_state->set(). Or, we can set '#type' => 'value' on this element, which will put it into $form_state's values, but not output any markup.
This should be
string[]
.The empty() check is redundant. If there are 0 allowed view modes, there is still less than 2 and an empty array will be returned.
But, more to the point, I don't think we should have this "return nothing if there are less than 2 view modes allowed" opinion in this method. This should be the condition for the #access flag of the select list itself, which will give contrib some wiggle room to extend or override. In other words, in buildForm(), we should set
'#access' => count($view_mode_options) >= 2
. I think that would allow us to pretty much remove this method entirely.It's too bad that $editor is not type hinted as EditorInterface, but that's inherited from upstream.
And what if $settings['plugin']['drupalmedia'] is not set? Should we return early?
Ubernit: $view_mode["status"] should be $view_mode['status'] (single quotes).
Surely we want some default configuration value (for example, ensuring that the 'embed' view mode is pre-selected)?
Comment #29
oknateAddressing #28:
1. ✅ Done.
2. ✅ Done.
3, 4. ✅ ✅ replaced with array_key_exists
5. ✅ Switched to #type => ‘value’ and added a comment.
6. ✅ Changed to string[]
7. ✅ Dropped the method, removed the empty check, updated the #access to check the count. I think I covered everything you suggested.
9. Regarding:
AFAIK, this plugin cannot be disabled. The only reason the config would not be set is if someone hasn’t saved this Text Format since upgrading to 8.8.
So I don’t think we need to exit early. We want them to be able able to set the config when the config isn’t set.
10. changed double quotes to single quotes.
11. Added the MediaEmbed filter default the default.
I'm leaving this as "Needs work". I got the dependencies working somewhat, but it's kind of hacky, and it should have test coverage.
Comment #30
oknateFixing some bugs when adding a text format.
Comment #31
oknateFixing the same code. The fix last time was off.
Here's the new code. I realize now that this code is useless when adding a text format, because of the order of operations. When you add an editor (such as CKEditor) in the select form element, it calls this code. At this point, you won't have an associated filter format in the editor, so you lack the prerequisites for setting the default!
So this code is only (moderately) useful if someone is going back to make changes but they don't have $config['allowed_view_modes'] set. Additionally, and I'll test this out, but I think this means, if you intend to leave this blank, it will set a default for you, which we don't want.
Comment #32
oknateRegarding #28.11:
I set that up #29-#31, but came to realized this is problematic here. A user might want to set this to empty, and adding a default prevents this. Since the logic requires more than one checkbox to be checked for the form element to show up in the dialog, I think setting one checkbox as a default is harmless, but I'm not sure it's worth the code to extract it from the media filter. It makes more sense to me to just drop the default as it won't ever happen when adding a text format as it requires the user to have already saved the form and re-opened it in order to get the config value from the MediaEmbed filter, and the sensible default will only be one checkbox, when two are required. I don't really see the value in providing the one checkbox. It seems off to me, since it's providing half a sensible config (in that two values are required), and that the user might want to leave it blank. So I'm removing the default for now.
Another issue I ran into, was the checkbox were leaving zeros in the config:
So I borrowed code from core/lib/Drupal/Core/Entity/Plugin/EntityReferenceSelection/DefaultSelection.php that filters out zeros.
Now if nothing is selected, that part of the config looks like this:
Comment #33
Wim Leers😨 This should not be necessary. #2821191: Allow object-based plugin definitions to be processed in PluginDependencyTrait and #2904550: PluginDependencyTrait::calculatePluginDependencies() does not handle theme provided plugins added the ability to let specific plugin instances declare their own dependencies. But it seems Layout is the only thing that uses this.
Pinging Plugin system maintainer @tim.plunkett for his input.
Comment #34
oknateI don't think the plugin definitions are objects for CKEditor plugins. I'm not very knowledgeable about this stuff, but I tried to implement EntityWithPluginCollectionInterface for the CKEditor plugins. There's a @todo
It seemed there was a lot of changes needed, and it changed the config structure, where the editor settings plugins, would need to be editor.plugins instead of editor.settings.plugins.
I gave up on that, and put this hack in temporarily.
Comment #35
oknateI think we're going to be moving the setting to the MediaEmbed filter settings, per our conversation in slack. In that case, we don't need to fix the editor's dependency issues.
Comment #36
Wim LeersPlease summarize that conversation on this issue. Not only can most people not access that conversation, the few people who can will no longer be able to access it in a few short days due to Slack's policies.
Comment #37
oknateTo summarize the conversation in Slack:
I have been putting the config on the DrupalMedia CKEditor plugin. CKEditor plugins seem to be missing dependency bubbling up to the editor (or whatever the term is). So I had put in a hack to get the dependencies.
The dependency bubbling works for filter plugins apparently (I'll need to confirm). The problem is, it seems off to me to put a setting for the dialog opened by the DrupalMedia plugin into the config form for the MediaEmbed filter, which is only tangentially related to the dialog.
But Phenaproxia convinced me otherwise. The dialog is not editor specific and by putting the config into the CKEditor plugin, if we reference those settings in the dialog, we have created an unwanted dependency on CKEditor. Settings related to media embeds should not be editor specific. Also, this setting could be used for other things as well. There is already an issue to limit the allowed media types in the media library button that inserts the embeds #3073535: Allow only a subset of the media library to be exposed to CKEditor, and it could be used for that too.
Additionally, I think it will help solve the lack of a dependency API for CKEditor plugins, by not using the settings form for CKEditor plugins for this use case.
Comment #38
Wim LeersMakes sense! 👍
Comment #39
oknate1) Moves the config setting to the filter.
2) Remove dependency hack. With Filter plugin, it's not necessary.
Comment #40
phenaproximaDidn't have time to read the tests, but this seems very clean and good to me. Nice work!
It looks like all of these changes can be reverted.
I was hemming and hawing on this label, but in truth, the "Edit media" dialog is the only thing which, currently, cares about the allowed view modes. If that changes, we can easily change this label as well. So, 👍
This code still feels a little convoluted to me; I think it might benefit from a comment explaining the thought process behind it. Not so much what we're doing here, as why we're doing it.
🤔 This seems like it might accidentally run afoul of PHP's type juggling. (For example, what if attributes[data-view-mode] is '', but default_view_mode is NULL?)
We can probably revert all this, plus the rest of the changes this file. AFAICT, it's no longer being used.
There is an errant blank line here. :)
Nit: This is equivalent to
$this->settings += ['allowed_view_modes' => []];
A field will appear in "the dialog" -- that's a bit vague :) I would suggest changing this to: "If more than one view mode is selected, users will be able to choose a view mode for each embedded media item."
&$element should be type hinted as an array.
$types is a misleading name for this variable. How about something like $available_view_modes instead?
Ideally we'd load the view mode entity and use getConfigDependencyName() here.
We don't need the if (!empty()) check. If the 'enforced' key doesn't exist, unset() will just be a no-op.
Comment #41
oknateAddressing #40:
1. ✅ Reverted the leftover code from DrupalMedia CKEditor plugin.
2. That was my thought process exactly, change the label when we add a second use for the setting.
3. ✅ Added a comment. "If the current media embed ($media_embed_element) has a set view mode, we want to use that as the default in the select form element, otherwise we'll want to use the default for all embedded media."
4. @todo: I'll have to look into this.
5.✅ Reverted.
6. ✅ Removed blank line.
7. ✅ Changed to
$this->settings += ['allowed_view_modes' => []];
8. ✅ Updated the verbiage.
9. ✅ Added type hint.
10. ✅ Changed variable name to $available_view_modes.
11. ✅ Updated to use the loaded EntityViewMode à la RSSPluginBase::calculateDependencies(). Also, I added the dependency for the default embed view mode since this could possibly be set to a view mode that could be removed too. So we're checking both settings on the MediaEmbed filter now for view mode dependencies. That was a minor miss on the initial issue. #2940029: Add an input filter to display embedded Media entities
12. This is good to know. This was refactored away after the change above in 11.
Comment #42
oknateLooked into #40.4 and I did find a problem with type hinting.
When you set data-view-mode = ‘’ on the embed and and filter’s allowed_view_modes count < 2, so there's no select.
In the submit function this code.
if ($form_state->getValue(['attributes', 'data-view-mode']) === $form_state->getValue('default_view_mode'))
Would result in a comparison of (FALSE === NULL) which would result in a FALSE when we would actually want it to execute the code.
$form_state->getValue(['attributes'])
evalutes to this:
and
$form_state->getValue('default_view_mode')
returns
NULL
This isn't a type juggling problem, but rather a strict comparison problem without making sure what we're comparing are strings.
To remove the chance for this I did two things: first, I moved the code that adds the default to the form out of a conditional, so that it is harder to get the default_view_mode to be NULL, since there's a default and the select form element for it on the config form doesn't allow you to set it to NULL. (I also renamed default_view_mode to filter_default_view_mode to be clearer about where it comes from in the submit function.) Secondly, I added a not NULL check to
$form_state->getValue(‘filter_ default_view_mode’)
to make sure we’re not comparing FALSE to NULL or an empty string to NULL.When the select for selecting a view mode in the dialog is there, this isn't an issue.
Comment #43
phenaproximaThis will need a reroll now that #3066802: Ensure that embedded image media items do not display at unreasonable sizes by default is in.
Comment #44
phenaproximaStill didn't read the tests, but I like this a lot!
This class is explicitly marked internal, and this code has not made it into a tagged release yet, so it's okay for us to add this constructor argument without a deprecation. 👍
I'd rename this to $filter_media_embed or $media_embed_filter, so it's clearer what it is.
I'm not sure we need this ternary logic; I'd imagine that the setting will always be there, and that it will always at least be an empty array, seeing as how it's part of the filter's plugin definition.
Nit: There's an empty extra line here.
Can we say which attribute we'll be dropping? :)
Ideally we'd save the result of
count($view_mode_options) >= 2
into a variable, and use it for both the if statement and the #access property of the select list.Nit: There's an empty blank line here too. Also, what happens if the $default_view_mode stays FALSE? How will that affect the usability of the select list? Do we have test coverage for that case?
"Display" seems like a strange term here, but I'm not sure what might be better. "Display as", perhaps? Also, a #description on this field might be useful. Additionally, should we make it #required if #access is TRUE?
I hope we have test coverage to prove that the attribute is actually removed. :)
Since we're adding the setting to the plugin definition, I'm not sure we even need this line anymore :)
Can we call this $view_mode_options, for clarity?
Should be $this->t().
I think this is supposed to be
$this->settings['default_view_mode']
. The fact that the tests didn't catch this means we are missing a bit of coverage :)This is not accurate; at least two view modes must be selected. Also, we should probably say what happens if no view modes are selected.
I think this needs @param doc comments for $element and $form_state.
Nit: This can be one line.
As I previously mentioned, I'm not sure we need this ternary logic.
I don't think this setting should ever be empty. Why don't we change the configuration form so that it's required?
We can actually do this a bit more slickly:
If we do this, we can remove the if statement in the foreach loop.
Comment #45
oknateAddressing #45
2. ✅ I can see now that $media_embed is a confusing variable name, since we have $media_embed_element, changed to $media_embed_filter.
3. ✅ Removed the terniary logic. My concern was, if someone is upgrading their config might not have this. But this is new in 8.8, so that’s not really an issue.
4. ✅ Removed extra empty line.
5. ✅ Updated to specify the ‘data-view-mode’ attribute.
6. ✅ Added a variable, $sufficient_view_mode_options.
7. ✅ Removed extra empty line.
8. I’m going to leave it as “Display” for now. “Display as Media Library” sounds Yoda-like to me. “Display” set to “Media Library” better to me. Is there precedence for “Display as”? I’d like some more opinions before changing this. There’s some weirdness with the naming here, especially as we now know when you select “Default” it’s the equivalent of ‘data-view-mode=“default”’ which isn’t really a view mode, but a view display. If you really wanted to be accurate we’d have set the filter up to use data-view-display=“media.default”. There’s some looseness under the hood with the naming here. Generally though, with the exception of “default”, view modes and view displays have a one-to-one relationship. Some other options: “Embed view display”, “Embed display”. Nothing strikes me as perfect. Leaving alone for now.
This is unnecessary since there won’t be a “none” option.
9. 👍 Yes, I have coverage for that at the end of media’s CKEditorIntegrationTest::testViewMode().
10. ✅ Removed
$this->settings += ['allowed_view_modes' => []];
11. ✅ Changed variable name for clarity
12. ✅ Switched to $this->t()
13. I disagree. This should be
'#default_value' => $this->settings['allowed_view_modes’]
. First off, it should be an array, secondly, when you have saved the form, you would want your previous selection to display.. We had discussed earlier whether it made sense to set the default value when$this->settings['allowed_view_modes’]
is empty to be just an array containing $this->settings['default_view_mode’]. For now I don’t think that makes sense. You need to view modes for the form element to appear in the EditorMediaDialog. So I think waiting until a site builder has explicitly chosen two is better UX.14. Since this is optional, we shouldn’t use the word “must”. I updated it to this: “If two or more view modes are selected, users will be able to update the view mode that an embedded media item should be displayed in after it has been embedded. If less than two view modes are selected, media will be embedded using the default view mode and no view mode options will appear after a media item has been embedded”
15. ✅ Added @param docs for the element validate callback. It’s inconsistent in core, based on a quick check, but I think it’s better to add them, even if they’re so common they’re not very useful.
16. ✅ Updated to one line.
17. ✅ Removed the terniary logic.
18. Removed the condition. But I don’t think we should make allowed_view_modes required. It’s supposed to be optional and I think making the field required but more than one item not required is confusing UX when using the config form.
19. Using
'mode' => $view_modes
doesn’t work. If memory serves me right, you can’t use arrays like that in loadByProperties().Comment #46
oknateHere's a video walkthrough for the feature.
Video:
https://www.drupal.org/files/issues/2019-09-14/view-mode-dialog-select-w...
Comment #47
geek-merlin😍!
#45:
> There’s some weirdness with the naming here, especially as we now know when you select “Default” it’s the equivalent of ‘data-view-mode=“default”’ which isn’t really a view mode, but a view display.
Ugh, allowing default here seems really odd to me in the first place. (But i guess that went in earlier and is under BC protection?)
Comment #48
oknateThe inclusion of "Default" as a view mode option is not under BC protection as Drupal 8.8 hasn't been release. But I think allowing "Default" makes perfect sense. The "Default" entity view display for media image has now been set up to be embed-worthy. See #3066802: Ensure that embedded image media items do not display at unreasonable sizes by default.
Comment #49
oknateComment #50
Wim Leers\Drupal\Core\Entity\EntityDisplayRepository::getDisplayModeOptions()
:🤔
'The view mode that is used by default'
(To avoid confusion with the
default
view mode.)🤓 Either we must say "view mode ID" everywhere, or we should just say "View mode" or here.
$allowed_view_mode_ids
We're making this form definition contain a lot of logic. Let's move this logic into a helper function.
I also have my doubts about this form label.
I looked at #2061377: [drupalImage] Optionally apply image style to images uploaded in CKEditor 5 to hopefully get inspiration from there. That uses as the label for an image style dropdown.
But I think
is probably even worse.What aboutI suspect that'd be fraught with localization issues. ?What about
, , , ?attribute.'),
🤓 Nit: I think the "by" in "by using" can be omitted?
👍
🤓 Übernit: 80 cols.
🤓 Übernit: inconsistent comment styles.
🤓 Übernit: s/id/ID/
🤓 Übernit: s/It/it/
🥳 Love that all our careful designing and planning in previous issues means only a single line needs to be changed here! :D
🤓 Übernit: this change is unnecessary, can be reverted.
Comment #51
oknateAddressing #51:
3. It's inconsistent that there’s a default entity view display when at the same time there's no default view mode, because all the other ones have view modes. This requires conditional handling if you’re trying to load a label from the current view mode, for example. Once you know about it, it’s easy to plan for.
4. ✅ Changed this to ‘The view mode that is used by default’. I’m not understanding which default view mode you’re talking about with which it’s conflicting. Can you point me to code?
5. ✅ I’ll stick with ‘allowed_view_modes’, I think that we’re asking for machine names or ids is obvious in a config that takes strings, also there’s precedence with the other setting ‘default_view_mode’.
6. ✅ Updated to $allowed_view_mode_ids.
7. ✅ Added a helper function. Nice suggestion.
8. I don’t love any of these. I’ll switch it to your suggestion “Format” for now.
9. ✅ Changed “by using” to “using”.
11, 12, 13, 14. ✅ Nits fixed.
16. ✅ Undid the change at end of the plugin.js. That was PhpStorm’s doing.
Comment #52
Wim Leers\Drupal\Core\Entity\EntityDisplayRepositoryInterface::DEFAULT_DISPLAY_MODE
.s/select/form/
Can be
static
.Why store this in form state? Why not look this up?
I don't think I've seen this anywhere else in Drupal core.
Nit: 80 cols.
Comment #53
oknateAddressing #52:
Re: $allowed_view_mode_ids vs $allowed_view_modes: Why don’t we just drop this variable, it’s only used on the next line now.
$view_mode_options = array_intersect_key($this->entityDisplayRepository->getViewModeOptions('media'), $media_embed_filter->settings['allowed_view_modes']);
1. ✅ Changed wording
2. ✅ Made the function static.
3. ✅ Switched to use $form_state->set(). The reason I didn’t look it up is that $editor is passed as the third argument to buildForm, so I don’t think it’s available in the submit function, which is why I was saving it in the form. Unless there's a way to do that in the submit function?
4. ✅ Updated the 80 col.
Comment #54
Wim Leers#53 is an improvement on all fronts! 👍
This comment is now obsolete, the
#access
line makes it crystal clear.🤓 Nit: the surrounding parentheses are unnecessary.
🤔 Better yet: why not wrap this entire thing in:
?
Then this could go away too!
🤓 Nit: 80 cols.
🤓 Nit: Gets
🤔 Would
$media_element_view_mode
,$media_element_view_mode_attribute
or$view_mode_attribute
be more clear?Comment #55
oknateAddressing #53:
1. ✅Fixed the edge case and added test coverage. It was only adding the blank caption when oldData.hasCaption was false. It also needs to add it when this.data.hasCaption is true but this.data.attributes['data-caption'] is not set. This might be able to simplified to
if (this.data.hasCaption && !this.data.attributes['data-caption']) {
2. ✅ Removed comment.
3. ✅ Removed the parentheses. We shouldn’t make the form field conditional. In the last patch (that added this form), Effulgentsia and Phenaproxima decided it’s better to leave the form fields and add #access rules because it makes it easier to extend the form. This is also how the other fields are set up, with the exception of image, which has a condition that the media requires an image source field, but also has an access check.
4. ✅ Thank you, I think $media_element_view_mode_attribute is much better.
Comment #56
oknateUpdating the logic for the bugfix, see #55.1.
This seems to work just as well.
I don't need to repost the FAIL patch, since it works for this patch too.
Comment #58
Wim LeersThere's 5 more coding standards violations to fix, but once that's done, I think this is RTBC 👍
Also, the issue summary still says there's new configuration on the CKEditor plugin, but it's now on the filter. So the issue summary needs to be updated, and it should document the reason for this decision.
Comment #59
oknateI'm not sure what to do to fix these warnings:
I think they are out of scope for this issue:
Given this was what was changed in those files:
Also, it passes js lint:
Comment #60
oknateAfter discussing with lauriii on slack, he said for eslint errors that are due to CKEditor APIs, we should add
// eslint-disable-next-line
statements.I added those, and if you run "yarn run lint:core-js" on the two es6 files, they show a few warnings, but no more errors.
I don't think that will help with the coding style warning. It's saying that these files are ignored due to a matching pattern and to run the test with the '--no-ignore' flag. That would be a change to either the .eslintignore in the core folder or a change to the way the tests are run so that eslint is run with the --no-ignore flag.
Comment #61
Wim LeersThanks for the issue summary update, @oknate! I clarified it further.
The current screenshot in the issue summary is outdated. We also should have a screenshot for each of the two UI additions.
Comment #62
Wim LeersNote: This should have been added as part of #2940029: Add an input filter to display embedded Media entities, but wasn't.
I think it's okay to do it as part of this patch instead of moving that to a separate issue/patch.
Comment #63
oknateComment #64
Wim LeersLike I wrote in #58: RTBC! 🥳
Comment #65
webchickOkay, reviewed this today with @oknate.
So first of all, the actual functionality is awesome, and a really good direction for us to go in.
The UX is... :\ not... so... awesome.... however. :\
This is a classic "pogo-sticking" UI. You're given a selection of options ("Full content", "Media library") but absolutely no idea what those will result in when selected. Your only recourse is to select one, save it, see what it looks like in the WYSIWYG editor, go back, select another one, see what it looks like in the WYSIWYG editor, repeat for however many options are available, then finally make your final selection, several (annoying) clicks later than the task would ideally take. After doing this exercise 3-6 times, you will eventually learn that "Media library" means "Small" and "Full content" means "Big," but the next content author after you is going to have to go through the same (frustrating) learning experience. :\ It is definitely not optimal.
Nate and I brainstormed about several possible options to resolve this:
I'm curious of others' thoughts. It's debatable whether we want to block this issue on solving the "pogo-sticking" problem or push it to a follow-up. The benefit here is high, even with the current UX, and Nate pointed out that Entity Embed (I think?) currently provides the same UI so we're not "regressing" from there. OTOH, it's creating new "UX debt" for us to clean up "later," which is not optimal. :\
The only other thing here is I would not name this "Format." We already have "input formats" which are a completely different concept, so please let's not conflate the concepts. I would name this "Size" or something that is more indicative of what it is.
Comment #66
webchickFor the record, The Phantom of Phenaproxima apparated in from his vacation to vote for option #65.3. ;)
Comment #67
Wim LeersCorrect, this is a limitation of entity view modes. They do not offer previews, they do not have icons.
Agreed that none of those are viable. The second one is technically viable but would result in a horrendous UX.
I do agree that usually it will be about size though. But view modes are not guaranteed to map to "size". Different fields may be displayed for example: in case of "painting" media, it could be that you're using the "painter information" view mode or the "pannable painting" view mode, which would display completely different information.
The root cause of all this: view modes are a powerful abstraction, but they're so abstract that the content author must know about them. This is honestly why I personally believe this does not belong in Drupal core but in a Drupal contrib module.
The reason I RTBC'd it nonetheless is that:
<select>
is only ever visible if you select at least two checkboxes in . Otherwise, the default view mode is still used (which we just improved at #3066802: Ensure that embedded image media items do not display at unreasonable sizes by default to look sane out-of-the-box). In other words: only sites that A) create multiple view modes, B) specifically configure this to enable content authors to pick a specific view mode will ever get to see this dropdown in theEditorMediaDialog
!Comment #68
webchickCorrect. However, the reason this issue is in the "must-have" list is to prevent this situation from happening, since it prevents you from editing your content:
In order to resolve this, we need the ability to resize the embedded media, which implies the existence of at least two view modes in most cases (I think? Though maybe not?). This issue is one possible way of solving that. #3078287: Constrain the width of aligned images, media, blockquotes etc to a max of 75% is another, and would be my preference, since it doesn't add any complexity to the UI, but that one seems not to be as easy to get in as we thought. :\ (But @oknate seemed to think it was making headway, which is great.)
Fair point on why not "Size." "Display" or something could work in that case then.
Comment #69
Wim LeersThat is not my understanding.
That is the only way to solve the problem you demonstrated in the screenshot.
We don't want content authors to pick a different view mode because it looks bad in the assistive text editor. In fact, with this issue they still cannot "solve" that unless the configuration changes that I mentioned are made.
This issue is about allowing content authors to pick the view mode that is appropriate for the context it will be displayed in to end users. A number of people who have been involved in the Media Initiative for years were very vocal that on complex site use cases, this is essential. IIRC @seanB and @marcoscano felt very strongly about this. Perhaps they can chime in here?
Hah — that's what it used to be! 😂 But both @phenaproxima in #44.8 and I in #50.8 thought that was too confusing and odd. I provided some suggestions in #50.8, and @oknate went with . I'm happy to go with if you feel that is clear after all :)
Comment #70
oknate+1 for "Display" for the label.
Comment #71
seanBPersonally, I would never enable the 'Media library' view mode for use in WYSIWYG editor. When you need multiple ways of displaying media in the editor, you would create your specific view modes, name them properly, and then only allow the ones that are meant to be embedded.
So for me a sensible default would be: only enable the 'default' display (this also means by default editors wouldn't have to choose anything!), and allow users to enable other things as they see fit after they created new/more view modes.
Comment #72
FeyP CreditAttribution: FeyP as a volunteer and at werk21 commentedIf I may contribute my 2ct from the sidelines regarding #65:
TLDR:
Overall, I see the point, but I think it's more like a should-have. The issue is mitigated by the fact, that editors will learn, which view mode they would need to choose to get the desired as they will get familiar with the site. At the same time, the existing implementation is already a major improvement and if you would ask me, I would be in the group of the very vocal people mentioned by Wim, who argue this is a feature needed in more complex setups. I can imagine that basic sites could get away with just one view mode, but for most of our projects for example, that are usually more complex, we just need the option. The implementation in the patch would work very well for us already and what Sean said in #72 makes a lot of sense, so why not just go with it as is and work on a solution for #65 in a follow-up?
W/r/t the options:
Regarding the label of the option:
And finally, thanks for working on this! Really looking forward to using all the new features in production :).
Comment #73
seanBoknate asked for my opinion on the mentioned option in #65, so here it is:
So I would go for option 3, if using the display name of the view mode is not good enough.
I also agree with everything in #72. Thanks FeyP for taking the time to write this.
Comment #74
marcoscanoLate to the party, but I'm also in favor of not blocking this on #65
I get the concern though... To me, it boils down to: depending on which hat you are using, you'll see one side of the vase... :)
If I'm thinking from a wordpress-ish perspective, under the expectation that Drupal evaluator's experience should "just work" without UX hurdles, it is indeed somewhat annoying having to click through all the options to find something that suits what you are doing. To me in that scenario, the solution would possibly involve directly embedding, and then allowing for resizing (🙈), or having a friendly tooltip or something that would let users easily "make this bigger/smaller". That has a world of ramifications and complexities, especially when dealing with non-image media. (and for the record, I personally _don't_ think we should go this route)
If I'm thinking from the ambitious-digital-experience-site perspective, where editors are relatively well-trained and do that all day long, I think it's fairly reasonable to expect that they will be familiar with the relationship between "viewmode labels -> how things look".
And I reiterate what others said... yes, I think the ability to choose the representation of the "embedded thing" while embedding it is a must on all sites I've worked on. Also fair to say that these sites wouldn't have a problem in using a contrib module to get that extra bit of functionality...
TBH, I am not really sure anymore which sites are in the 80% Drupal use case at this point... 🤷♀️
Also, a minor question about:
Would it be worth disabling the options that have instances using them?
Not sure if it's worth the complexity of checking this, but I can see a situation where the dev/site builder "thinks" that disallowing one viewmode here will make it magically disappear/change from wherever it's being used. Not letting them disallow viewmodes that are in use in the first place might be a simple way to avoid all that confusion.
Comment #75
oknateIn regards to #74's question:
If you have a piece of content that has two embeds, one with view mode "Full" and one with view mode "Teaser", and you disable all the options here, the only thing that changes is that when you click the "Edit media" button in the upper right hand corner of one of the embeds, there's no longer an option presented to change the view mode. So I would argue "no", it's not worth disabling options in use within embeds. It would be a lot of code to determine the entity usage, and the allowed_view_modes only control access to this form element, at this point.
This bit of the dialog will probably be extended in contrib modules. My hope is we can keep it a simple as possible in core, at least until someone comes up with a brilliant more complex solution.
Comment #76
marcoscano#75: Thanks!
I agree it's a hard thing to solve... The confusion I wanted to point out was not so much concerning the form, but more in regards to the situation when the site builder disallows a viewmode, and existing content continues to be rendered in that viewmode. There might be an expectation that it wouldn't happen (even though it's clear that if you don't provide a replacement, the system can't guess what it should use to render your existing content, but...)
Since this is a site-building/dev facing setting, maybe with an additional help text like "Unselecting these options will not change existing content that was embedded with them", or "Will only affect new content" could be enough?
Comment #77
Wim LeersJust one remark: the problem with using the label "view mode" is that only a Drupal site builder or developer understands what this means. Then again … perhaps it's not really more unclear than "Display" 🤓 Agreed that good translation context is essential.
We cannot detect this both reliably and efficiently. Furthermore, this is only a UI-level suggestion setting: this does not restrict the view modes actually used and respected in filtering. It's still possible to specify any valid view mode ID in the
data-view-mode
attribute.So it does not work in the way you describe in #76 — that was considered to be undesirable. This setting does not affect neither existing content nor new content: it only affects the
EditorMediaDialog
's UI elements.Comment #78
webchickAwesome, thanks for all of the thoughtful feedback, esp. from folks using Media with content editors day-to-day! Very valuable. :)
I think I'm convinced that we can discuss the "pogo-stick" problem separately, and not put it in front of this patch. It's a good point that the impact might be moot (or at least far lessened) if the site builders choose view mode labels that make sense to content authors. And they can always be trained, that is true; it's just definitely less ideal than an intuitive UI that doesn't need training. :) For that, we need something more akin to what @marcoscano brings up, where the resizing happens on the front-end, but that's definitely a huge UX dragon to slay, and also not a must-have we want in front of Media Library. ;)
So then I think this is only "needs work" for the label; sounds like we're coalescing around "Display", but we need to sort out the translation context.
Comment #79
oknateComment #80
Wim LeersComment #81
larowlanThis looks great, leaving at RTBC cause there's only a personal preference nit I can find
these changes seem out of scope - can you advise why they're required - edit: nevermind found comment #55
note to self/other reviewers - this class has not yet been in a tagged release, so we don't need to do the BC dance here. In addition, we also don't need an upgrade path for the config changes 🎉
ubernit: we can return early here and avoid the elseif
Comment #82
oknateIf we're going to return early in that method then setting the $default_value variable makes less sense. I reworked the method to return early without setting the $default_value variable.
Comment #83
Wim Leers#81.1: I discovered that bug in #54.1. @oknate included the fix here, but alternatively #3081988: Disappearing edit button and caption on media embed when using dialog could be committed first. Or actually, we could even omit it from this issue/patch altogether. I think that'd indeed be preferable.
Comment #84
oknateAddressed #83, removing the fix for disappearing caption and edit button. That can be handled separately in #3081988: Disappearing edit button and caption on media embed when using dialog.
This patch removes the fix and the test coverage that was specific to switching view modes for that bugfix. If we want to add this test coverage back in that issue, we'll discuss it there.
Comment #85
Wim Leers🤓 Nit: Now all changes in this file seem pointless too — literally nothing is changing but
eslint
compliance "fixes" and a docs addition. Let's omit that from this issue too: tighter scope is easier to review, commit andgit blame
:)Comment #86
oknateAddressing #85: Removed eslint and coding standard fixes from
core/modules/media/js/plugins/drupalmedia/plugin.es6.js
Comment #87
Wim LeersComment #88
webchickIssue credit.
Comment #90
webchickOk, gave this another once-over; apart from this line of horror and doom that we should probably move to its own method in a follow-up...
...this looks good to me, and looks like @larowlan's feedback has been addressed as well. The UX issues identified in #65 are somewhat mitigated by a) we don't show a view mode selector in the dialog unless there are at least two options selected by the site builder, and b) site builders are able to name these whatever they want, including "Small" and "Big" or whatever.
I can see this being a really powerful feature for lots of sites (including Drupal.org!) so let's get this sucker in, and tag it as a highlight!
Committed and pushed to 8.8.x. Woohoo!!
Comment #92
Chris Burge CreditAttribution: Chris Burge at University of Nebraska commentedDrupal\media\FormEditorMediaDialog::buildForm()
:Dropping the 'data-view-mode' attribute can result in corruption of user data. I've opened a critical bug to address: #3109289: MediaEmbed conflates default view mode with user-selected view mode
Comment #93
Wim LeersSuperb find, @Chris Burge! 👏🙏