#135 | standard-default-image-view-mode-large-2.mov | 4.89 MB | oknate |
#135 | standard.png | 590.91 KB | oknate |
#133 | demo-umami-default-image-view-mode-large.mov | 6.6 MB | oknate |
#133 | snake-river-image-embedded.png | 501.14 KB | oknate |
#131 | 3066802-interdiff--129-131.txt | 989 bytes | oknate |
#131 | 3066802-131.patch | 28.11 KB | oknate |
|
#130 | 3066802-130.patch | 2.28 KB | oknate |
|
#130 | 3066802-130--FAIL.patch | 897 bytes | oknate |
|
#129 | 3066802-interdiff--129--FAIL--to-129.txt | 1.41 KB | oknate |
#129 | 3066802-129.patch | 28.43 KB | oknate |
|
#129 | 3066802-129--FAIL.patch | 26.58 KB | oknate |
|
#128 | 3066802-interdiff--126-128.txt | 1.36 KB | oknate |
#128 | 3066802-128.patch | 27.79 KB | oknate |
|
#126 | 3066802-126.patch | 27.76 KB | oknate |
|
#126 | 3066802--interdiff-124-126.txt | 11.99 KB | oknate |
#124 | 3066802-interdiff--109-124.txt | 46.52 KB | oknate |
#124 | 3066802-124.patch | 20.82 KB | oknate |
|
#109 | 3066802-109.patch | 30.07 KB | oknate |
|
#109 | 3066802-interdiff--106-109.txt | 3.87 KB | oknate |
#107 | 3066802-interdiff--103-106.txt | 18.47 KB | oknate |
#107 | 3066802-interdiff--104-106.txt | 20.19 KB | oknate |
#107 | 3066802-106.patch | 30.07 KB | oknate |
|
#104 | 3066802-104.patch | 30.23 KB | oknate |
|
#104 | 3066802--interdiff-103-104.txt | 29.85 KB | oknate |
#103 | 3066802-103.patch | 28.81 KB | oknate |
|
#103 | 3066802--interdiff-101-103.txt | 640 bytes | oknate |
#102 | 3066802-102.png | 284.79 KB | phenaproxima |
#101 | 3066802-101.patch | 28.73 KB | oknate |
|
#101 | 3066802--interdiff-99-101.txt | 527 bytes | oknate |
#99 | 3066802-99.patch | 28.77 KB | oknate |
|
#99 | 3066802--interdiff-94-99.txt | 3.42 KB | oknate |
#99 | 3066802--interdiff-97-99.txt | 3.36 KB | oknate |
#97 | 3066802-97.patch | 28.74 KB | oknate |
|
#97 | 3066802--interdiff-94-97.txt | 1.21 KB | oknate |
#95 | 3066802-94.patch | 28.8 KB | oknate |
|
#95 | 3066802--interdiff-93-94.txt | 7.92 KB | oknate |
#93 | 3066802-93.patch | 28.58 KB | oknate |
|
#93 | 3066802-interdiff--91-93.txt | 492 bytes | oknate |
#91 | 3066802-90.patch | 28.62 KB | oknate |
|
#91 | 3066802-interdiff--88-90.txt | 504 bytes | oknate |
#89 | 3066802-88.patch | 28.6 KB | oknate |
|
#89 | 3066802--interdiff-86-88.txt | 15.15 KB | oknate |
#86 | 3066802-86.patch | 24.74 KB | oknate |
|
#86 | 3066802--interdiff-60-86.txt | 7.64 KB | oknate |
#86 | 3066802--interdiff-85-86.txt | 997 bytes | oknate |
#85 | media-embed-no-image-style-warning.png | 282.46 KB | oknate |
#85 | 3066802-85.patch | 24.64 KB | oknate |
|
#85 | 3066802--interdiff-60-85.txt | 7.53 KB | oknate |
#60 | 3066802-60.patch | 22.23 KB | oknate |
|
#60 | 3066802--interdiff-54-60.txt | 7.47 KB | oknate |
#55 | 3066802--interdiff-48-54.txt | 9.09 KB | oknate |
#54 | 3066802-54.patch | 19.14 KB | oknate |
|
#54 | 3066802--interdiff-52-54.txt | 2.66 KB | oknate |
#53 | 3066802-53.patch | 18.97 KB | oknate |
|
#53 | 3066802--interdiff-48-53.txt | 8.19 KB | oknate |
#48 | 3066802-48.patch | 19.01 KB | oknate |
|
#48 | 3066802--interdiff-46-48.txt | 1.38 KB | oknate |
#46 | 3066802-46.patch | 19.06 KB | oknate |
|
#46 | 3066802--interdiff-44-46.txt | 6.88 KB | oknate |
#44 | 3066802--interdiff-43-44.txt | 784 bytes | oknate |
#44 | 3066802--interdiff-36-44.txt | 14.8 KB | oknate |
#44 | 3066802-44.patch | 18.79 KB | oknate |
|
#43 | 3066802-43.patch | 18.79 KB | oknate |
|
#43 | 3066802--interdiff-36-43.txt | 14.8 KB | oknate |
#43 | 3066802--interdiff-41-43.txt | 2.5 KB | oknate |
#41 | 3066802-41.patch | 19.27 KB | oknate |
|
#41 | 3066802--interdiff-36-41.txt | 14.67 KB | oknate |
#41 | 3066802--interdiff-40-41.txt | 8.99 KB | oknate |
#40 | interdiff_36_40.txt | 6.05 KB | anmolgoyal74 |
#40 | 3066802-40.patch | 21.48 KB | anmolgoyal74 |
|
#38 | interdiff_36_38.txt | 7.44 KB | anmolgoyal74 |
#38 | 3066802-38.patch | 22.06 KB | anmolgoyal74 |
|
#36 | 3066802-36.patch | 21.68 KB | oknate |
|
#36 | 3066802--interdiff-35-36.txt | 1.81 KB | oknate |
#36 | 3066802--interdiff-29-36.txt | 9.76 KB | oknate |
#35 | 3066802-35.patch | 21.64 KB | oknate |
|
#35 | 3066802--interdiff-29-35.txt | 9.64 KB | oknate |
#29 | 3066802-29.patch | 19.92 KB | oknate |
|
#29 | 3066802--interdiff-26-29.txt | 12.39 KB | oknate |
#26 | 3066802-26.patch | 19.05 KB | oknate |
|
#26 | 3066802--interdiff-25-26.txt | 3.53 KB | oknate |
#25 | 3066802-25.patch | 19.26 KB | oknate |
|
#25 | 3066802--interdiff-24-25.txt | 1.83 KB | oknate |
#24 | 3066802-24.patch | 19.24 KB | oknate |
|
#24 | 3066802--interdiff-23-24.txt | 4.92 KB | oknate |
#23 | 3066802-23.patch | 14.32 KB | oknate |
|
#23 | 3066802--interdiff-22-23.txt | 1.78 KB | oknate |
#22 | 3066802-22.patch | 14.25 KB | oknate |
|
#22 | 3066802--interdiff-18-22.txt | 7.91 KB | oknate |
#22 | 3066802--interdiff-21-22.txt | 1.19 KB | oknate |
#21 | standard profile.png | 1.11 MB | oknate |
#21 | umami test.png | 3.35 MB | oknate |
#21 | 3066802-21.patch | 14.21 KB | oknate |
|
#21 | 3066802--interdiff-18-21.txt | 7.93 KB | oknate |
#20 | 3066802-18.patch | 17.11 KB | oknate |
|
#20 | 3066802-interdiff--17-18.txt | 1.4 KB | oknate |
#20 | confirmation message on creating new media type.png | 57.56 KB | oknate |
#19 | media--embed-view-mode-480x480.png | 1.25 MB | oknate |
#17 | 3066802-interdiff--14-17.txt | 5.53 KB | oknate |
#17 | 3066802-17.patch | 16.19 KB | oknate |
|
#16 | 3066802-interdiff--14-16.txt | 5.53 KB | oknate |
#16 | 3066802-16.patch | 33.1 KB | oknate |
|
#14 | 3066802-14.patch | 11.59 KB | oknate |
|
#11 | 3066802-11.patch | 65.65 KB | oknate |
|
#11 | 3066802--interdiff-6-11.txt | 922 bytes | oknate |
#8 | 3066802-6.patch | 65.65 KB | oknate |
|
#8 | 3066802--interdiff-5-6.txt | 23.45 KB | oknate |
#7 | 3066802-5.patch | 75.11 KB | oknate |
|
#4 | 3066802-4.patch | 9.43 KB | oknate |
|
#3 | 3066802-3.patch | 5.03 KB | oknate |
|
#2 | Screenshot 2019-08-13 at 12.22.27.png | 3.53 MB | Wim Leers |
Comments
Comment #2
Wim LeersNow that #2801307: [META] Support WYSIWYG embedding of media entities is mostly done, with #2994696: Render embedded media items in CKEditor and #2994699: Create a CKEditor plugin to select and embed a media item from the Media Library having landed, I think it's time we start pushing this forward at the same time, to improve usability and avoid a big DrupalWTF when people excitedly try this media embedding functionality in Drupal 8.8.
The WTF-aspect can easily be reproduced:
/node/add/article
.(Not to mention this is also what the end users get to see.)
Comment #3
oknateHere's an initial patch that solves #2.
It installs the view mode with the media module, and adds optional configs for the media bundles installed by the standard profile.
I think maybe these optional configs should go into the standard profile. I wasn't sure. I borrowed them from media library and tweaked them ever so slightly, by using larger image styles. The fact that media library has them within the module, made me think we could include them either within the media library (because an embed button doesn't exist until you install media_library), but decided to put them in media, because if you install the standard profile and have some other contrib means of adding the drupal-media tag within content, it would be nice for it to work too.
@todo We'll need an update hook to install the configs on existing sites.
Comment #4
oknateOops, I forgot the code that switches the default view mode.
Comment #5
Wim LeersI think they can live in the
media
module to be honest. That's what the patch is currently doing, so 👍A side benefit is that
@Filter=media_embed
can then also assume this exists!Another side benefit would be that we can automatically install this config in an update hook, so existing sites can start using this without complex manual steps!
Comment #7
oknateThis patch adds a bunch of configs in order to get the DefaultConfigTest test to pass. These optional configs have a lot of dependencies. So this adds them, which fixes the test, but will force the install of these bundles on new installs.
The problem is, we don't want to force all of these to be installed. So either that test needs to change, or we need to move all of these optional configs to standard and demo_umami. I don't understand how media_library has similar configs without the dependencies and it passes the same test.
Comment #8
oknateThis patch drops the optional configs, and uses post update hooks to configure the displays. This was surprisingly easy, thanks to the Media Library module already having the code. I just had to copy it over, update some strings and remove extra code creating form displays.
Comment #11
oknateFixing dependency on the view mode I added. By the way, the reason I'm not using 'medium' or 'large' as I originally was, is because of this issue I encountered: #3030437: Remove dependency on 'medium' and 'thumbnail' image styles from media and media library modules.
Comment #12
oknateComment #13
oknateThe patches are totally off. I think I forgot to merge in the latest changes to my working branch, and so there's a bunch of extraneous stuff in there.
Comment #14
oknateRerolled the patch to remove extraneous changes.
Comment #15
oknateAfter discussing this with phenaproxima, I realized I made a mistake removing the configs in #8. The post update hook won't run on install, so unless configs are provided, they'll be missing on new installs.
Comment #16
oknateIgnore this one, it has extraneous changes.
Comment #17
oknateAdding back configs. Note, the image_style the patch is adding is 480x480. The same as the image module's default 'large' image style.
Comment #18
oknateI'm noticing that media library has code that installs the display when a media type is created through the UI.
and test coverage media_library/tests/src/Functional/MediaLibraryDisplayModeTest.php
Should we copy that over and do the same thing, so that a view display is set up for media types when added through the UI?
Comment #19
oknateHere's a screenshot of the current patch's image style, 480x480, same as core 'large' image style. I think it's maybe too large.
Comment #20
oknateAddressing #18 (but needs test coverage). Here's the confirmation message when creating a new content type:
Maybe for the confirmation message, this is better: 'An embed view display has been created for the %type media type.'?
Comment #21
oknateI realized it's a chicken and egg thing to try to include optional media view displays in the media option configs. You can't install those until the media module is installed. So removing once again. The media library can do it, but the media module can't. So moving the configs to standard and umami profiles.
I tested out some image sizes and for umami, I used their large style 'large_21_9'. For standard, I couldn't find one I liked, since I'm trying to accommodate 16:9 landscape images, so for now I'm using the 'media_embed' style included in the media module.
Comment #22
oknateFixing some dependency issues I noticed on the last patch.
Another thing to note. I dropped the configs for the bundles other than image. In the demo_umami profile, it seems to me that the default configuration for the other bundles are sufficient. They don't use an image field. The problem we're trying to solve here is that the default image bundle in demo_umami and the standard profile use a raw image:
So I think we really only need an entity_view_display config for that bundle in the those profiles.
For minimal installs and existing sites that are upgrading, there's the form submit hook that will add an entity_view_display using. the thumbnail and the view mode 'media_embed' we're adding.
Comment #23
oknateAdding a dependency to the entity view display configs. The DemoUmamiProfileTest is still failing locally. I'm still trying to figure out how to fix it. But I wanted to post this update, since I think it's better.
Comment #24
oknateAdding test coverage for #18 and #20, adding view display when media type added through the UI.
Comment #25
oknateThis fixes the demo umami test error.
Comment #26
oknateA little cleanup.
Comment #27
oknateNext steps:
Comment #28
phenaproximaNice work! This patch is looking great! It does need some changes (and some questions to be answered by committer-type folk), but overall this is a solid approach.
We don't need the @throws, because this function never actually throws anything.
Nit: $values does not need to be its own variable.
A quicker way to do this without looping:
$display->set('content', [])
.So...I'm not sure why we would want to expose the thumbnail in an embedded view mode. For a YouTube video, for example, we'd want to show the video itself (the iframe). What we should do here instead is take advantage of MediaSourceInterface::prepareViewDisplay().
It makes sense for Media Library to configure the thumbnail, since that's what's normally displayed in the media library. But for an embed, we should use the defaults provided by prepareViewDisplay().
I know this was copied and pasted from Media Library, so this is not your fault at all. But looking at it with fresh eyes, this line makes no actual sense :)
If $display->save() fails, it throws an exception. If it succeeds, it returns SAVED_NEW or SAVED_UDPATED, both of which cast to boolean TRUE. So in other words, this function will always return TRUE. Let's just remove this line here, and open a follow-up to fix it in Media Library.
I was going to suggest using hook_form_BASE_FORM_ID_alter() instead, but I see this is following what Media Library already does.
Since the return value of _media_configure_embed_view_display() is useless, I would instead suggest this:
Or, if we want to be harsher, we can just call the function and not bother catching the exception.
How did we arrive at these dimensions?
Why not use
['%label' => $image_style->label()]
?I think I'd like a release manager to validate this. Also, nit: $values doesn't need to be its own variable.
So, here's the thing -- most media types don't necessarily need a specialized embed display. The only ones which really do, at least for now, are the ones that use images as their source field. I'm wondering if, to simplify things, we should create the view displays selectively -- i.e., only do this for image media types. I'd like to hear a product manager's opinion on this idea before we proceed, though.
system
is installed anyway; I don't think it needs to be explicitly listed in $modules.Comment #29
oknateAddressing #28:
1. ✅ Removed the throws statement in the comment.
2. ✅ Added chaining.
3. ✅ replaced loop with $display->set('content', []).
4. ✅ Changed the displays to use ::prepareViewDisplay(). That’s a handy method! I also updated the tests since they were testing for the thumbnail.
5. 👎Removed the return statement, and added a follow-up for media library: https://www.drupal.org/project/drupal/issues/3077822
But, later on, I added it back. We need a way to determine if the view display was updated, so that we can only display the success message when it was updated. There are two cases where it would not throw an error, but wouldn’t update the display. If the entity view display is empty (such as if they deleted it), or if the view mode is empty (if they deleted it). The second case is actually not handled in the Media Library module. I added an issue for it. #3077932: Prevent deletion of the Media library view mode
6. As you point out, this follows the model established in media_library. Also we don’t want to lock this into one form. In the off-chance that someone extends that form and it has a different form id.
7. Added try catch statement.
8. Those dimensions are just placeholders added by me. I just looked at a recent project I had worked on to get a general idea and I added similar dimensions. My personal preference is that we use a landscape aspect ratio so that landscape images aren’t really small. The possibilities here are endless.
9. Changed to
$image_style->label()
, per your recommendation. I could see the argument against this change, though. We’re hard-coding it a few lines above.So what's the point in this context?
10. ✅ Removed the variable $values.
12. Removed the dependency to ‘system’.
Comment #30
phenaproximaThanks for the updates! This is shaping up.
So this has
cache: true
(which is the default value)...yet we explicitly disable caching when rendering embedded media, instead relying on the caching of the host entity. I wonder if we should havecache: false
in this view mode, for this reason. I'd like Wim to confirm or deny this idea.This return description should be rephrased. How about: "Returns TRUE if the entity view display was configured correctly, FALSE otherwise."
Nice. This is a good use of the boolean return! :) I agree with your justification.
A comment over this bit would be useful. "If the embedded entity view display has already been configured, we don't need to redo it."
This will use our image style for every image-formatted component in the display. I think that's a bit overreaching. Instead, we should check if the source field is an ImageItem (or a subclass thereof), and if it is, we should configure only the source field to use our special image style (assuming it's using the image formatter, of course, and has no image style already applied). So that will be a bit more verbose, but I think it will also be less "invasive". Something like this:
Comment #31
catchThis update depends on the image style, but post updates aren't guaranteed to run in any particular order, so we should merge the two updates into one.
Comment #33
webchick@effulgentsia did some great research around the existing Image module, YouTube embeds, etc. and came to the conclusion that the best thing to do here is to have the view mode's image style default to "Large" (which we should be able to do because it's provided by Image module, which is a dependency of Media module). This will create the best consistency with other fields on the site, and ensure that if a site builder adjusts this size to be different, Media stays consistent.
Comment #34
webchickAdditionally, per the bug exposed on the UX call, this should change the image from "Link to full-sized image" (or whatever it's called) to "No link" so that links to things can be added to images from CKEditor.
Comment #35
oknateAddressing #30:
1. Leaving this for Wim to confirm or deny. I suppose someone could use the ‘embed’ view mode elsewhere and then, you’d want it to cache in that circumstance. But also, the way the embeds render, I think this setting is irrelevant.
2. ✅ Replaced with your verbiage, thanks.
5. ✅ Removed the loop and used your code that identifies the source field and only updates that one. This is good in the off-chance that
$type->getSource()->prepareViewDisplay()
returns more than just the source component.Addressing #31:
We're dropping the new image style, so this is no longer relevant, but thank for pointing that out. I didn't know that. I thought they ran alphabetically.
Addressing #33:
Removed the new image_style and replaced it with large.
That means this screenshot is relevant again, and we can remove the "needs screenshots" tag.
Comment #36
oknateAddressing #34:
Removing the link to the file. I eyeballed this one as I was running out of time to work on it. I will go back and test it later today.
Comment #37
phenaproximaI'm glad we were able to agree on a scope for this patch. This is cleaner, better, and constantly improving.
We should use
\Drupal::service('entity_display.repository')->getViewDisplay('media', $type->id(), 'embed')
here, rather than calling static methods of EntityViewDisplay. It will create the display (without saving) if it doesn't exist. We can return FALSE if $display->isNew().Let's change the comment a bit. I would suggest "If this media type is using an image field as its source field, set the image style to the 'large' image style included with the Image module."
What's $config? This should be:
Also, we should be returning early from this function if the 'large' image style doesn't exist.
This is no longer needed.
We don't need to set the 'module' dependencies manually. The fact that it's an enforced dependency makes that redundant. So this should be:
Nit: There's no need for $view_display_created to be its own variable.
Why do we need to do drupalPostForm() twice? That shouldn't be necessary...
Nit: Let's call
$assert_session = $this->assertSession()
at the top of the method, and reuse that throughout. I'd like Media to standardize on one style of asserting things.This isn't really needed.
This is a false assertion. It should be asserting the absence of the text "The Embed view display has been created for the d'Artagnan media type." (It should not have the label of the media type, not its ID.) This is yet another reason why we shouldn't be keeping the media type ID in its own variable. :)
There is no need for this line. All media types are required to have a source field.
Except in certain unusual cases, we should use === everywhere.
This can be $this->assertInternalType('array', $field).
We should also assert that the image_link setting is empty.
This can be a little cleaner, IMHO, in this form:
Overall, this method should assert the view display exists and has an array component for the source field. Then, if the type's source plugin is 'image', it should also assert that the component has the correct image_style and image_link configuration. So generally I think we should refactor this whole method in that direction.
This, and its related
use
is not needed.Aren't there more media types for us to assert?
I think there's an extra blank line at the end of this file. (There should only be one.)
Comment #38
anmolgoyal74 CreditAttribution: anmolgoyal74 commentedComment #40
anmolgoyal74 CreditAttribution: anmolgoyal74 commentedUpdated with most of the suggestions.
Comment #41
oknateAddressing #37 and (validating changes in #38 and #40):
1. ✅ Updated to if !$display->isNew(), and using entity display repository.
2. ✅ Updated in #38.
3. ✅ Updated in #38.
4. ✅ Updated in #38.
5. ✅ Updated in #38.
6. ✅ Updated in #38.
7. The two post forms were because functional tests can’t do Ajax, so that was a work-around (In the original test this was copied from in media library.) Based on the conversation we had on Slack, I’m switching the test to a functional javascript test in this patch, so it doesn’t have this wonkiness.
8. ✅ Updated in #38.
9. ✅ dropped the variable.
10. Updated to use the label in the assertion.
11. ✅ Updated in #38.
12. ✅ Updated in #38
13. Changed to
$this->assertInternalType('array', $field);
14. ✅ Updated in #38
15. ✅ Updated.
16. ✅ Updated.
17. ✅ Additional types added in #38
18. ✅ Updated in #38
Comment #43
oknateI didn't test the update test when working on the last patch. I had the version in #38 which failed, oops. Now that I tested it, I can see the only types are File and Image in this context:
I could have just removed the extras, as #40 does, but decided to abstract it, so that if these dump files change and if more media types are added in an updated dump file, it would still work.
The test starts with these:
Comment #44
oknateCoding standard fix.
Comment #45
phenaproximaAlmost there -- unfortunately, there's a big flaw in the test. :( But I don't think it'll take much effort to fix.
Should be 'AJAX'.
This is wrong. We are passing media type IDs into this method, and none of them are 'image'. We really should be loading the media type, getting the source field definition, and only asserting things if it's an image field. So, I think this method should look like this:
This should be assertEmpty(). We want to prove that the image is not linked in an embed.
Then, I noticed an architectural thing:
Looking at this more closely, I think we might be violating encapsulation here. This kind of logic is exactly what MediaSourceInterface::prepareViewDisplay() was intended to do, and so IMHO the Image source plugin should be responsible for doing this in its prepareViewDisplay() method. I think that will be much cleaner.
So, I suggest that we remove this block, and modify \Drupal\media\Plugin\media\Source\Image::prepareViewDisplay() -- we'll need to override the method -- like so:
Comment #46
oknateAddressing #45:
1. ✅Changed to uppercase 'AJAX'.
2. ✅Oops, I obviously got confused when I was refactoring that. You're right, I was conflating media bundles and media source plugins. Updated per your recommendation.
3. ✅Changed
$this->assertNotEmpty($component['settings']['image_link']);
to$this->assertEmpty($component['settings']['image_link']);
D'oh!4. ✅Moved the code configuring the display into prepareViewDisplay for the image source plugin. Brilliant! That is much more appropriate.
Comment #47
phenaproximaOh, this looks gooood...
I would suggest moving this comment to Image::prepareViewDisplay() and rephrasing it slightly. Something like:
For the `embed` display mode, use the `large` image style and do not link the image to anything.
Can we get a blank line after the parent::prepareViewDisplay() call, for readability?
Comment #48
oknateAddressing #47.
1. ✅Done.
2. ✅Done.
Comment #49
phenaproximaThank you!
Second line of the comment needs a space after the //.
Also, I just realized this comment doesn't explain why we're doing this. So let's add some more wording. I suggest: "This is done in order to ensure the image does not become too unwieldy when embedded into formatted text, and to allow it to wrapped by an author-created link."
Comment #50
phenaproximaShould be "Embeds need..."
This is a bit inaccurate. The display is automatically created for custom media types, it just needs to be re-created for existing media types. Maybe we should change that sentence to "Ensure that all existing media types have an embed display."
We should probably update DemoUmamiProfileTest to ensure this display exists and looks the way we expect.
Same for StandardTest.
Comment #51
Wim Leers\Drupal\Core\Entity\EntityDisplayModeBase::$cache
, which saysWhether or not the rendered output of this view mode is cached by default.
. I agree we can set this tofalse
. Well-spotted! 👏👍Nit: 80 cols.
Nit: This is a pointless comment IMHO.
🤔👍 This really should not be happening using form alters, but using entity hooks, so that this also works when creating media types via either the Entity PHP API or via the JSON:API HTTP API or via the REST HTTP API or via GraphQL. But … this is following the pre-existing pattern frommedia_library_form_alter()
where we did try to do that and it turned out to be impossible. (Not to mention you can't create config entities via REST/JSON:API/GraphQL yet anyway.)So +1.
🤔
Nit: s/display/displays/
Also: it's odd to be talking about entity view displays and then see entity view display modes in the function name.
This is plural, but we create only one view mode.
🤔 This text is out of place here?
"let's make sure this is fixed" -> this sounds really odd.
🥳🥳🥳🥳
🤔 Nit: I think this is needlessly complex. I don't think other update tests are asserting the message?
🤔 Function name and description do not match.
🤔 This comment seems wrong? We're deleting things, not "saving an existing media type"? It feels like I'm missing something.
Nit: 80 cols.
Rather than replacing this test case, we should keep it, and add a new one. This is specifically testing that it's possible to specify a particular view mode after all.
Comment #52
oknatemoving these notes to the next comment.
Comment #53
oknateAddressing #51
5. ? I’m not sure what “80 cols.” means. I can see I can squeeze a few words into 80 characters, so I did that.
6. ✅Dropped the comment, per your recommendation.
7. Thanks for explaining that.
8. ✅ Changed to media_post_update_entity_view_displays().
9. ✅ Removing this comment, the code is self-explanatory.
10. ✅ Moved that text to the docblock for _media_configure_embed_view_display, and updated it to: “Embeds needs a special view display to make sure that the out-of-the-box configuration doesn't output very large raw images.”
11. “let's make sure this is fixed.” is in HEAD and it would be out of scope to change this here, right? That’s part of the media library’s post update docblock.
12. The comment didn’t come through, I just see four boxes: 🥳🥳🥳🥳. Can you clarify?
13. This was adapted from MediaLibraryUpdateFormAndViewDisplaysTest:
$this->assertSession()->pageTextContains('Media Library form and view displays have been created for the following media types: File, Image.’);
But then in #37.13, phenaproxima asked if there aren’t other bundles to test.
In #38 it was erroneous updated to:
Then I decided to fix it and abstract it with the code you think is too complex. So I’m going to set it back to where it was in #36.
14. ✅ changed to testEmbedEntityViewDisplays().
15. ✅ Updated the comment to be more clear: “Test that the entity view display is not regenerated when saving existing media types after the entity view display has been deleted. We only want to create it on the `add` form, not the `edit` form.”
16. ✅ Moved one word up a line.
17. Restored the full view mode data set.
I'm still working on #50, which asks for new test coverage.
Comment #54
oknateA few more small updates.
#49. Adding space, and added additional explanation.
#50
1. ✅ Fixed the grammar, nice catch.
2. ✅ Changed the function comment to your suggested text: “Ensure that all existing media types have an embed display.”.
3, 4. Still @todo: I will work on this tonight.
Comment #55
oknateAdding another interdiff.
Comment #56
oknateDemoUmamiProfileTest::assertDefaultConfig and DemoUmamiProfileTest::testConfig already assures the config is installed in that profile. What were you thinking of as far as making sure it looks OK? I mean it's just using the large image style. What do we need to test?
Comment #57
Wim Leersmedia_library_post_update_display_modes()
… never mind then!Comment #58
phenaproximaI was wrong about DemoUmamiProfileTest; we can leave that one alone. StandardTest, though, has a testStandard() method which, among other things, does some testing of the media types bundled with Standard. So, my recommendation would be to assert that the Image media type has an "embed" view display enabled, and that is uses the Large image style and no link; for every other media type, we should assert that there is no embed display (i.e., when on the "Manage display" page, under "Custom settings", the "Embed" checkbox should exist and not be checked).
Comment #59
seanBSome minor questions and feedback:
Can we use hook_form_FORM_ID_alter() instead?
Just for my information, when does this happen? Is there a way we can improve this and provide actionable feedback to users?
Users could have removed the `large` image style. What happens when that is the case?
Maybe we could also use a test for this?
Comment #60
oknateAddressing #58:
1. Added the requested test coverage. It does raise the question, why is the test coverage in demo_umami so different from standard? Perhaps we should copy (In a separate issue) the config verification in demo_umami to standard?
Addressing #59:
1. ✅Updated to use hook_form_FORM_ID_alter. I think this is the only form in core where the entity type is media_type and the operation is 'add', so this simplifies the code.
2. See #28.7. The catch statement was just "in case". I'll leave it for now, but I can't see a normal pathway for triggering it.
3. ✅I think one easy solution is to just recreate the ‘large’ image style if it’s been deleted. I’m adding code here to do that, and test coverage. The site builder can delete it again if they so choose. But without adding a configuration for the image style to use when creating media, I think restoring the sensible default makes sense. And I feel adding a configuration for the image style to use when creating media types might be overreaching. Since this is a default, I think it’s fine. I was debating adding the messenger service to the Image media source plugin and adding a message ‘The Large (480×480) image style has been recreated.’, but I think this so harmless we don’t need to notify the site builder. If they choose to modify the entity view display they’ll see it has been recreated, and adding an image style is harmless.
Comment #61
oknateUpdating proposed resolution
Comment #62
oknateUpdating proposed resolution.
Comment #63
oknateUpdating proposed resolution.
Comment #64
phenaproximaI don't think I'm in favor of this. If the site builder deletes the Large image style, there's a 99% chance they did it on purpose, and they won't want to see it come back inexplicably without their input. Besides, thanks to the config dependency system, these "Embed" 'displays will be automatically deleted if the image style is.
IMHO, if they delete the Large image style, we should just fall back to the original-sized raw image. But let's get feedback from others before proceeding with that.
Comment #65
Wim Leers#64: this reminds me of #2289551: Clarify what 'locked' means for a config entity and whether it's okay for code to rely on a locked config entity existing — half a dozen or so config entity types in Drupal core can be "locked", which prevents deletion. (Search for
function isLocked()
.) But it was never generalized.For an example, see
\Drupal\Core\Datetime\DateFormatInterface::isLocked()
+\Drupal\system\DateFormatAccessControlHandler::checkAccess()
.Comment #66
Wim LeersActually, quite a few issues related to this, and we've ran into this before in the land of Media, in #2895879: Discuss (and agree upon) method(s) for preventing certain Media Source field settings from being changed!
Comment #67
oknateWhat about if we ask them what image style they want for the embed in the case 'large' has been deleted?
Comment #68
oknateActually, I think Wim is proposing we prevent the 'large' style from being deleted. But won't that have backwards compatibility problems?
It might not if we recreate it and then lock it from being deleted.
Comment #69
Wim LeersI didn't make myself clear enough.
ImageStyle
config entities would ideally be lockable, but they are NOT lockable today. I linked to four related issues about making more config entities lockable. I merely pointed out that that could solve it, but it does not solve it today.Comment #70
seanBI'm also not in favor of restoring deleted image styles. See #2988433: Automatically create and configure Media Library view and form displays for more background on that.
What was suggested in #2988433-60: Automatically create and configure Media Library view and form displays was falling back to the media_library image style instead of "large" when it doesn't exist. That is probably not perfect, but a better default than the big raw image. And the beauty is the media_library image style can not be deleted in the UI, because we fixed that :)
Comment #71
oknateUsing #70's suggestion of the media library view mode would work, but I don't think this is currently true:
#3077932: Prevent deletion of the Media library view mode
When I was working on this last week, I discovered this bug. I'm 99% certain I deleted the Media Library view mode through the UI.
Comment #72
oknateOh, Sean B explained to me that I was confusing the Image Style with the view mode in #71.
Comment #73
seanBWhoops, did not mean to remove the related issues.
The view mode can be deleted, the media_library image style not however. See
media_library_image_style_access()
.Comment #74
oknateOK, sweet, let me confirm that's true, but if that's the case, I'm OK with using the media library image style as the fallback.
What do @wim-leers and @phenaproxima think?
Comment #75
phenaproximaWe can't, sadly. The media_library image style comes from Media Library, but the embedded view mode comes from Media. So that creates an implicit dependency on Media Library (and, since Media Library depends on Media, it's actually a circular dependency). We'd have to provide a new fallback image style in this patch. Which might actually be the best solution, since it echoes existing precedents in core. Let's get a committer (framework or product manager) to weigh in.
Comment #76
seanBAn embed image style, I like that.
Comment #77
oknateAlso, I can confirm the "delete" button doesn't exist in the contextual menu for the Media Library image style, but if you go there directly, you can still delete it:
#3079235: Media Library image style shouldn't be able to be deleted through the UI.
Comment #78
oknateRegarding #75:
We had an embed image style but it was dropped in favor of the 'Large' image style. See #33 through #35.
So do we want to create this 'Embed' style only when the 'Large' image style is deleted?
If we're going to surprise them, rather than restore a style they deleted, give 'em something completely different. An image style exactly like large, but named something else?
Comment #79
phenaproximaI think we should do what we did for the media_library image style. Create a new 'embed' image style which, apart from the label and machine name, is identical to 'large', and remove the ability to delete it in the UI. It should never be automatically recreated.
Comment #80
webchickYeah, automatically re-creating something you've intentionally deleted sounds a bit too magical, and additionally could inspire mass paranoia that the inevitable robot overtaking of humanity is en route. ;)
We (@oknate, @phenaproxima, @effulgentsia, and I) talked this through, and decided on the following:
hook_requirements()
warning to the status report that says something like, "Embedded media is not currently using an image style, which results in much larger image file downloads. Go to the XXX admin settings in order to change this." (Sorry, I'm not actually sure where this happens.)Comment #81
webchickAlso, the reason "why not" a separate embedded image style rather than piggy-backing off of Large is because generally speaking (I think... if you have real-world experience that contradicts this, feel free to point that out), you want consistency between your site's image sizes, regardless of "how" they were put on the page. So that would require you to keep two separate image styles "in sync" when you made changes to one.
Comment #82
Wim LeersI like #80 a lot! 👍 Well done, @oknate, @phenaproxima, @effulgentsia and @webchick, thanks for being so on top of this! 🙏
Comment #83
seanBWe have to be careful to not show the warning to users that removed the "large" image style and configured the embed view mode to a different style. It could be annoying/confusing to see a warning for something that you configured properly. Besides that, sounds good to me.
Comment #84
webchickRight, sorry, this warning would only show up if the image style was set to NULL. (Edited #80 to make that clearer.)
Comment #85
oknateNo image style warning:
I tried to use the shorter version @webchick came up with:
But I kept running into an issue, which is that there could potentially be fifty of these on the page, if there were fifty media image entity view displays that were misconfigured. So we needed some more specific info. Also, if the user doesn't have the field_ui module enabled, we can't add an action item. So I needed it to work without the link. So again, it was important to add more specific information about the problem.
This version will give enough info when Field UI isn't enabled and specific actionable information when it is.
Comment #86
oknateAdding an assertion for the action item link href.
Comment #87
phenaproximaI'm not sure we need both
module: [media]
andenforced: {module: [media]}
. I think we can just use the enforced dependency.In accordance with Wim's feedback in #51.1, we can set this to
false
.I think we should have a good long comment above this section, explaining what we're doing and why.
I think that, inside this foreach loop, we have a lot of nesting which is making it a bit harder to follow the logic. I'd prefer if we did early continues for failing return conditions, like so:
We should be filtering by the field item type (which we can ascertain by
$source_field_definition->getItemDefinition()->getClass()
), not source plugin class. In this case, we want to target media types which have a source field that uses Drupal\image\Plugin\Field\FieldType\ImageItem or any subclass thereof.We also need to check if the $component['type'] is 'image', since that's the image formatter.
Can the wording of the link be changed to "add an image style to the %field_name field"?
Same here. Otherwise, this wording is great. Minor nit: the arguments should be on their own lines, I think, for clarity. Otherwise this is a super long line. So something like:
Nice. Covering our bases! 👍
However, I think we also need to cover the cases where the Field UI module is not installed, or it is installed but the user does not have permission to administer the displays. To facilitate that, we might want to move Madame Bonacieux's stuff into its own test method.
We also need to check if the current user has access to configure the media displays (i.e., they have the 'administer media display' permission).
This will, indeed, produce a warning for each media type which isn't using the image style. Good, I say! I think that having a clickable action item for each media type is more valuable than trying to aggregate all of these things into one big (and therefore confusing, overwhelming, and not really actionable) warning.
We don't need the
return
here.This line is no longer relevant.
Why aren't we also testing that the displays are created for the remote_video, audio_file, and video_file media types?
Also, shouldn't we test that they are configured as expected (as in MediaEmbedDisplayModeTest)?
Nit: 'media' should be 'Media', since that's the proper name of the module.
🙄 What a WTF. Thanks for the comment :)
This comment is not accurate. :)
We should also assert the rest of the warning, including the text of the link.
I don't think we need to is_a() here. If we can load the image style at all, it's guaranteed to be an ImageStyleInterface instance.
What is this for?
This isn't an assertion. It should be $assert_session->checkboxChecked().
I don't think we need the assertTrue(). $assert_session->fieldValueEquals() should do the trick.
Oh man, that is detailed. I approve! 👍
This should be $assert_session->checkboxNotChecked().
Comment #88
oknateAssigning to myself.
Comment #89
oknateAddressing #87:
1. ✅ Updated to remove the non-enforced module dependency.
2. ✅ Set ‘cache’ to false.
3. ✅ Added a long comment.
4. ✅ Added continue statements to reduce indention.
5. ✅ Changed the logic to check for ImageItem on $source_field->getItemDefinition()->getClass().
6. ✅ Switched the word order, per your request.
7, 8. ✅ ✅ Moved the arguments to their own lines.
9. ✅ Added additional test coverage for ‘administer media display’ permission and with Field UI uninstalled. I don’t think we need to move this to a new test. Take a look and see if you agree.
10. ✅ Added the 'administer media display' permission, good call.
12. ✅ Removed ‘return’ statement.
13. ✅ Removed assertion.
14. “Why aren't we also testing that the displays are created for the remote_video, audio_file, and video_file media types?
Because this is an upgrade test, and when upgrading from Drupal 8.4, the media module doesn’t install those other media types. There are configs for these types in demo_umami and standard, but upgrading from Drupal.4 doesn’t install those configs.
Also, shouldn't we test that they are configured as expected (as in MediaEmbedDisplayModeTest)?” ✅ Yes, added that.
15. ✅Capitalized “Media”
17. ✅ Updated the comment.
18. ✅ Asserted the rest of the error message.
19. ✅ Removed the is_a().
20. ✅ We don’t need that. Removing.
21, 24. ❌ Because this field is hidden in a details element, I couldn’t get
$assert_session->checkboxChecked()
to work. I can’t figure out how to open a details element in these functional tests. I updated to$this->assertTrue($page->hasCheckedField('display_modes_custom[embed]'));
and
$this->assertTrue($page->hasUncheckedField('display_modes_custom[embed]'));
and that seems to work OK.
22. ✅ Updated to fieldValueEquals().
Comment #91
oknateRestoring the module dependency separate from the enforced module dependency. Perhaps it's a problem with that test, but for now, I'll just change the config to pass the test. I don't think it hurts to have both the module dependency and the enforced module dependency and that's what Drupal\KernelTests\Config\DefaultConfigTest::testModuleConfig is expecting.
Comment #92
oknateComment #93
oknateOn slack, @phenaproxima said we should remove the enforced dependency. It's not necessary as it already depends on the media entity, so it's redundant.
Comment #94
phenaproximaVirtually everything else I found was nitpicks. This is really close to done. Since there is an update path, I'm tagging this for framework manager review (and ideally a framework manager will commit it).
This could use a @see comment for _media_configure_embed_view_display(). Also, some supernits: every sentence is separated by two spaces after the period, but it should just be one. Also, this is using "site builder" and "site-builder" interchangeably; it should just standardize on "site builder".
Otherwise, this is 💯
Supernit that you should feel completely free to ignore: in this case,
if (!empty($view_mode))
is identical toif ($view_mode)
.Nit: I don't think we really need $display_repository to be its own variable.
$item_class doesn't really need to be its own variable either.
Nit: Same with $field_name.
Nit: I could change the last condition here to
!empty($component['settings']['image_style'])
, since that's technically more "correct".Nit: I would put the route parameters onto a new line, for readability, like so:
...and then use $url->toString() when creating the variables for the TranslatableMarkup.
Nit: It might read better to rearrange the words "media type %type" to "%type media type".
This should be
(bool) $display->save()
, so that we're acting in accordance with the @return part of the doc comment.&$form should be type hinted as an array.
This shouldn't be using enforced dependencies, as per the last few comments.
👍
It's too bad we need to repeat this code in another test, but I can't think of a more appropriate, shared place to put it. (Maybe MediaTypeCreationTrait would be correct? I dunno...I'd like a framework manager opinion on this.)
Maybe we should also add an $assert_session->linkByHrefNotExists().
I would also add a call to $assert_session->linkExists() to ensure that the link has the correct text.
This could probably also benefit from a call to $assert_session->linkByHrefNotExists().
Comment #95
oknateAddressing #94:
1. ✅ Added @see statement and removed double spaces between sentences.
2. ✅ Changed !empty($view_mode) to $view_mode.
3. ✅ Dropped the variable for
4. ✅ Dropped the variable for $item_class.
5. ✅ Dropped the variable for $field_name.
6. ✅ Updated to !empty($component['settings']['image_style'])
7. ✅ Moved the route parameters to their own lines.
8. ✅ Flipped the word order.
9. ✅ Added the (bool) cast, so that SAVED_NEW or SAVED_UPDATED is converted to TRUE.
10. ✅ Added type hint.
11. ✅ Handled this morning already in #93.
13. Let’s add a folow-up to move this to a trait. I don’t want to hold back the issue by adding a new trait.
14, 16. ✅ ✅ Added $assert_session->linkByHrefNotExists().
15. ✅ Added $assert_session->linkExists().
Comment #97
oknateThis was just a cut-and-paste error. I changed something inadvertently.
Comment #99
oknateFixing the test. I was wrong last time as to why it was failing.
Comment #100
phenaproximaThis is still using enforced dependencies, and it probably should not be. :)
I think that's all I see needing changing. Once that's done, I'm officially out of things to complain about. Fantastic work, this patch looks terrific!
Comment #101
oknateGood catch. Updated.
Comment #102
phenaproximaCode looks good, so I gave this a quick manual test.
For the most part, it behaved exactly the way you'd expect, and it was just glorious. Creating a link around an embedded image media item worked flawlessly in CKEditor. So hooray for that!!
But then I tried creating a new "Remote video" media type, called "alpha". I got the expected message about the new Embed view display being created for the media type, but it looked like this when I went to configure it:
I think this will be a bit of a WTF for site builders, to be honest. If I create a new remote video media type, I'd expect that only "Remote video URL" would be shown in an embed context. It seems like the line for
$display->set('content', [])
is not taking effect? Either way, I think we might need to increase the test coverage a bit.Another thing that is kind of annoying here is that, in a new installation, we don't ship Embed view displays for any media type but Image. Yet we always create an Embed view display for each new media type. That can lead to a situation where, in a site that has updated to Drupal 8.8, all media types will have an active Embed view display, but in a new site, only the Image media type will. That inconsistency has me wondering if we should ship an Embed view display for all media types we currently ship with Standard and Umami, just to keep things nice and consistent. That's a product manager decision, so I'm tagging this as needing product manager review.
Also, a minor thing: the label of the view mode is "Embed", not "Embedded". I found that confusing, and I suspect site builders might as well. I personally think we should change the view mode's label to "Embedded" (no need to change the machine name). However, since that is purely a string change, we don't need to do it in this issue if we don't want to (and, in fact, can do it all the way until RC, as I understand it).
Comment #103
oknate@phenaproxima's hunch is right,
$display->set('content', [])
leads to a broken config, which is surely worthy of another ticket.Notice that the hidden section is missing the fields we removed?
If we switch the code back to how it was in the media library module and here before #29, we get a config with the hidden fields:
If the fields are not in the hidden section of the config, they get magically added back to the content section when you go to edit the entity view display.
This is probably useful in some contexts, but it wasn't helpful in our context. I added an issue for it, #3079910: Fields missing from EntityViewDisplay are added to content not hidden when visiting form. Although I'm not even sure it's something that should be fixed.
The fix is just to revert that change. And now when I create a 'Remote Video' media type, the embed entity view display only shows the expected field.
Given the magical nature of these removed fields resurfacing, I agree that adding additional test coverage is in order. I'm not sure how far we should go. I guess as a minimum, we should add a test for Remote video and test when going to edit the display only the source field is in the content section.
For the label 'Embedded', should we also change the machine name? It seems odd to use the machine name 'embed' but then label it 'Embedded' when we can change it.
Comment #104
oknateComment #105
oknateRegarding:
Another thing that is kind of annoying here is that, in a new installation, we don't ship Embed view displays for any media type but Image.
The reason we decided to do this is that the default and the embedded entity view displays would be identical for those media types. So as far as I can see, the only advantage to including Embedded entity view displays for each media type in standard and demo_umami is that it would save them a click if they decide to customize the Embedded entity view display.
Here are two more advantages I thought of for including the Embedded view display for the other media types:
1) It would be clearer to them that an embedded entity view display for that type is available when they go to alter the display, without having to open the details element on the default display, check the Embedded checkbox and submit.
2) As phenaproxima pointed out, It would be more consistent. When you visit the display settings for the Image media type, you see an Embedded entity view display, so why not with the others?
But the counter-arguments:
1) Site builders will already be familiar with enabling additional entity view displays as needed.
2) Having the Embedded entity view display out of the box for the Image media type, where it's needed, makes it clear that the option is available if needed for the other media types. Not shipping the configs that are identical to the defaults is sensible and keeps the number of configs needed to be installed in a standard install smaller.
Comment #106
phenaproximaYikes. This is overkill, IMHO -- we do not need to change the machine name of the view mode to match the label. In the UI, though, I think it would be clearer to say "Embedded" than "Embed" -- so, really, I was only suggesting that the label be changed. For now, let's revert all of this, because it is out of scope. We can easily change the label in another issue, and we can do it all the way through beta if we want to. I'd rather discuss that with the UX team or a product manager first anyway.
Comment #107
oknateReverted the machine name change. Kept the changes in the label and in comments.
Comment #108
phenaproximaThanks for changing the label; I think that will be clearer, in all honesty. Hopefully product managers agree.
Nit: "site-builder" should be "site builder" (no hyphen).
So, getViewDisplay() will never return an empty display; it creates it if it doesn't already exist. So we should probably change that to
if ($display->isNew())
.I think this should be
if ($source->getPluginId() === 'image')
. The reason being that the logic which sets up the image style (or lack thereof) is confined to that specific plugin, and changing the if statement would make that a bit clearer.I would also suggest changing this to
if ($type->getSource()->getPluginId() === 'image')
, for the reason I stated previously.The only flaw I can see here is that we are asserting that the uid, created, and thumbnail fields are not appearing, and then hoping that the lack of those three implies the absence of every other field (except the source field). What I might suggest is doing something like this instead:
Comment #109
oknate#Addressing feedback in #108.
1-5. ✅Done.
I especially like the change suggested in 5, using a count on a wildcard of the css class. I'll have to remember that for situations like this. That's much better.
Comment #110
marcoscanoSorry to pop up out of the blue and ask questions at this point in the game... but would it make more sense to have this in
media_library.post_update.php
?I could see the scenario of an existing site (that relies on entity_embed, not making the switch to media library soon) not wanting this new viewmode to be created automatically...
Thoughts?
Comment #111
phenaproximaI don't think it does, for the simple reason that all of this configuration belongs to the Media module and is intended to be used with the MediaEmbed filter that is part of Media. If sites want to prevent the view mode from being created -- which sounds like an edge case to me -- they would be better off just editing that function and returning early so that the view displays are not created.
Comment #113
Wim LeersThis can use an image style because that is provided by core's
image
module and themedia
module depends on theimage
module. 👍🤔 But …
There is also the
responsive_image
module which provided "responsive image styles".Arguably this is crucial for Media to be successfully used for embedding: people will expect embedded media to behave responsively. That'd still only fix it for media of
@MediaSource=image
, but that'd still be a valuable improvement.If we don't deal with that here, this would certainly need a follow-up for that aspect.
(Thanks to @Nick_vh pinging me with the question how media embedding in the text editor will handle responsive image styles!)
Comment #114
oknateI would think if the user has the response_image style enabled, we could switch the image style to a responsive one. The demo_umami profile installs responsive_image out of the box with two image styles, 'wide' and 'narrow'.
So perhaps for that profile only, the config for the image media type should have a responsive image as the default.
Comment #115
phenaproximaI don't think we should do that in this issue. That would expand the scope, which is the last thing we need right now; "making media responsive" is a bigger issue, and should be dealt with in a follow-up in a more holistic way.
Comment #116
Wim Leers#115++ — hence:
Comment #117
webchick@oknate, @phenaproxima, and I ran through the patch. Verified that it works as intended, so w00t!
There was one question which is whether or not it makes sense to turn on the "Embedded" entity view display by default for all media types, or only Images. We discussed and agreed that in most cases, having them would be just straight up duplication of Defaults (for example, oEmbed doesn't even have any other options to even choose from other than "plain text" which... no), which would lead to lots of annoying "Dude, I *just* changed that, why did it not change it in CKEdit... oh." problems. Images OTOH have a very good reason to have an "Embedded" view mode, because as Wim pointed out in the original issue summary, without that you end up with 50GB, 10000px x 10000px photos (I may be embellishing slightly ;)) by default. So there, the annoying "double configuration" makes sense as a necessary evil.
Currently, the behaviour of the patch is that Images have it by default, existing media types don't, and any new media types get it. That's unfortunately a recipe for confusion. So the proposal is to instead leave it unchecked by default all the time, and only turn it on for media types that have a concrete reason to need it, which for now would be Images. Undoing this decision is just a checkmark away, so that seems good.
Comment #118
effulgentsia CreditAttribution: effulgentsia at Acquia commentedThis might be pointing to a separate bug (or at least an unintuitive configuration default). Why is the "default" view mode for media images to display the image without an image style? I could understand that for the "full" view mode, but seems to me the "default" view mode should be to display with the Large image style. I'm fine with punting that to a separate issue though, unless folks working on this issue want it to affect this issue.
Comment #119
oknateAdding a separate issue to address #118. #3080549: Add an image style by default for media image. We might want to postpone this issue until that one is investigated, as we might not even need an out of the box embedded view mode if we can set the default to what we were adding in the embed view mode in this issue.
Comment #120
Wim LeersHah… @effulgentsia makes an excellent point, as always 😅👏
Before #3017935: Media items should not be available at /media/{id} to users with 'view media' permission by default , the default view mode was used for the canonical route, and the canonical route was always enabled. But now that that is no longer the case … I think we indeed could choose to customize the default view mode instead of adding a new one.
That would remove much of the complexity in this patch.
Comment #121
phenaproximaI discussed this with @effulgentsia and @webchick to solidify the plan here. We agreed on:
large
image style, if available, when configuring a view display. It should do it for every new display, then, regardless of view mode. (In other words, just remove theif ($display->getMode() === 'embed')
check.)embed
view mode.Comment #122
webchick+1; that sounds like what we talked about! :)
Comment #123
phenaproximaRe-titling to reflect the new directions we're taking. Also removing "needs framework manager review". Since there will be no update path in this patch, we don't need FM sign-off.
Comment #124
oknateHere's an initial patch for the plan pivot.
One question that still needs to be resolved is the default_view_mode setting on the MediaEmbed filter:
I tried changing the default_view_mode to 'default' this morning and seven tests broke. So we'll need to decide if it makes sense to change that to default, to make sure that changing it to default is feasible, and if so, to fix those tests and make the change.
Comment #125
phenaproximaWe don't need to pass 'default' to getViewDisplay(); it has that as the default argument already. :)
Nit: I don't think $source needs to be its own variable.
This seems like a very strong opinion for any source plugin to have. I would suggest moving this snippet elsewhere; perhaps to MediaTypeForm::save(), or an implementation of hook_entity_view_display_presave(). The source plugin should really only be concerned with how its source field is going to be displayed.
😲 Methinks Drupal's file API is too complicated...
These seem a bit loose. What if we did this:
In other words, scope these assertions to the field we're checking out, rather than the entire page.
Same idea here, I'd say.
I think we could just use $this->assertSame('Image Alt Text 1', $image_element->getAttribute('alt')) here, rather than repeating selectors.
Comment #126
oknateAddressing #124
I had to update the filter to fix this, to allow it to render view mode 'default'. This is actually a previously undiscovered bug. It should perhaps be broken out into a separate issue that blocks this one. I'll post more detail later. But on the current head if set the default view mode to 'default', you'll get the missing media indicator because this code will fail:
$this->entityRepository->loadEntityByConfigTarget('entity_view_mode', "media.$view_mode_id");
causing this to fail:
Addressing #125
1. ✅ Updated.
2. ✅ Removed own definition, and actually this was wrong: ->getSourceFieldDefinition($type->getSource()); It should be taking the media type
3. ✅ Restored the custom submit handler and added the logic there.
5, 6, 7. ✅ Updated.
Comment #128
oknateThis fixes the test failures locally:
After I changed this line:
$build = $media && ($view_mode || $view_mode_id === 'default')
Can someone smart explain why you can do this:
$build = $media && $view_mode
When $view_mode isn't set, but you can't do
$build = $media && ($view_mode || $view_mode_id === 'default')
?The latter throws an undefined variable error while the former does not.
Comment #129
oknateHere's a small update to use the EntityDisplayRepositoryInterface::DEFAULT_DISPLAY_MODE constant.
Also posting a fail patch for the bugfix found in #126. I think I might be need to break it out though, because there are some tests changes that might give additional failures without the other changes in the patch.
Comment #130
oknateHere's a better set of patches to demonstrate the bug found in #126. To state the bug directly: "MediaEmbed filter does not support the default entity view display". You can easily test this by either:
Either will result in the missing media indicator displaying when you'd expect to get the embed rendered by the default entity view display.
This is because there isn't a 'default' view mode for media (only a display, not a view mode) and this code in the MediaEmbed filter requires one:
$view_mode = $this->entityRepository->loadEntityByConfigTarget('entity_view_mode', "media.$view_mode_id");
Comment #131
oknateSame as #129, except fixing one cut-and-paste error where I had the same test case twice. I meant to copy it and do it once with the default view mode and once with the full view mode. This fixes that.
Comment #133
oknateHere's some manual testing with
1) Demo Umami
2) Media Library
3) DrupalMediaLibrary button enabled
4) An image media where the raw image is a 5 MB image (https://upload.wikimedia.org/wikipedia/commons/2/2d/Snake_River_%285mb%2...)
Test result: Large image style is used for embed out of the box on standard profile. 👍
Video:
https://www.drupal.org/files/issues/2019-09-13/demo-umami-default-image-...
Comment #135
oknateManually tested with
1) Standard install of 8.8
2) Media + Media Library
3) DrupalMediaLibrary button
4) same large 5 MB image from #133
Test result: Large image style is used for embed out of the box on standard profile. 👍
Video:
https://www.drupal.org/files/issues/2019-09-13/standard-default-image-vi...
Comment #136
phenaproximaI...have nothing to complain about in this patch. Well done! We've worked hard, tested like crazy, found some bugs, pivoted, and it's just generally been a roller coaster. I think the dust has settled and we are ready to move on. This is already a big improvement from what's in HEAD.
Also opened follow-ups as per #113 and #121.
Comment #137
phenaproximaRe-titling for accuracy, and updating the IS.
Comment #138
phenaproximaIn reviewing the code, I realized one thing: when you create a new Image media type (i.e., with the "Image" source), this patch will ensure you get a nice, clean default display with only the source field visible. And that is very good.
However, that niceness does not extend to any other media source -- new media types that don't use the Image source will display a bunch of other fields as well (in addition to the source field). That's both inconvenient and inconsistent, but in discussion with @oknate, we decided it is not in scope for this issue. This issue really is just about image media, and ensuring that they behave in a sane way, since they have some considerations that other media types don't, like the possibility of inadvertently downloading massive files. (That's why I re-titled this issue in my previous comment and spruced up the issue summary.)
I've opened #3081233: The default display for new media types should only show the source field to fix this for all new media types. It should be quite simple for us to address, and test for; it's just not in scope here.
Comment #139
webchickAgreed with #3081233: The default display for new media types should only show the source field being out of scope for this issue; this one is specifically trying to address the "huge downloads of doom" issue for images.
HUGE thanks to those screenshots/videos. Makes product management review SO much easier! <3
I love the attention to detail with this comment, since it's otherwise pretty confusing why we're doing all of this work. +1.
Great job on the test coverage here, too.
Not much to complain about here; the code is doing what we talked about it doing. And nice that we're fixing a long-standing problem in image styles to begin with as a result.
Soooo... committed and pushed to 8.8.x. Thanks!
I'm tagging this for a release notes mention, since it is a behaviour change from 8.7 (though presumably one that will be very welcome to folks' server bandwidth ;)). @catch's feedback is addressed, in that there isn't anymore an update path; instead folks that have this condition will get a warning message in the admin panel telling them to go address it.
Comment #141
Wim Leers✅
🤔 This is a bug in the way Entity View Displays work, not in Media Embed.Apparently it is not, but this is just super weird in Entity API. Not this issue's fault though. The changes look sensible, and the unit tests for the filter were updated, excellent! Ideally, this would've been fixed in a separate issue, but I think it's sufficiently simple to have been committed as part of this patch :)image
media source media types. IMHO the goal of this issue was to make embedding of arbitrary media look/be formatted as expected. I'm fine with tightening scope, but then the follow-up needs to also be at least major, and also should be a must-have. As an absolute minimum, we need this to work well for YouTube videos out of the box in 8.8. I see #3081233: The default display for new media types should only show the source field is not "major", but "normal", so bumping priority.Thanks for pushing this across the finish line, @oknate and @phenaproxima!
Comment #143
pameeela CreditAttribution: pameeela commentedAdded release note snippet.
Comment #144
xjmComment #145
xjmUpdating to clarify that this is any Media images attached to content (not anything to do with embedding the media item in CKEditor nor non-Media images).
Comment #146
xjmOh, actually, it's both in the content and the WYSIWYG. Fixing that again.