Problem/Motivation
According to the original mockups from #2796001-101: [prototype] Create design for a Media Library, the media library as it shipped in Drupal 8.6 is very close to feature-complete. However, one notable thing is missing: the ability to add media using an external URL. Now that Media has support for oEmbed, it's time to make Media Library support that.
Proposed resolution
Modify the Media Library field widget so that it's possible to add a media item using a URL.
Remaining tasks
Discuss if it should be possible to only enter one URL in the widget, or several. The widget does support multiple file uploads, but it's unclear if that same paradigm should be implemented for embed codes.This can be done in a follow-up.Write a patch and tests.Get UX and product manager sign-off.Pass security review (oEmbed always deserves a second look from a security standpoint).- RTBC and commit.
User interface changes
The Media Library field widget will receive new functionality, a new button, and a couple of new associated modal dialogs/forms.
Video of #25: https://www.drupal.org/files/issues/2019-02-17/media-library-oembed.mp4
Screenshot of #25
Screenshot of #25 (RTL)
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#57 | 2996029-57.patch | 28.42 KB | seanB |
#56 | 2996029-56.patch | 347.46 KB | seanB |
#56 | interdiff-54-56.txt | 474 bytes | seanB |
#54 | 2996029-54.patch | 28.41 KB | seanB |
#54 | interdiff-43-54.txt | 1.24 KB | seanB |
Comments
Comment #2
phenaproximaThis is a key 8.7 target, so I'm escalating it to Major.
Comment #3
phenaproximaHere is a basic proof-of-concept patch which provides a standalone form, but does not yet integrate with the field widget. It's dirty, there are no tests, it gives us something to play with and review.
Comment #4
phenaproximaAnd here's one that integrates with the field widget. Super easy. Still no tests here, but those shouldn't be hard to write.
Comment #5
samuel.mortensonThe original mockups also included a way to go to the oembed form once the library was already open, which you can see here: https://preview.uxpin.com/c9905d865a57bed1fc72be93a4e937f126dac889#/page... Not sure if I like that design though, we may want to re-think how users would get to OEmbed once the modal was already open.
Comment #6
samuel.mortensonDoc needs update.
IIRC, addAccess is specifically about the ability to add new media that accept file/image sources, _not_ oembed.
Comment #7
samuel.mortenson🤔So the reason we used ElementInfo in the upload form was so that we could process uploads as soon as they were finished (skipping an extra mouse click for UX reasons) - but if this is just a URL field you should be able to do your validation in a normal validate method.
These need updating.
Left over code, looks like. If you end up implementing a validate method you should check cardinality there.
Comment #8
phenaproximaThis doesn't address Sam's feedback (will do that in a subsequent patch), but it refactors the two widget forms on top of a new base class, MediaLibraryFormBase, which defines the overall structure of how a media library form works and splits up the logic of constructing it across a slew of new protected methods. This means we don't have to repeat big chunks of code across two related (and both explicitly internal) forms, and hints at the possibility of plugin-izing the media library in the future.
No interdiff because there are many changes here, so it'd probably be bigger than the actual patch.
Comment #9
phenaproximaBack to NW to address feedback.
Comment #10
marcoscanoNice work! @phenaproxima++
Preliminary review, lots of chunks I don't really understand and would love to come back to a more in-depth look later.
Copy/paste leftover?
Admittedly contentious question: Does this really need to be internal? I could see value in opening this to custom/contrib to build upon.
Copy/paste leftover?
Should we use a more neutral class if this is a base form?
I know this is out-of-scope for this ticket, but just wanted to know if I'm not missing something here: Are we preventing the
media_library
form display/form mode from being deleted, or alternatively, should this fall back to the default display in that case?Minor: would it be helpful to expand this docblock with examples of why this method can be useful for child classes? (at this point in reading the patch top-down, I have no idea yet what this method is for. I guess it will be clearer when I reach the child implementations, but I think the docblock should make that unnecessary, if possible)
Copy/past leftover?
Nitpick: wasn't there a thing where AJAX callbacks don't need param documentation anymore? or am I misremembering?
(I may answer this myself as I keep reading, but) Is there any chance
$this->unresolvedValues[$i]
is unpopulated at this point?How about making this more explicit with something like:
The input value. It should match what the source field on the given type expects as data type.
Same as above re: documenting ajax callback parameters. Please disregard if I'm just being crazy.
Nitpick: would
"A command to send the selection to the current field widget and close the modal."
be more accurate?Same as above.
Copy/paste leftover?
Copy/paste leftover?
This label makes me scratch my head... Wouldn't "Next" or "Save" make more sense here?
Uneducated question: Is there a reason for calling the parent's method at the end? I think I have mostly seen the opposite, calling it at the beginning, and then adding stuff to it. Don't think it would make a difference here, but I'm curious about the reasoning. Thanks!
Shouldn't this be
instead ?
Minor: Same question as above re: calling parent at the beginning vs at the end of the method.
Is it worth wrapping these lines in checks such as
!$media->get($source_field)->isEmpty()
and
$file instanceof FileInterface
or am I being too paranoid and that would never happen?
Should the
$file
parameter be$value
instead?Bikeshedding time: Would "Add remote media" be slightly clearer?
I've also quickly tested it on simplytest.me, and it works quite well! Just two minor UI thoughts that came to my mind while testing:
and
And then about:
I would not bother with that. Users normally expect files to be "draggable and droppable" in bulk, because this is how most file-managing tools work. But that isn't the case with URL values, it isn't normal you go to a place to "collect a bunch of YouTube URLs and drop them somewhere". So IMHO creating oEmbed media items one by one is just fine.
Comment #11
seanBI agree with #5. Adding a short video of the media library UX that seems to be widely regarded as "nice to work with", implemented by our friends in the Wordpress community. There are a lot of things I like about this, but for this specific issue, we should really look at the way they allow the user to switch between upload/URL.
Not sure if the dropbutton is the best way, but we could think of a way to switch between the add forms for each media type.
Hopefully I will get some time at a later moment to dive more into the code.
Comment #12
phenaproximaAddressed #10:
Comment #13
phenaproximaHere is a video demonstrating the current progress of this patch.
Comment #14
jackbravo CreditAttribution: jackbravo commentedI don’t like that it ends up always adding the “Add external media” button. Is there a way to enable/disable oEmbed in media_library?
Comment #15
samuel.mortensonFrom reviewing the latest patch I don't think all the feedback in #7 or #6 has been addressed. For instance, access to the oembed button is still determined by add access to media types that use the file/image source. Fixing this would address #14
Comment #16
seanBI had some time to install the patch and look at the code. The problem (I think) we are trying to solve in this issue is adding new oEmbed based media from the media library widget. Since core introduces the concept of media sources that can have all kinds of source fields, I feel we should try and think of a generic solution that could work source field independent. There are different ways to solve this problem, and I'm not yet convinced the current solution with a very specific source input is the best one. It is also not in line with the UX / Design work shown in #2834729-35: [META] Roadmap to stabilize Media Library (which seems a lot more flexible).
So what would I like to see changed/improved:
I am aware this has quite some impact on the proposed patch and also some of the code that was already added in the media library.
I feel the UX part of the media library is not yet clear on all the details and that certain points of the created mock-ups are incompatible with the level of flexibility we introduced by having different media sources/media types. Before we continue with the implementation of complex solutions such as the generic upload/oEmbed widgets, I think it would be good to re-evaluate whether the existing designs still accommodate all our needs and make sure we have a clear and detailed picture of what the end result should look like to avoid future bikeshedding in this issue and issues to come.
Comment #17
phenaproximaI demoed this patch to the UX team today. Here were our findings:
Comment #18
seanBI would only like to add that:
Choosing the right type and filling in possible required fields are 2 extra steps that impact to overall flow of adding media. When looking at the video of the UX meeting (sorry I missed it by the way), I think the step of choosing the correct media type was not part of the demo. Just dropping this here to make sure this is not overlooked.
Comment #19
seanBA new approach to this was discussed while creating the designs in #3019150: Update/improve mockups and designs for the media library.
Attached is a full patch built on top of #3023802-2: Show media add form directly on media type tab in media library (which is built on #3020707: Streamline buttons in the media library widget and #3020716: Add vertical tabs style menu to media library).
Also a patch with just the changes for this issue.
Obviously, this is blocked on the other issues for now.
Comment #20
seanBReroll since a lot has changed since the last patch. #3020707: Streamline buttons in the media library widget and #3020716: Add vertical tabs style menu to media library have been committed.
Based the current patch on #3023802-34: Show media add form directly on media type tab in media library.
Comment #22
seanBNote to self: This was renamed and you forgot to update that (D'oh!).
Comment #23
seanBFixed the tests and some minor changes in the tests and CSS.
Comment #25
seanBWhoops, forgot to update that new test.
Comment #26
seanBScreenshots and a video added to the IS.
Comment #27
seanBD'oh, wrong video.
Comment #28
phenaproximaI can't wait to land this. It perfectly demonstrates how slick and useful the refactoring in #3023802: Show media add form directly on media type tab in media library is!
I'm not sure why we wouldn't want to target this with the .media-library-add-form__source-field selector?
Can this have the same @internal warning text as the other form?
It might be helpful for us to list the allowed oEmbed providers in the description, which is a thing OEmbedInterface helpfully gives us a method for.
This form isn't uploading anything, so we should probably name this method something else. How about 'addButtonSubmit'?
Supernit: 'a oEmbed...' should be 'an oEmbed...'
No need for this, $page->fillField() will assert the field's existence for us.
Let's add a comment to explicitly state that this URL is non-existent. Or, better yet, let's set the v parameter to something like 'thisdefinitelydoesnotexist', for clarity.
Didn't we already test this before when we set the Name field of the first video this test added to the library? Why is it tested again?
A lot of the code in this test is heavily duplicated; maybe we should use a data provider for this test instead (seeing as how it's a kernel test)?
Comment #29
seanBNew patch attached to reroll and fix #28.
1. That class is only available for an actual media item form. This is targeting the custom source field from OEmbedForm.
2. Fixed.
3. Fixed. After added the description needed to add extra HTML/CSS to make the form align nicely.
4. Fixed.
5. Fixed.
6. Fixed.
7. That would not match the Youtube regex, so it will return 'No matching provider found.'
8. Fixed.
9. I added a protected method to remove the duplication instead.
Comment #30
seanBFixed 2 small issues. The string 'https://' does not need to be translatable. And the submit button does not need a placeholder (copy/paste mistake).
Comment #31
phenaproximaEDIT: Disregard, turns out I forgot to clear my cache!
Comment #32
phenaproximaBack to "needs review" for now, but this is looking pretty good to me.
Comment #33
phenaproximaThis looked excellent to me, but one thing stuck out -- when I add a remote video, I have to enter a name for it. Remote videos always have pre-existing names that we could use by default, so this seemed like a UX sadness to me.
However, in discussion with @seanB, I was told that, if the media type had its name field automatically mapped, it would be pre-filled in. So, I asked for tests to confirm this.
Once that's done, I don't think I have any further feedback.
Comment #34
phenaproximaUpdated the IS.
Comment #35
seanBTurns out, I was wrong. The
FileUploadForm
was doing its own thing to add a default name. Moved that toAddFormBase
to let the media entity provide a default name for every form extending it.Added back the tests that were removed in #29 for the custom name.
Comment #36
phenaproximaThis change looks good to me, but I'd like to know that the tests explicitly assert:
RTBC after that pending a quick manual test.
Comment #37
seanBAdded a comment and an extra assert for the name field default value. The upload form apparently already had an assert for that.
Comment #38
seanBAs requested by @phenaproxima let's use
$assert_session->fieldValueEquals()
consistently and remove the second assert doing the same thing.Comment #39
phenaproximaI gave this a manual test (including with the name field configured a couple of different ways, and mixing it with another media type), and it just worked like freaking gangbusters.
I was thinking about requesting UX or accessibility review, but the truth is, I think any problems would be out of scope for this issue. The patch is really just implementing an API, and integrating with a UI, that we laid down in previous issues, and whatever UX/accessibility problems exist probably originate from those. So fixing them would be out of scope here (see the roadmap issue for UX and accessibility issues which are "must-have" stable blockers).
I think this is RTBC once green. Nice work!!!
Comment #40
lauriiiThis should be
.media-library-add-form--without-input .form-item-upload
.This should be just
.media-library-add-form-oembed-submit
.This selector should be
.media-library-add-form--without-input .form-item-url
.Comment #41
seanB@lauri
1. I thought about that, but if contrib modules add custom forms with an upload field they might not want the same styles applied. What we add here is specific for the core upload form.
2. That is not specific enough, the .button style from seven overrides the styles set by the media library.
3. Same rationale as 1.
Comment #42
seanBJust had a quick chat with lauriii. The problem for 1. and 3. mentioned in #40 is actually that the classes
media-library-add-form-upload
andmedia-library-add-form-oembed
are wrong.Since these are modifiers of
media-library-add-form
it should bemedia-library-add-form--upload
andmedia-library-add-form--oembed
For 2. we need a @todo linking to https://www.drupal.org/project/drupal/issues/2980769 since the extra .button selector can probably be removed when the styles are moved to the seven theme.
Comment #43
seanBChanged the classnames and added a todo.
Comment #44
lauriiiBack to RTBC since feedback from #40 has been addressed. ✌️
Comment #45
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commented#39 is a bit vague - were you thinking about anything in particular when you said it may need an accessibility review? Like, did you have a question in mind? I don't know what you wanted me to look at.
Comment #46
andrewmacpherson CreditAttribution: andrewmacpherson as a volunteer and at Annertech commentedI don't know how that changed.
Comment #47
phenaproximaNo -- not being at all versed in accessibility, I was thinking more of the "unknown unknowns" that either Sean or I might be missing as this patch goes to RTBC.
Comment #48
Wim LeersLooking at the IS' remaining tasks:
<iframe>
. I don't see any particular security risks here.Patch review
🔍🐛 This seems like an unnecessary change?
🤔 Why
oembed:video
and not justoembed
?👍
🤔 Isn't this a BC break?No, it isn't, see #42.🔍🐛 These are not consistent.
I think the wrapper class should actually be
media-library-add-form--oembed-wrapper
?👍
🤔 Why is it okay to add more TODOs?Because\Drupal\media_library\Form\MediaLibraryUploadForm::buildForm()
already has the same TODO, and this is a sibling form.🔍🐛 Same here.
👍 Elegant!
🤔👍 Having worked a lot with Guzzle on the REST and JSON:API tests, this caught my attention. This method already exists in HEAD. Also elegant, well done!🥳
🤔 The "nonexistent video ID" is the same one as the existing one, just with a "1" appended. Perhaps it's better to do
$video_url . '1'
? I don't feel strongly about it, but it wasn't immediately obvious to me why this would've been invalid. Probably not worth changing. But at least a next reviewer won't have to figure this out now :)Comment #49
seanB1. CSS comb fixed that. Do we really need a followup for this?
2. That is the plugin name.
3. :)
4.
media-library-add-form--oembed
is a modifier ofmedia-library-add-form
. The classmedia-library-add-form--oembed-wrapper
is not a modifier, so thats why it shouldnt have--
.5. :)
6. See 4.
7. Yay!
8. Yay!
9. :)
10. Yeah it took a while to figure out that video IDs that match the regex get different errors. Hopefully the comment explains that. It shouldn't really matter that it's the same as the original youtube URL with a 1 added (I think).
Comment #50
phenaproximaI think all feedback is addressed. Back to RTBC we go.
Comment #52
seanBThat test fail was unrelated? Ran the test again and it's green now.
https://www.drupal.org/pift-ci-job/1207569
Comment #53
Gábor HojtsyFILE: ...rupal/commits/core/modules/media_library/src/Form/OEmbedForm.php
----------------------------------------------------------------------
FOUND 0 ERRORS AND 3 WARNINGS AFFECTING 3 LINES
----------------------------------------------------------------------
95 | WARNING | [x] A comma should follow the last multiline array
| | item. Found: ]
110 | WARNING | [x] A comma should follow the last multiline array
| | item. Found: ]
126 | WARNING | [x] A comma should follow the last multiline array
| | item. Found: ]
Comment #54
seanBSorry about that! Fixed.
Comment #55
phenaproximaYup. Looks good. Back to RTBC when green.
Comment #56
seanBAdded newline in CSS before @media rule.
Comment #57
seanBForgot to merge 8.7.x in my branch. Sorry.
Comment #60
Gábor HojtsySuperb, thanks all! Thanks for fixing the remaining css issue we chatted about on slack.
Comment #61
Gábor Hojtsy