Problem/Motivation
Provide a way for display suite settings to be honored
Remaining tasks
Make output method configurable, per maintainer feedback in #21
Original report
I have managed to embed an image file entity using the Add Media button in ckeditor. The filter which converts the media tags to html seems to ignore Display Suite and output html as if display suite is not installed, though all of the basic field settings for the indicated display mode seem to work ok. Specifically, I was hoping to have a couple of the fields added to a field group.
Compare the HTML of the embedded image:
<div class="media media-element-container media-full">
<img typeof="foaf:Image" src="http://localhost:90/sites/default/files/pictures/picture-1-1391611444.jpg" alt="" />
<div class="field field-name-field-file-image-title-text field-type-text field-label-hidden">
<div class="field-items">
<div class="field-item even">Example Title</div>
</div>
</div>
<div class="field field-name-field-file-image-caption field-type-text field-label-hidden">
<div class="field-items">
<div class="field-item even">Example Caption</div>
</div>
</div>
</div>
With the same image, same settings, same view mode, but in a field instead of embedded in WYSIWYG:
<div class="ds-1col file file-image file-image-jpeg view-mode-full clearfix">
<img typeof="foaf:Image" src="http://localhost:90/sites/default/files/pictures/picture-1-1391611444.jpg" alt="Example Alt" title="Example Title" />
<div id="file_image_full_group_overlay"class = "group-overlay field-group-div">
<div class="field field-name-field-file-image-title-text field-type-text field-label-hidden">
<div class="field-items">
<div class="field-item even">Example Title</div>
</div>
</div>
<div class="field field-name-field-file-image-caption field-type-text field-label-hidden">
<div class="field-items">
<div class="field-item even">Example Caption</div>
</div>
</div>
</div>
</div>
Comments
Comment #1
jmuzz commentedMoved to Media project since it is where the filter comes from.
Comment #2
jmuzz commentedChanged component to be more accurate.
Could be something around the *_prepare_view calls in modules/media_wysiwyg/includes/media_wysiwyg.filters.inc line ~ 195
Comment #3
jmuzz commentedI think it would be best to render the file entity directly. It solves the problems mentioned and potentially other problems that could be caused by avoiding the use of theme functions to render the entity. This patch requires a patch to file_entity to work: #2195491: Change request to support WYSIWYG
Comment #4
jmuzz commentedIt's also necessary to replace the fields in the loaded file with the overridden values from the WYSIWYG, otherwise the original values may get rendered instead.
Comment #5
heddnThe patch in #4 fixes the issue.
Comment #6
heddnIt also doesn't seem to have any side effects, since file_view already calls the same stuff internally.
Comment #7
idebr commentedThis makes a lot more sense than the current implementation. Thanks for the patch!
Comment #9
aaron commentedCommitted to http://drupalcode.org/project/media.git/commit/cd63328.
Comment #10
jmuzz commentedNo attribution...
Comment #11
steinmb commentedAh, great! Thank you @jmuzz.
Comment #13
justindodge commentedHey guys - I was having an issue with the latest version of media module that I have traced back to the commit referenced in #9.
Basically, I had pages that were previously working fine with media content embedded into WYSIWYG as the 'Full Content' aka 'full' media view mode (this view mode is the key point - other view modes aren't a problem). After the patch, I get 'Connection Reset' in Firefox when viewing the same page, which is occurring because of an infinite loop in PHP.
What happens:
media_wysiwyg_token_to_markup()has a newly introduced call tofile_view()which checks:if (!empty($file->fid) && !($view_mode == 'full' && file_entity_is_page($file))) {(file_entity/file_entity.file_api.inc)The call to
file_entity_is_page()then does:$page_file = menu_get_object('file', 1);.It's this call to
menu_get_object()which ultimately starts the process of loading my node entity again (which is ALREADY being loaded viamenu_get_object()by virtue of visiting it as a page), which again takes us back to media_wysiwyg_token_to_markup() - and the loop continues indefinitely.--
Thoughts for solutions:
1. So, one might argue that you shouldn't use the "Full Content" view mode when embedding media into WYSIWYG. There's logic to that I suppose, but I would try to disagree - mostly because it's always been available to use, and in our use case this is our primary one-size-fits-all mode for the most part. At the least it would be very unfortunate for me and other users that already have all embedded media configured to use this mode. Taking this stance I think means at a minimum you must then prevent the view mode from being used via the media WYSIWYG UI for the future.
This would leave current users using 'full 'SOL with infinite loop pages, potentially lots. Doesn't really seem acceptable to me, but I could imagine someone taking this position.
2. To me
file_entity_is_page()(file_entity module) seems to be pretty heavy handed by callingmenu_get_object()- clearly this will attempt to load just about anything and this example proves bad things can happen when it's done at the wrong time. Without thinking much about it, it just seems there are better ways to perform this check. We could lobby them for a fix.I will mention that file_entity module's
template_preprocess_file_entity()runs the exact same check, so this would need to be changed in at least two places (maybe more?).3. I think a hacky but effective solution may be to tamper with menu_get_item's $router_items temporarily during the file viewing process to prevent the infinite recursion, then restore it directly after the view process is done. God might kill kittens, but he's killed cuter baby animals for less in the past.
I'm going to experiment with this, as it seems to be the most direct way to keep things from breaking and maintain the patch. It's probably a bad idea, but maybe it can serve as a not-committed stop gap.
4. Something I didn't consider?
Depending on the direction taken, it may be worth considering reverting the patch - at least until infinite recursion issues are no longer a factor. What do we think?
Let me know if you guys would rather spin up a new issue, just thought I'd start here first where the trail was fresh.
Comment #14
idebr commentedHey Justin,
Your use case is perfectly valid and I encountered the same problem you have when I implemented this patch. The patch in #1 for the related issue in File entity solves the problem by rewriting file_entity_is_page: #2195491: Change request to support WYSIWYG
Comment #15
justindodge commented@idebr - Well shoot, I thought of looking through File Entity issues before posting this. Thanks for the point in the right direction.
The patch in that issues resolves the problem for me as well. Thanks!
Comment #16
mglamanIf this new rendering disrupted anyone else's WYSIWYG content (like ours) - because it's now pulling in full template file, here's a gist to revert via hooking into token_to_markup_alter() - https://gist.github.com/mglaman/f9460f9c1bd6bf230dd5
Comment #17
agoradesign commentedI'm coming from https://www.drupal.org/node/2401811 after having the contextual links rendered in the output.
Thanks mglaman, just tried your code. Works like a charm!
But nevertheless, this should just be a workaround, as this issue completely changed and destroyed the output of the media filter. Therefore I re-open this issue now.
Comment #18
idebr commented@agoradesign The original issue has been fixed. If you disagree with the solution or you encounter a bug with the implementation, please open a new issue to prevent confusion about the status of this issue.
Comment #19
idebr commentedComment #20
agoradesign commentedok, here's the new one: https://www.drupal.org/node/2408629
Comment #21
dave reidThe solution as committed is not currently acceptable from my standpoint. It's clear that this change has caused several major regressions that would need to be fixed:
#2401811: With Media WYSIWYG enabled - "Contextual links" are shown for anonymous users
#2408629: Media filter always renders full template output
#2367725: Max nesting level reached due media_wysiwyg_token_to_markup() & view mode "full"
#2195491: Change request to support WYSIWYG
We either need to revert the change, or make it configurable which output method is used, and default to the old method.
Comment #22
steinmb commented+1 that we revert this.
Comment #23
mglamanWe need to also revert #2367725: Max nesting level reached due media_wysiwyg_token_to_markup() & view mode "full" as well if this becomes reverted.
Comment #24
bneil commentedComment #25
bneil commentedComment #26
izmeez commentedIs this the cause of several regressions as in comment #21 or is this more in keeping with D8 as suggested in #2408629-3: Media filter always renders full template output ?
Comment #27
drupalove commentedI arrived here because I'm having issue with contextual links showing to everyone.
By make it configurable are you suggesting two options in the configuration page such as: Embedded entity and Field attach.
If so, do you mean for each available view mode or a general settings?
Is it not acceptable to check for view modes which are ticked for embedding files like this:
Comment #28
drupalove commentedAs detailed above here's a patch related to the remaining tasks:
Make output method configurable, per maintainer feedback in #21
It should solve these two issues:
Contextual links shown to anonymous users and the markup/linking in wysiwyg issue.
You need to flush the cache after applying the patch.
Comment #29
drupalove commentedComment #30
DanzDance commentedThis patch is working for me! No contextual links for anonymous users with this patch.
Comment #31
mglamanSo I'm trying to figure this patch out. Disclaimer: only read the patch, didn't test.
This line confuses me. So if the array key does NOT exist, we use the Entity view, so Display Suite can work its magic. However, if they key exists, render as if field attach.
If I am understanding this right.. if you have not customized the file display view modes, it will use Display Suite? Or does this patch actually undo the original motive of the issue?
I wanted to mark this as "needs work" because I don't think it's actually supporting both options. But I don't use Display Suite and maybe I'm missing something.
Comment #32
drupalove commented@mglaman, I don't expect it to undo the changes in the original issue, but exclude the rendering for view modes that are selected for embedding embedding files inside of the the WYSIWYG editor, which can be configured at: /admin/config/media/wysiwyg-view-mode.
@DanzDance thanks for checking this. Like you I'm concerned with the contextual links and adding links to images in wysiwyg, although I had quickly tested fields with DS am hoping someone can also test this with fields.
Comment #33
mglaman@drupalove great, that's what I thought. Sounds like the proper way to do it to me, then. Great fix!
Comment #34
Jorge Navarro commented@drupalove It's fixing the issue for me too.
Comment #35
Jorge Navarro commentedComment #36
chiebert commentedForgive me if I'm being premature in reverting this to Needs review, but:
I've just been trying to deal with the contextual links issue that seems to be appearing in a number of related issues. Seeing some of the comments here - notably at #28, I assumed that perhaps this one patch would be the Holy Grail and deal with the underlying contextual links problem, but leave the other behaviours alone.
Alas. I'm not using Display Suite to define any file entity view modes - just a custom view mode via hook_entity_info_alter(), and I've attached a caption field to the image file entity. Before this patch, I get the unwanted contextual links for anonymous users - but I also get the expected media-element-container wrapper
<div>. After this patch, I don't get the contextual links, but I also don't get a full rendered image file entity as per the view mode I've specified. I'm just getting a naked<img>element, without a wrapper<div>or the caption field I've configured for the view mode.I'm using the latest -dev versions (as of this date) of File Entity, Media, and Ckeditor. Media_wysiwyg and media_wysiwyg_view_mode modules are enabled, and I've confirmed that, even with this patch applied, I'm getting the machine name of the view mode appearing as a class on the rendered
<img>tag: in my case, file-em-img-caption.Is anyone getting the best of both worlds with this patch + any other?
Comment #37
chiebert commentedOops - meant to set this to 'needs work', actually...
Comment #38
chiebert commentedSo, yeah - I've spent some more time in the debugger and the logic of this escapes me:
I don't use DS, but I do have a custom view mode and I have added fields and have configured my view mode to display one of those fields. So, in my case (since I've embedded an image via Ckeditor, and used media_wysiwyg_view_mode to choose my view mode for the display of my image),
if (!array_key_exists(...))evaluates overall as FALSE, so file_view() never gets called for my image file entity, and so my custom field never gets attached, and therefore, later on down the function, when we get to$element['content']only has 1 child,['file'], so it evaluates as FALSE, and I never get my wrapper divs...Does this really work for folks using DS?
Comment #39
drupalove commented@chiebert thanks for looking into this.
Adding your custom view mode is fine since it will be excluded from the unwanted rendering with Wysiwyg editor.
If everyone is happy with the approach of skipping view mode rendering in the Wysiwyg, it is easy to extend it to output the image caption & other fields you have added and a wrapper - in the same way like the image attributes and the image link (link_text), classes, etc. are output.
Comment #40
chiebert commented@drupalove: I think perhaps you may have misunderstood me: I created my image file view mode and selected it for display using media_wysiwyg_view_mode precisely because I wanted - and expected - view mode rendering in the final node view.
I think that's the expected behaviour here, since out of the box, when one enables media_wysiwyg_view_mode, one is presented with a choice in the media browser popup: 'display as', with a choice of view modes (configured via media_wysiwyg_view_mode). Why have the configuration to choose a view mode, and then present the user with a view mode choice, if by the very act of choosing that view mode, this patch excludes it from view mode rendering? We shouldn't then require the user to write a hook_media_wysiwyg_token_to_markup_alter, just to attach the fields that she has already painstakingly configured using the UI.
Am I missing something here?
Comment #41
chiebert commentedOkay, I'm nervous that, because this change potentially breaks so many old sites, it'll be reverted, which I think is a step backwards - I mean, leveraging the already-existing file_view() makes total sense here.
I'm willing to plug away at a way to configure this, as per @Dave Reid's concern in #21. Would this work as a concept:
media_wysiwyg_token_to_markup()we check these variables:Comment #42
drupalove commentedHey @chiebert,
I’m glad we’re in agreement the output should be configurable as suggested by Dave.
Could you throw some light on why we need a variable on the browser page at admin/config/media/browser.
Also, why can’t we check for allowed wysiwyg view modes in the array media_wysiwyg_wysiwyg_allowed_types() like I did in the patch rather than declaring another multiple type variable? I understand if the elements are not in the array then the user has intentionally not restricted them at admin/config/media/wysiwyg-view-mode and wants to use them for embedding files via wysiwyg. In other words, we have a handy switch already available to us rather than adding a variable at admin/config/media/wysiwyg-view-mode.
After you had the issue with the markup and caption, I thought we could look into using the same conditional execution in the media_wysiwyg_token_to_markup() - i.e. checking again for allowed wysiwyg view modes and adjusting the output to include the caption and other fields for the allowed view modes.
If you think it will not work could you briefly shed some light as your earlier comment was not clear to me.
If we agree my way is not suitable I’m in support of declaring new variable(s).
Comment #43
chiebert commented@drupalove: I'll see if I can be more clear...
Precisely because we need to configure this rendering method, and I can't see how your proposed patch in #28 is testing the cases correctly (see next response).
(By which you mean
media_wysiwyg_get_wysiwyg_allowed_view_modes(), of course.) The main reason is that your test is backwards, I think - don't get me wrong: I keep saying that I'm open to being corrected, but nobody has done so thus far.I see two problems with your patch:
And by the way, if the user has also installed the Media WYISWYG View Mode submodule, and chosen to restrict the view modes presented in the media browser popup, then that array will have even fewer items. In my case, it only had the one, which is the one that I chose.
Not being a user of Display Suite, I assume that the change up in #4 was made so that, however you chose to define your entity's display, you could be sure that was what was rendered when it was embedded in a text field. That being the case, we need to find a solid/easy way to let users manage the display of their file entities, and configure which rendering method is used. I suggested the Media browser config page as a place for a default rendering setting, since that's the currently-existing media_wysiwyg config page, and so it makes sense to put it there, from a UX perspective.
If we also want users to be able to more granularly set a rendering method per view mode, then I retract my earlier suggestion of using the media_wysiwyg_view_mode admin page, and rather suggest adding a vertical tab to the admin/structure/file-types/manage/FILETYPE/display admin page for each of the instances of the multi-variable...
Comment #44
drupalove commented@chiebert, thanks for clarifying this and for mentioning the change in #4 which will make the next step easier.
I think you missed something, see number #2 below.
media_wysiwyg_get_wysiwyg_allowed_view_modes() returns an array of view modes that a user:
See the other screenshot showing the dpm of $view_modes returned by media_wysiwyg_get_wysiwyg_allowed_view_modes() in the node. It is an array of the exact 5 view modes (keyed by machine names) which I have not restricted at admin/config/media/wysiwyg-view-mode.
Unless I’m missing something I still believe we are able to distinguish the view modes of embedded wysiwyg files without additional variable at admin/config/media/wysiwyg-view-mode
What do you think we should do next?
I'm glad you're trying to push this forward which eventually will fix at least 3 issues I know of beside this beta blocker issue.
Comment #45
chiebert commentedI didn't miss that bit about restricted view modes - see the last sentence of my first point in #43.
Let me try this again, from the beginning (meaning, before this whole issue started):
media_wysiwyg_token_to_markup()sort-of-manually built up the fields using calls tofield_attach_prepare_view(),entity_prepare_view()and thenfield_attach_view()(see the lines that were removed in the patch that was committed way up in #4).field_attach_view()method was completely removed, in favour of adding field information frommedia_wysiwyg_filter_field_parser($tag_info)to the $file object, and then simply callingfile_view()from File Entity, which is all about using the right way of rendering entities - so presumably now Display Suite-managed view modes are handled properly (again, I don't use DS, so I don't know what's different about the method).field_attach_view()and its precursers), or else simply default to using the old method.if (whatever test you want) {use the file_view method}then you would also need to include anelse {use the old method}to cover those who want the old method. Which you've left out.So, the way forward, as I see it:
We need something to test, to see if someone wants/needs the full entity rendering of
file_view(), or the old method of callingfield_attach_view().We might possibly test to see whether the selected view mode is controlled by DS - but who knows if there will arise other module out there that does something similar to DS and we'd be back in the same boat.
If we can't find something existing to test (and I hope I've convinced you that
media_wysiwyg_get_wysiwyg_allowed_view_modes()does not cut it), then we need a variable.Comment #46
ksenzee#45 is a very good summary. As chiebert says, for this to be configurable, we need some way to know whether the site should be using the old field attach–based rendering method or the new file_view() method. Proposals on the table are
a) opt in to the new rendering sitewide, via a checkbox at admin/config/media/browser
b) opt in to the new rendering one view mode at a time, via a vertical tab at admin/structure/file-types/manage/FILETYPE/display
c) use old-style rendering for people who have restricted their list of wysiwyg-allowed view modes, and new-style rendering for everyone else (at least this is how I think the patch in #28 ends up working)
The original point of this issue was to get rid of the old field attach–style rendering entirely. Does anyone disagree with that as a long-term goal? If not, then I'd rather see us go with a) or b). That way, we can default to the old rendering method, and people can switch over to the new rendering when they're ready to. Nobody's markup will break because of a minor version update. On the next major update, we could even get rid of the old method, and point out the updated markup in the release notes as something people need to be ready for. If we go with c), we'll be stuck with the old field attach–based rendering, even into the next major version update.
I personally think a) is the best and fastest way forward. b) seems like overkill (especially if we want to someday phase out the old rendering style). Dave, any opinions? Technically I'm a media module maintainer but I haven't committed anything in donkey's years so I don't really count. :)
Comment #47
themusician commentedI agree with ksenzee that #45does a great job of summarizing the thread/issue. I also concur that option a is a future-friendly and backward compatible approach.
Even if 2.x reaches a stable release, the old render mode could be dropped, but we need to help people see what has changed. I love the idea of defaulting to the current display method and then allowing the new method to be turned on when a site owner is ready and had made the appropriate changes.
Comment #48
dave reidHrm, I thought I had already stated I'm 100% in favor of option A in #46. I would prefer that new installs get the new render method, but existing installs get the old render method (set manually via an update hook).
Comment #49
ksenzeeHere's a patch that makes the file rendering method configurable (option A). New sites get the new method, old sites get the old method, and you can change methods on the settings page.
Comment #50
dman commentedNice to see consensus arriving here.
I have a remaining niggle in this space - specifically that *although* this patch/fix now mostly uses my displaysuite layout (yay)
- I still get an extra unneccessary 'media-element-container' div, even when my rendered content is just one figure element (that I'd rather style directly).
I understand that it's safer and much more Drupally to always add another div if there is any chance of styling in the future ... but this screws up my widths and floats.
The problem I see right now is that display suite (specifically at least) intercepts the rendering quite late in the process to add its own wrapper. At this point in the code
we don't actually know what the $output will really look like or whether we need to force that wrapper.
FOR NOW (my need today) I'm thinking to introduce a little media_wysiwyg_token_to_markup_alter() to repair this niggle.
But I'm wondering whether we could also retire that count(element_children) logic to the "old way" and trust that the "new way" will always have at least one of its own wrappers around a view_mode.
Comment #52
dave reidCommitted #49 to 7.x-2.x. Thanks so much @ksenzee and everyone else for helping push this forward.
@dman Could you please file a follow-up issue for your comment so we can address it in a new issue?