This is a stub issue to hold discussion and ideas while #1879120: Use Drupal-specific image and link plugins — use core dialogs rather than CKEditor dialogs, containing alterable Drupal forms is getting finished up.
Right now we have the ability to insert an image into a WYSIWYG editor through a modal dialog that is provided by Drupal. However this modal right now only provides the basics: URL, height/width, and alt attributes. There is very little point in making a dialog that does a server-side request unless we make use of the the server-side abilities that Drupal provides us. In this case, I'm referring to allowing a user to upload an image in the image modal dialog.
Because the modal dialog is server-side, it means that we can use a #type = 'managed_file' element in the modal to handle file uploads. After the initial problem of uploading a file is handled, we may extend this element (similar to the way FileField Sources does) to provide other ways to select a file, such as using Views to select recent uploads, or to actually *transfer* images from remote URLs, or to paste from the clipboard, or other ways of managing files.
Related issues
#421118: [Meta] Standardize capitalization on actions
#2067119: 'width' and 'height' HTML placeholder attributes in image dialog are not translated, yet should be lcfirst
#2067263: Drupal dialog placement must take displacing viewport elements, like the Toolbar, into account when calculating placement
#2067285: The entity in-place editing toolbar appears above the Drupal dialog
#1844220: Make in-place editing keyboard and aurally accessible
#2060405: Impossible to uninstall any module using the file usage service, because it is impossible to delete all file usages by a module
#2067833: Add image alignment to WYSIWYG
Comment | File | Size | Author |
---|---|---|---|
#100 | editor_image_uploads-1932652-100.patch | 32.98 KB | Wim Leers |
#100 | interdiff.txt | 1.07 KB | Wim Leers |
#94 | Screen Shot 2013-08-28 at 1.13.33 AM.png | 100.24 KB | webchick |
#94 | Screen Shot 2013-08-28 at 1.21.36 AM.png | 84.07 KB | webchick |
#94 | Screen Shot 2013-08-28 at 1.25.53 AM.png | 20.08 KB | webchick |
Comments
Comment #1
quicksketchSo in general, I think the things we know for sure are these:
However we don't know where we should put these settings for sure. Initially I thought using an existing File field would be the way to go. The existing field UI for configuring a file field would handle all of these settings for us. Unfortunately this approach would have a few downsides. Namely, you'd end up with an extra field on your entities that you'd never use directly, and you'd have a constant problem between "which one wins" when a file is referenced in a text area but removed from the file field (or vice-versa). The biggest problem of all is that this would mean you could only upload images when a filtered_html element is used on *entities*, because we're dependent upon another field for handling the uploads. This means that places that aren't fields (i.e. Header/Footer configuration in Views) wouldn't be able to upload an image when using a text format with an editor, because there would be no place to display the field configuration.
We could start going down the path of making views into fieldable entities. But I don't think that's the right route to take anyway. It's confusing that you would need to go one place to configure your editor (text formats) but you would need to go someplace else entirely to configure how image uploads would work within the editor. So instead, I'd like to make the following proposal:
$element['#editor_uploads'] = TRUE
. Each module that provided editor module integration would need to specify this property, or another module would need to form_alter() it in.<img src="whatever.png" data-fid="123" />
.editor_save_files($input_text, $type, $id, $editor)
or$editor->save_files($input_text, $type, $id)
This would parse the input text for all FIDs and mark the necessary files as permanent. It would also increment the file usage entries by one (hence why $type and $id are provided). If files were *removed*, it would also decrement the file usage entries by one and then call file_delete() to clean up the file if no uses were remaining.This approach solves nearly all problems that I can think of. It makes configuring uploads in an editor trivial: the settings are right there when configuring the editor (probably when you enable the drupalimage button). It also makes it so you can upload files anywhere text formats are used, even on places where they're not entities, assuming that the module that saves the value of the filtered_html element has set the #editor_uploads = TRUE property and calls the necessary save function when saving the value to the database (or CMI in some cases). It also removes the annoyance of having a field that sites on an the entity for no purpose other than to insert files into the WYSIWYG. And it removes the problem of stale files and mismatch between a file field displayed on the entity and files that are referenced directly in the text area.
The only downsides are that if a user manually removes the data-fid property from the HTML, a file usage entry will not be added (or will be decremented if updating a value), causing the file to be deleted after 6 hours when cron cleans up temporary files. It's also slightly inflexible that all your files will be saved into the same directory, and that file upload settings are per-format. However I don't think this is a terrible limitation, since text formats are already individually permissioned, and if we really wanted we could make some kind of token for the upload directory that allowed files to be saved into a particular location based on the properties passed into $editor->save_files(). That would solve most file organization concerns (if any).
Comment #2
quicksketchComment #3
jcisio CreditAttribution: jcisio commentedI'm working on a Drag'n'Drop (instead of a native or CKEditor dialog) file upload that works with the latest version of Firefox/Chrome/IE. Should it be part of this issue or I publish first a contrib module? In the latter case I'll focus on a D7 version.
Comment #4
quicksketchI'd like to make every common mechanism available in core (select file, drag and drop, paste from clipboard), but I'm not sure if that's a realistic goal. This particular issue is getting the architecture in place to just manage files consistently in WYSIWYGs, so we'll probably only be doing the simplest implementation (select and upload) here. If you're getting into drag and drop, you might look at @Deciphered's module: http://drupal.org/project/dragndrop_uploads.
Comment #5
larowlan@quicksketch, does #1 allow us to make the image form fieldable ala file_entity/media?
Eg taxonomy terms or other fields on the images etc - so the views etc (eg recent uploads etc) could be as powerful and flexible as possible
It's a managed file so I guess we could form_alter in the field_attach_form/submit/validate logic at a later date?
Comment #6
jcisio CreditAttribution: jcisio commentedThanks, I didn't know that module.
Comment #7
quicksketchYes, all files uploaded through the WYSIWYG would be full file entities. Because the managed_file element is built entirely around managed files, each file created/uploaded via the WYSIWYG is a file entity just like any other file uploaded into a Field module file field. As such, fields can be added to the individual file after it's been uploaded. My module file_entity_inline already demonstrates that you can extend the managed_file element to include inline fields related to the uploaded file. Though it currently only works for file fields, it executes its inline ability on all managed_file elements; it's just that fields are the only place where you can configure the functionality.
Yep, and if we so desired, we could formalize the concept of File Field Sources module and make that the official mechanism for selecting a recently uploaded file via a view, or any other mechanisms you'd like to getting files on your server (FTP, cURL transfer, etc). Out of the box I'd like to at least have file upload and a views-based browser in the modal dialog.
Comment #8
larowlan@quicksketch - let me know where I can help with this, this will be awesome
Comment #9
quicksketchHi @larowlan! The immediate need is to get the basic modal support in: #1879120: Use Drupal-specific image and link plugins — use core dialogs rather than CKEditor dialogs, containing alterable Drupal forms. I've started work on a patch that builds on top of that one, but it's minimal so far. I'll post my progress when I have something working.
Comment #10
Wim Leers#1: general +1 :)
Some remarks/questions:
#type = filtered_html
element work? Which module would call it? This is the most vague part to me, though I think I kind of know what you mean, it's just technically not very clear. You talk as if this exists already, but unless I'm missing something, it does not yet exist. Most likely, you're referring to "any place where text filtering is taking place", but I'm not sure this architecture change is acceptable for everybody. Nor do I even know what the consequences of such an architecture change would be.$element['#editor_uploads'] = TRUE
necessary at all?The only way to not break previous revisions is by counting file usage counters on the revision level, not the entity level.
editor_save_files
stuff… that'll be "kind of like a filter but not really". I like the overall concept, but I think this is where it won't fit into the existing architecture. I very much hope I'm wrong :)Comment #11
quicksketchActually yes you're right. For now I'd just like to focus on image uploading and have the drupalimage plugin do any necessary binding we require for drag and drop or copy/paste.
Yep, I agree here too.
Yeah, after the recent fiasco with Drupal 7.20 and broken inline images all over the place... we'll need to think this one through a little better. IMO to do it right we'd need a data-attribute for the image style and have the SRC attribute always point to the original file until after filtering.
My bad, I mixed that up with "text_format". Everywhere I said #type = filtered_html I meant "text_format". It's the Form API element that takes a #format property already and makes the combo textarea + format select list.
Because uploads through the WYSIWYG are only going to be stored as temporary files. The module will need to implement a saving mechanism to mark the files as permanent. For example text.module will call $editor->save_files() in hook_field_insert/update() while Views might save any inline files when the entire view is saved. So there needs to be an indicator at the time that the form is built that indicates, "this particular field's content will be parsed on save", since it's not necessarily a given that all modules will do that.
It's pretty simple actually: every time a node is saved with a new revision, all the text fields within that node are parsed for FIDs. For every FID found, every single file is incremented by one usage for that node. If editing an existing revision, you have to get all the FIDs for the previous revision, then compare that against the list of FIDs for the new revision. Any files that have been removed, you decrement the FID count for that node. So a single node with revisions is very likely to have the same file referenced many times. Only by deleting every revision (or the entire node all at once) would all of the file usage records go down to zero, thus causing the file to be deleted.
Yep, but even though we're counting usages by revision, we can lump all the counts from all revisions into a single "this entity has X uses of this file". It's the same way File fields manage revisions today.
Yeah exactly spot on with "kind of like a filter but not really". This saving of files to make them permanent is no different in my mind than each module needing to store a #type = text_format element's format ID. The module has to store that somewhere (usually the database) and at the same time its the perfect opportunity to parse it for any file references, since you know at that point you'll already have both the text that needs parsing and the filter format (which can then load the editor configuration).
Comment #12
Wim LeersAlright, sounds like we're in complete agreement :) I'm glad that your experience with File Field Sources has given you a more holistic background — thus you're in a much better position to judge all this than I am! :)
RE: image styles fiasco — that is actually related to #1863530: Don't generate CDN URLs when using the Insert module by blacklisting file/ajax/* (an issue with the CDN module)… :) It'd be cool to take all of that into account.
Comment #13
wwalc CreditAttribution: wwalc commentedMaybe I don't understand how the data-fid will work in general, but I have some doubts regarding the data-integrity...
1) What will happen if I copy & paste content from another Drupal site, with an image that has
data-fid
set?Example:
Site "A" has an image "A" with data-fid = "1". I copy some content from Site "B", along with an image "B", with (the same) data-fid = "1" (I am even not aware of this as I just selected something and pasted it).
2) Another (minor) problem to keep in mind - an image is uploaded, data-fid is set automatically, then user changes an URL in the image dialog to a different image.
(I guess this case can be solved quite easily by removing fid in case of an external image, or by updating fid to the correct value if the URL points to a file that has a different fid, to make sure that image will not be lost accidentally some day).
Comment #14
quicksketchWe could do some basic URL checking to check that the FID lines up, such as checking the base file name lines up with the associate file entry loaded from the database. However I would think that it would be unlikely (but not impossible) that a user would copy/paste text only and both sites would happen to have the same file in the same location at all. In which case if the file didn't exist on server B, we could skip any file accounting on a mismatch or non-existent file.
We could use the same treatment as the first situation in the event of a mismatch.
In most situations if the FID has been changed or mismatched, it would result in the original file that was uploaded being deleted after 6 hours during cron.php cleanup of temporary files, but this would only be a problem if the user manually changed/deleted the data-fid but kept the URL the same (very unlikely). If the URL was changed but the FID was left the same (slightly more likely), then presumably the new file would already be "owned" by another piece of content and the worst situation would be that piece of content being deleted and a dead link resulting. Neither situation is terribly fatal and would essentially result in that particular reference going unaccounted for.
Comment #15
Wim LeersClarifying issue status; this is postponed on #1879120: Use Drupal-specific image and link plugins — use core dialogs rather than CKEditor dialogs, containing alterable Drupal forms landing.
Comment #16
sunThat's what UUIDs are for. You're absolutely right that content should not contain references to serial IDs.
Luckily, all entities have UUIDs in D8 already. We can simply use them.
Comment #17
quicksketchThanks @sun that's a great point. I hadn't realized/thought of that.
Comment #18
Wim LeersDo we aim to get this done before code freeze? Can this be done after code freeze?
Comment #19
nirbhasa CreditAttribution: nirbhasa commentedJust wondering what is happening with this - is it too late to get this in? I am not au fait with what is and isnt allowed under API freeze, but this seems like the kind of 'on-top' functionality that doesnt require API change.
New Drupal adopters - who may see image uploading as an integral part of the WYSIWYG experience - might be a little deflated to find it not there. (It won't affect me in the slightest, I just took my first test drive of the latest D8 last week, with a view to putting a site live in the next month, and so far I love and love and love what I am seeing)
Just a suggestion: I note there is an 8.x version of https://drupal.org/project/elfinder - earlier versions were integrated with the CKEditor module, but the latest 8.x probably isn't integrated with the Drupal native dialog yet.
However, it might serve as an imperfect-but-there solution and then work can be done on a more fully integrated experience in D9. Bringing it in as a standalone module wouldn't hold up any other functionality.
Comment #20
Wim Leers#19: I also think this can still go in, it won't require an API change, only an API addition (insofar this will be considered an API).
I agree this is super super important. Unfortunately I won't have time for it. quicksketch promised to work on it at DrupalCon Portland, almost two months ago, but he got sucked into client work so hasn't had the time either. Maybe he has time now? :) Or maybe you have time?
Comment #21
nirbhasa CreditAttribution: nirbhasa commentedSo here is a patch that adds:
- a managed_file field to the image dialog
- upload directory, max filesize, min and max dimensions to the filter config page: these are used to construct validators for the managed_file field
Im not too sure what to do about file saving, ill need a little help here. The patch contains some simple file saving in the submit function of the image class. However, for some reason file_load isn't working on the uploaded file (its also not previewing properly once uploaded, maybe that's a hint)
Comment #23
nirbhasa CreditAttribution: nirbhasa commentedHmm. Basically the tests are failing because the CKEditor test doesn't pick up the extra
$editor->settings
variables. Should I store them somewhere else -$editor->upload
perhaps?Comment #24
nirbhasa CreditAttribution: nirbhasa commentedNew patch: this one actually uploads an image, although the saving probably needs to be abstracted somewhat, the code is still in the form submit function.
The other thing is that uuid's are not created by the managed_file field upon initial upload, is that a bug we need to make another issue for, or is it something that needs to be handled as part of the form submit process?
I also moved the upload settings to
$editor->upload
- it seems to make sense to have$editor->settings
deal just with the particular text editor.Im not sure how much farther I can take this, it would be good to get another set of eyeballs on it.
Comment #25
nirbhasa CreditAttribution: nirbhasa commentedAccidentally deleted tags - readding now!!
Comment #26
quicksketchNice @nirbhasa! A few things: Let's kill minimum image dimensions. That makes sense for a dedicated (tightly controlled) image field, but not so much for a WYSIWYG's uploading. An option that *should* exist however is the ability to choose the file scheme (private/public/etc), in the even that access to images should be tightly controlled (say on an intranet site).
Comment #27
nirbhasa CreditAttribution: nirbhasa commentedSo this patch loses the minimum dimensions and adds file scheme.
To summarise whats left (as I understand it):
- The uploaded file needs to get itself a uuid as part of the managed_file element upload, and I think that's going to need its own ticket (Let me know, and I'll create it!) We can then add the uuid as a 'data-id' attribute to the HTML.
- Once that is done, move the file saving to an editor_file_save function or $editor object that is called by hook_entity_presave. This scans all attached textarea fields for this 'data-id' attribute, makes the files with those uuids permanent if they aren't already, and increments the file usage tally for those files.
- We need to implement hook_entity_delete to scan textareas in all revisions of that entity (is that going to be a performance drag?), and hook_entity_revision_delete to scan textareas in that particular revision, and decrements the file usage accordingly.
- Add #editor_uploads property to the text_format element in editor_element_info. What does our callback function do if editor_uploads is FALSE? Replace the managed_file field with the original URL field? (sorry, this is the bit I'm least clear about)
Comment #28
quicksketchYep, I think that's correct. If you have #editor_uploads = FALSE but are still showing the image button, the image dialog would just have the URL field. The user wouldn't even be able to use a file browser (assuming we are able to implement one) or other means. If that file were managed by Drupal, selecting an existing file would need a data-id attribute and increment that file's usage just like a newly uploaded file.
Comment #29
nirbhasa CreditAttribution: nirbhasa commentedUUID issue: #2046809: UUIDs not added when file uploaded using managed_file FAPI element. I guess we can press forward on the rest in the meantime.
Comment #30
quicksketchThanks @nirbhasa. As I wrote in #2046809: UUIDs not added when file uploaded using managed_file FAPI element, I think we can work-around this current problem by just using entity_load() on the acquired FID, and then pull the UUID out of the loaded file.
Comment #31
quicksketchOkay here's a reroll (still needs work overall but I'm letting Testbot take a shot). It makes the following changes:
- Image file settings are now "owned" by the DrupalImage CKEditor plugin. This means that the settings only appear when the image button is dragged into the toolbar.
- However despite the DrupalImage CKEditor plugin owning the settings in the form, the settings are actually saved into the base $editor->settings array. This is because Editor module owns the image dialog form. In theory other modules could populate the same settings array to use the image dialog with other editors, but since CKEditor's DrupalImage plugin owns the settings form, they'd need to recreate that portion.
- Vertical tabs summary support for the new settings.
- I added support for a new FAPI property on all "text_format" elements called "#editor_uploads". This property determines whether or not an upload field is provided instead of a URL field. The TextareaWidget provided by Text module sets this property to TRUE.
- UUIDs are now added to the inserted file tags. These increment file usage on entity save. They DO NOT yet work on deleting revisions, content, or updating an existing revision. I think the code location needs to be moved (right now it's in
Drupal\text\TextProcessed
). There's a TODO in there documenting this.- Temporarily including the fix from #2046809: UUIDs not added when file uploaded using managed_file FAPI element until that issue is resolved separately.
Comment #33
nirbhasa CreditAttribution: nirbhasa commentedHi, took a look at patch - definitely looks much better :)
- The URL field is shown by default. Once I save the filter format settings page, then the managed_file field appears.
- I had a look at trying to move the file usage code into the entity hooks. What is the easiest way to get the values of all text editor fields for a particular revision ID? Im having a little trouble navigating the docs.
My hands are going to be full over next few days, I can try and come up with something next week, unless you get there first :D
Comment #34
webchickOh. This is the issue I meant to make major, I think!
Comment #35
Wim LeersNice progress here! What's left to get this to completion? :)
Comment #36
nirbhasa CreditAttribution: nirbhasa commentedFunctionally, the only thing left to do is to move the file usage incrementing/decrementing somewhere that is aware of revision context, so we can act on entity delete, revision delete, and revision update. Im having hardware issues at moment so i cant be of much help this week, unfortunately.
Comment #37
Wim LeersI'm on it now.
Comment #38
Wim LeersFixed bugs
$entity->id()
returned NULL.editor
module, not thefile
module as the owner/user in thefile_usage
table.$editor->settings['image_upload']
stuff would always be set, even if theDrupalImage
button was not being used, plus#editor_uploads
was not text format-specific, so this effectively meant you still had no per-text format control over this. I've added aimage_upload.status
config key, with a corresponding "Enable image uploads" checkbox. Once you check this, image uploads are enabled for this text format, and at the same time this means we can now hide all the image upload settings unless this is checked (using#states
). This allowed me to remove the#editor_uploads
plusdata-editor-uploads
plusuploadsEnabled
hacks/passing through all over the place.The original reason for having
#editor_uploads
was this:But now we implement this saving mechanism through entity hooks, so there is (fortunately!) no need anymore for a custom callback that every module has to call.
editor.editor.(full_html|basic_html).yml
files weren't updated yet to have image uploading enabled by default.Fixed design flaws
data-file-uuid
implies it is used/owned byfile.module
, so I renamed it todata-editor-file-uuid
.schema.yml
files hadn't been updated yet (see https://drupal.org/node/1905070). Worse, even, the approach taken in previous patches in this issue was fundamentally incompatible withschema.yml
files, because$editor->settings
contains text editor plugin-specific settings, but this issue is breaking that. That's why I moved the settings from$editor->settings['image_upload']
to$editor->image_upload
.DrupalImage
plugin rather thaneditor.module
. So other text editors would need to recreate this form. I fixed that.editor.module
now provides a function to generate the subform necessary for image upload settings, so that other text editor plugins can just reuse this.Follow-ups filed
editor.module
: all file usages should be deleted. Sadly, the file usage service's API prevents this from being done properly. Filed an issue: #2060405: Impossible to uninstall any module using the file usage service, because it is impossible to delete all file usages by a module.data-imagestyle
attribute, and is handled by a yet-to-be-addedimagestyle
filter. However… it would probably be even better if this would be integrated with thepicture
module instead, so the images are responsive. Everything remains analogous: instead of selecting an image style, you'd select a picture mapping. See #2061377: [drupalImage] Optionally apply image style to images uploaded in CKEditor 5.Remaining flaws
_editor_get_processed_text_fields()
essentially hardcodestext.module
's field types. I'm not sure how we can get around that. I can think of work-arounds that will enable Drupal 8 contrib to inject more field types, but I cannot think of a way to have them being found automatically; the entity/field system metadata is not rich enough for that AFAIK. In the grand scheme of things, I think this is only a small flaw though, and one that is not caused by or inherent to this issue.Noteworthy remarks
hook_entity_revision_delete()
was not present inentity.api.php
, so I fixed that too.<img>
tag. Furthermore, hotlinking external images is generally a bad practice anyway (URL might change, resource might cease to exist, hotlink protection might break it, inherently worse front-end performance, and so on). Finally, by installing https://drupal.org/project/filefield_sources, you would simultaneously update the "insert image" experience in the WYSIWYG editor, which is highly desireable.TextProcessed::setValue()
(which was utterly broken because when that is called, no entity ID has been generated yet for new entities), and replaced that withhook_entity_(insert|update|delete|revision_delete)()
implementations. All is well for nodes and other fieldable entities. However, this does not work for Views: we have no way of knowing where in a View (Entity) object textual information lives that uses a text format: because it is not a fieldable entity, it does not implementgetPropertyDefinitions()
, which is what we use for all other entities to figure out where we need to record file usages. That being said, I think this is very much an edge case, and as such it should be handled in a follow-up. The >95% use case is to be able to use this on nodes and other fieldable entities.What's more, is that in the two locations where Views uses
#type = text_format
, it actually explicitly sets#wysiwyg = FALSE
, to instruct http://drupal.org/project/wysiwyg to not apply a WYSIWYG editor. (I discovered this while trying to figure out a way to make it work regardless of the above reasoning on why not to do it.) Because Drupal 8 requires it to use#editor = FALSE
, that isn't happening yet. I'm not sure why they did this, but I'm sure it's with good reason, so I think it's better for all of us to just not worry about this for now.Screenshots
This whole thing is less than ideal. Ideally, we'd have a media library in Drupal core, and allow the user to upload files to the media library, and select files from the media library. We don't have that. The current UX is bad. This patch makes the UX much more in line with what most of us expect to be able to do. It's technically less elegant than it should be, but technical elegance can't stand in the way of better UX.
But … the overall approach taken here, with a
data-
attribute containing the file's UUID, also paves the way for an easier upgrade path in Drupal 9 to ship Drupal with a built-in media library!Comment #39
Wim LeersMADNESS!
Comment #40
Wim LeersThis probably needs usability review.
Comment #42
Wim Leers#38: editor_image_uploads-1932652-38.patch queued for re-testing.
Comment #43
hass CreditAttribution: hass commented#wysiwyg = FALSE
sounds like porting leftover...Comment #44
Wim Leers#43: yep, exactly :)
Comment #46
Wim LeersOkay, the failure is legitimate. Reproduced locally. When running
Drupal\node\Tests\NodeRevisionsAllTestCase
:WTF.
I must say I don't yet see what causes this.
Comment #47
Wim LeersFound & fixed.
Also: FML. I'd written full test coverage for
editor.module
's entity hooks but failed togit add
the file. Now it's gone. Rewriting it at 22:20 on a Friday night. :/Comment #48
Wim LeersReproduced the full test coverage from memory, fueled by http://palm.be.
Comment #49
Wim LeersThe follow-up #2060405: Impossible to uninstall any module using the file usage service, because it is impossible to delete all file usages by a module has been fixed — yay!
Can we now get this issue moving forward too? Anybody up for reviews? Anybody who wants to trade patch reviews?
Comment #50
Gábor HojtsyI looked at the config changes vs. the schema changes and they all look good.
Comment #51
Wim LeersThanks! Now we still need PHP, JavaScript and usability review!
Comment #52
Gábor HojtsyReviewed the PHP code as well. Generally good. Some notes!
IMHO feel free to put in the same code as the one you implemented :)
Also, is this hook already there but was undocumented? I miss a change in the patch where this is invoked.
It is strange to see the placeholder being the same as the label on the field. What additional information does this add (beyond being noise?). If it does, t()-ing it would be needed too, no? It is user facing text.
Should this be extensible somehow? Contrib can add more text-like fields that would work with ckeditor possibly, no? Not sure if I have a use case from the top of my head though.
Maybe we should just look at the text processing setting, and assume if it is on, then regardless of type, the field is text. :)
Is this extensible to eg. an image gallery module with regular form alter? I assume so being in a buildForm(), but wanted to make sure this is taken into account.
This should now be Contains \Drupal... no?
Too much whitespace.
Comment #53
Gábor HojtsyCrosspost.
Comment #54
Bojhan CreditAttribution: Bojhan commentedLooking at this, I see no usability issues. The only thing that marked me as odd is that the file field is now above the body? That shouldn't be like that. I also expected this would add a file, to the file upload field (in its listing) - but perhaps thats just previous conversations shaping the expected behaviour.
The files listings and modal dialog are still horrible in terms of UX, but that is not part of this issue :)
Comment #55
Wim Leers#53:
I first did that, but all other examples are WRT some
example_entity
, so an example in line with those should be thought of.Yes, it is an existing hook.
This is done because the form element label (
#title
) is hidden (#title_display => invisible
), so that we can have a<width> x <height> pixels
form with the two form fields inline. That's also why we want/need#placeholder
.That being said, yes, it should've been
t()
'd. Fixed.Yes, it should be extensible. It is listed as remaining flaw number 1 in #38.
Great suggestion: implemented! :)
You're right. Bad copy pasta.
All fixed now!
#54:
That's also not part of this issue. It's been like that in Drupal 8 for a long, long time. As long as I can remember, actually.
That's intentionally not the case, and indeed probably previous conversations shaping the expectations :)
Thanks for the usability review!
Comment #56
hass CreditAttribution: hass commentedA placeholder that is just the same like the title does not add any helpful info. Aside of this the placeholder is not written ucfirst. However I'm strongly for removing this as it does not add anything helpful. A "number" as example placeholder may makes sense here and is helpful.
Comment #57
seutje CreditAttribution: seutje commentedI don't see anything wrong here, the selectors are a bit gross, but that's inherent to how the name attribute is built.
Comment #58
Gábor Hojtsy@hass: the label is not visible, that was the point. Maybe a screenshot would be helpful for you? :)
Comment #59
hass CreditAttribution: hass commentedWell, a screenshot can help a lot :-). Than we have the ucfirst issue only in placeholder text.
Comment #60
Wim Leers#59: there already is a screenshot in #38, but I'll repeat it here for you:
It will look very weird/crappy/broken if we change
width x height pixels
toWidth x Height pixels
. I veto against that. Automatically lowercasing that is also inherently broken, e.g. in German it'd need to beBreite x Höhe Pixel
, but would then becomebreite x höhe
. Isn't the proper solution to add a translation context?Comment #61
tstoecklerHmm... translation contexts are generally used for giving semantic meaning to a word or string. I don't really see why that's needed, though. Following your example:
we just do t('width') and the German translation of 'width' (lowercase) is 'Breite' (uppercase) because 'breite' (lowercase) is not a proper word in German. KISS?
Comment #62
Wim LeersI agree! That's exactly what I have now :) But … hass is arguing that that is bad, see #56. I don't see a cleaner solution either, so unless hass comes up with a better solution, I think the current patch is good to go. I don't want this issue to derail even more than it already has, so if hass feels very strongly about this, we can change it in a follow-up.
So, now we've had a schema.yml (#50), usability (#54), PHP (#52) and JS (#57) review.
Does that mean this issue is now RTBC?
Comment #63
hass CreditAttribution: hass commentedI'm coming from #421118: [Meta] Standardize capitalization on actions that may has a misleading title regarding the issue here, but we are changing all this words for the reason of context. If we have English lcfirst we should not translate ucfirst in German. I fear that we run into the same issues like #421118: [Meta] Standardize capitalization on actions and wished we change all the single/two words strings to ucfirst. I'm not a native english speaker, but why is
Width x Height pixels
weird/crappy/broken? Add/Delete/Change looks not weird/crappy/broken, butWidth x Height pixels
does? I'd like to understand... :-)Comment #64
tstoecklerI must say that I'm sort of torn about t('width') vs. t('Width'). The former looks weird in code, the latter looks weird in the UI (both arguably), so I guess the latter would be my tentative choice.
However,
is simply not correct. "width" is a proper English word with the translation "Breite". That's just the difference in capitalization in the two languages. You can never say "breite" in Germany, while you can say both "Width" and "width" in English.
Again, that's not to say that we should definitely stick to lowercase, that's just to say that we don't have a problem with translatability either way.
Comment #65
Wim Leers#63, #64: please start a new issue — this discussion is very much offtopic. The code under scrutiny already is part of Drupal core, so you can discuss and fix it in a separate issue: http://drupalcode.org/project/drupal.git/blob/394b9d158f8491dbd4f1c2733d...
I'll remove the
t()
-wrapping that was introduced in this patch.Comment #66
tstoecklerAhh, I see. I did not realize that. In that case, you are of course correct. That totally belongs in another issue. Opened #2067119: 'width' and 'height' HTML placeholder attributes in image dialog are not translated, yet should be lcfirst for that.
Comment #67
Wim LeersNW because I should reroll it to exclude the translation hunks being discussed in #56–#66.
Comment #68
Gábor HojtsyI'm fine with removing the translation code and discussing it separately, since it looks like an unexpectedly contentious issue.
Comment #69
Wim LeersAs per #67: removed the contentious translation hunks, which are now being dealt with at #2067119: 'width' and 'height' HTML placeholder attributes in image dialog are not translated, yet should be lcfirst.
Comment #71
jessebeach CreditAttribution: jessebeach commentedRelated but not blocking, dialog placement calculations don't currently take displacing elements like the Toolbar into account when determining the position:
#2067263: Drupal dialog placement must take displacing viewport elements, like the Toolbar, into account when calculating placement
Comment #72
jessebeach CreditAttribution: jessebeach commented#69: editor_image_uploads-1932652-69.patch queued for re-testing.
Comment #73
jessebeach CreditAttribution: jessebeach commentedLet's get label naming consistent:
This is the current admin form for the plugin:
Here's what I suggest as label changes:
The intent is to make consistent through the UI that this feature concerns inline image placement.
Comment #74
jessebeach CreditAttribution: jessebeach commentedI noticed a CSS issue with in-place editing while testing. I've logged it as a bug: #2067285: The entity in-place editing toolbar appears above the Drupal dialog.
If we get this committed soon, it'll be my responsibility to make sure it works with the in-place editing aural UI flow: #1844220: Make in-place editing keyboard and aurally accessible.
Other than the label changes in #73, the JavaScript code looks fine. I read through the PHP code and it seems sane and straightforward. The translation issue has been shifted to the right queue, rather than being debated here. It's almost RTBC, once the labeling issues are addressed.
Comment #75
Wim Leers#73: I like what you're trying to do, and I agree that the "Drupal image" tab name is rather … arcane. However … the tab names are generated automatically from the CKEditor plugin names. And you've guessed it, the CKEditor plugin name is "Drupal image".
We can't rename the CKEditor plugin to "inline images", that'd be wrong. I can rename it to just "Image" though.
Furthermore, I *can* add a title to the vertical tabs container: "CKEditor plugin settings", just like we have "Filter settings" further down on that page. I think that'll help in clarifying what this is all about.
Finally, "Allow inline images" is similarly wrong, it implies that if you don't check that box, the user won't be able to insert images at all. But all it is intended to do is precisely what the previous checkbox said: it enables image uploads. Changing it to "Allow image uploads" is fine though.
So, combining all this, I end up with this:
I hope that you'll find this a good compromise.
Comment #76
Wim LeersForgot to attach interdiff, which is tiny:
Comment #77
hass CreditAttribution: hass commentedCan we change "Allow image uploads" to "Enable image uploads", please? Allow sounds like a permission where enable is the normal wording if we enable features.
Comment #78
Wim Leers#77: That's what I had. I changed it based on jessebeach's feedback in #73. Please find consensus with her.
Comment #78.0
Wim LeersUpdated issue summary.
Comment #79
hass CreditAttribution: hass commentedAdded #2067833: Add image alignment to WYSIWYG to related cases as this may should be part of this issue, but isn't.
Comment #80
Wim LeersStraight reroll of #75 after #1847002: Move entity type classes from Drupal\$provider\Plugin\Core\Entity to Drupal\$provider\Entity landed.
Comment #82
Wim LeersDarn, I missed a spot :/ Will reroll.
Comment #83
Wim Leers.
Comment #84
Bojhan CreditAttribution: Bojhan commentedThe summary of the VT should probably include whether its allowed. Thats the most important setting.
Comment #85
jessebeach CreditAttribution: jessebeach commentedI'm fine with "Enable image uploads". No sense blocking an important issue on inanity.
Comment #86
Wim LeersYay! So I will:
Then this should be RTBC!
Comment #87
Bojhan CreditAttribution: Bojhan commented1. That sounds good.
Comment #88
Wim LeersVoila, done!
Comment #89
Bojhan CreditAttribution: Bojhan commentedComment #90
larowlanI think the standard is to use "" when the string contains a '
field_info_instance is deprecated, use Drupal\field\FieldInfo::getInstance() instead.
Does this work if Drupal is installed in a subdirectory?
Comment #91
Wim Leers#90:
file_create_url()
, as it should!Comment #92
Wim LeersJesse Beach found a huge bug.
Comment #93
Wim LeersIgnore #92, this bug is not being introduced here, but was introduced in #1879120: Use Drupal-specific image and link plugins — use core dialogs rather than CKEditor dialogs, containing alterable Drupal forms. Opened a new issue for that: #2071957: Cannot change existing images or links through Text Editor's image/link dialogs.
Comment #94
webchickUI before:
The only way to reference an image is via copy/pasting a URL. So my workflow is:
1) Type some stuff into the WYSIWYG editor.
2) Try and add a picture.
3) Go "(*&(@#" because I don't have a URL to the picture I want. :P~
4) Close the dialog, scroll *up* to "Image" and hit "Browse..."
5) Select the picture from my desktop or whatever.
6) Click upload.
7) Right-click to copy the URL.
8) *Re*-click the "add picture" icon in the WYSIWYG editor.
9) Paste the URL.
10) Click save.
Annoying.
With the patch:
Steps:
1) Type some stuff into the WYSIWYG editor.
2) Click the "Add picture" icon.
3) Hit "Browse..."
4) Select a picture from my desktop or whatever.
5) Click "Save."
Muuuuuch better!
Oh. Except for:
Wah-Wah. What happened there? I assume this has to do with the "secure image" filter (or whatever it's called) that's enabled on Basic HTML, because it works on Full HTML, albeit with the following errors:
That's a pretty big deal, so needs work for that.
A few code-y things, though I'm running out of steam atm so this might not be everything...
Sorry, docs gate. We can't let this patch go in without this.
Typically we don't smooshwordstogether. Is this a CKEditor convention? If not, "drupal.image" or "drupal-image" would be better.
AFAIK this should be using the new FormBase class now.
Comment #95
Wim LeersI tried everything I could think of and could not reproduce this. Furthermore, this has test coverage, and zero exceptions are raised there (I tried again locally).
If you're still seeing this, please provide steps to reproduce.
No.
Whomever introduced
hook_entity_revision_delete()
(it is NOT being introduced in this issue) just forgot to add it toentity.api.php
. There's another hook in there missing a detailed example. It's not my responsibility to come up with a nice example that's consistent with the rest. I just wanted to make sure we don't forget to do it in the future. The alternative is to just remove this hunk.The plugin names already are "drupallink" and "drupalimage" in the directory structure, so if we want to change this, that's out of scope.
No.
FormBase
/FormInterface
are for "full", "stand-alone" forms, with their own validate and submit handlers. This is not a full form. It has no validate and submit handlers of its own This is a subform that other forms may embed.DrupalImage::settingsForm()
embeds it.From #38:
Comment #96
Wim LeersSince none of the criticism in #94 seems to be accurate or reproducible, setting back to RTBC.
Comment #97
BerdirThat's the line. array_diff() only works on arrays that only have scalar values. PHP 5.3 just silently casts arrays to the string 'Array' and compares that.
Comment #98
Wim LeersI'm on 5.3.18, so that'd explain it. Thanks!
Comment #99
Tor Arne Thune CreditAttribution: Tor Arne Thune commentedEDIT: Too late.
Comment #100
Wim LeersUpgraded to PHP 5.4, reproduced, fixed. Thanks again, berdir! :)
(The updated code makes more sense and it now puzzles me how this ever worked — but it did work! You're so weird, PHP.)
Comment #101
webchickHm. It's still showing a broken image to me once saving the node form. :(
Steps to reproduce:
- Apply the patch and drush si.
- Go to node/add/article.
- Enter a title.
- Click the image button on the WYSIWYG
- Browse to a picture from your desktop or whatever.
- Click Save. You'll see the image appear in the WYSIWYG editor.
- Click "Save and publish" on the form.
- Node page shows up and... red X.
Comment #102
webchickHowever, I can confirm that the notices are gone when I switch the text format to "Full HTML" so there's that. :)
Comment #103
Tor Arne Thune CreditAttribution: Tor Arne Thune commentedI could reproduce the notice earlier, but not the image not showing. It showed up for me.
Comment #104
webchick:(
And your input format is set to "Basic HTML"? (or whatever the default is?)
This fails consistently for me every time. I'm drush si-ing in between. Not sure what's wrong.
Comment #105
Tor Arne Thune CreditAttribution: Tor Arne Thune commentedI install with the interactive installer, so maybe it's a Drush issue with permissions on the files directory?
I go to Add content, Article, fill in title, fill in body, click the CKEditor image button, browse for a file (tried both with and without clicking the upload button before clicking save), click save in the dialog window, click save and publish.
Comment #106
webchickHa, ok. After some further debugging, this is the problem... #2076847: FilterHtmlImageSecure incorrectly flags images coming from site URLs with ports in them as insecure.
I guess I will have to take your guys's word for it that this works. :)
Committed and pushed to 8.x. Thanks!
Comment #107
Wim Leers#106: indeed, that's the cause of that problem!
And WOOT! :D
Comment #108
quicksketchYay, how exciting! :)
Comment #109
Wim LeersGlad to see a happy quicksketch in the D8 issue queue :)
Comment #110
slashrsm CreditAttribution: slashrsm commentedYay! Kudos to all who contributed to this patch!
Comment #111.0
(not verified) CreditAttribution: commenteda