Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
In #2826690: [META] Add icons to paragraph types we want to add paragraphs type icons, thus, we need first to add a thumbnail/icon field to store the image.
Proposed resolution
Add the icon field, not sure if we should allow the user to select their own icons, in that case the demo module should also offer default ones.
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#85 | interdiff-2830016-82-85.txt | 1.36 KB | toncic |
#85 | add_a_thumbnail_icon-2830016-85.patch | 11.69 KB | toncic |
#82 | interdiff-2830016-80-82.txt | 1.13 KB | toncic |
#82 | add_a_thumbnail_icon-2830016-82.patch | 11.72 KB | toncic |
#80 | interdiff-2830016-77-80.txt | 892 bytes | toncic |
Comments
Comment #2
toncic CreditAttribution: toncic at MD Systems GmbH commentedComment #3
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded icon field for paragraph type. I can not set default icon because getIconFile() return null from unknown reason for me at the moment.
I need to fix that and add test coverage.
Comment #4
drobnjak CreditAttribution: drobnjak at MD Systems GmbH commentedComment #5
miro_dietikerThis is the implementation issue of the META about icons. Introducing icons is more than just add them to the types and then use them in the "add" widget. With other features upcoming, the META topic will grow and there are things that need discussion about the icon concept in general.
Comment #6
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixed problem with functionality, only need to write test coverage.
Providing screenshots.
Comment #7
pixelmord CreditAttribution: pixelmord at Wunder for Hubert Burda Media commentedI already mentioned in another issue that I really like the idea to have icons or similar to be able to visually identify the paragraph type.
However I do not like the proposal to mix content and configuration, because we would have a dependency between a content entity (the file entity for the icon/image) and the configuration (entity) which is the bundle. That rather bad for development and integration.
Could we just use that pattern that we have for the site logo for example, where you can provide a path? That way the might have to make sure that the path is valid for all environments, but it is still configuration and not content..
Comment #8
BerdirThis is done exactly like embed.module does it, and it works pretty well there. We're not the first to have content dependencies in config, views, blocks and other things have this too.
Providing default icons can be done with the default_content module for example.
Comment #9
Berdirincomplete label
this is not a button.
nope
lets make this protected
we probably want to have a generic fallback token.
We also need a calculateDependencies() method.
Another note on #8/7. We will need to figure out how to support default icons, and while I can imagine we could add a path setting too, it won't really help without having support for module:// stream wrappers as we can't hardcode the path to files in the module, so we still need to copy them to the public folder and then we can just as well make them managed.
We should also register usages of those icons using file_usage service.
Comment #10
miro_dietikerUsage: Yeah what i have seen is that usage was still temporary, so it would be deleted on cleanup cron.
Are we going to handle the default icon complexity in a follow-up?
Comment #11
BerdirFine with doing that in a follow-up. We can already do something like have a file in the module, copy it to public:// and save as a file entity, then reference it. For the demo module, for example (which we can also do later, since we don't actually use the icons yet anyway)
Comment #12
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded test coverage and implement comm #9. Created follow -up from #11
Comment #13
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded calculateDependencies(). Now is ready for review.
Comment #14
toncic CreditAttribution: toncic at MD Systems GmbH commentedCleaning patch.
Comment #15
johnchqueCan we use the EntityTypeManager here?
This test is not related with preview. Let's move it to ParagraphsTypesTest
Comment #16
toncic CreditAttribution: toncic at MD Systems GmbH commentedMove test in ParagraphsTypesTest and added dependency for file module.
Comment #17
BerdirDoesn't look you tested this because that's now how install() works.
you still use entity.manager.
Comment #18
toncic CreditAttribution: toncic at MD Systems GmbH commentedImplemented comm #17.
Comment #19
BerdirI'm not seeing any test coverage that the icon is displayed on the overview.
Comment #20
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded test case to check if image is presented in list builder. I am asserting if alt attribute is presented, so img element is also presented. I hope that this is enough.
Comment #21
Ginovski CreditAttribution: Ginovski at MD Systems GmbH commentedI'm getting 2 info messages, is this correctly set?
is*
For image assertion, try to get the path of the image and then assert it.
Maybe something like this example I found:
Comment #22
miro_dietikerThat's far from the expected use of the icon.
The recommended format should be SVG.
And the add widget will display those icons in a way bigger element than 32 pixels.
We might display it downscaled to a tiny size in buttons, but that's IMHO not relevant and should not go through an image style as SVG need to stay vectors IMHO. Not sure how to properly limit / define the requirement / validation in the UI.
Hint: Also Thunder wants to display the icons bigger in the preview / collapsed paragraph, see #2828110: Sorting of paragraphs 03 - create a NEW paragraph "in place" between existing ones
Comment #23
BerdirI'd say don't limit the resolution to start, we can always add code to automatically downsize like image fields support when we know how we use the icons and how big they're displayed?
Comment #24
toncic CreditAttribution: toncic at MD Systems GmbH commentedI removed resolution validation and now is looking very bad, and also changed the file extension validation to be on 'svg' but still we can upload other types like png. jpg and so on.
Providing screenshot.
Comment #25
miro_dietikerYeah. That looks bad, but the image you uploaded as an example is also highly confusing. ;-)
I'm not sure about column sequence.
We will usually display Icon + Label. It might be best to start the row with an icon column prior to the label.
What also confuses me is the column "PARAGRAPHS TYPES". That should simply be label.
Comment #26
toncic CreditAttribution: toncic at MD Systems GmbH commentedHardcoded width and height for image to scale automatically, and also added css to decrease the width for column where is a icon.
Now is looking better. Also changed the order of column.
Providing screenshot.
Comment #27
johnchqueAs discussed change the class of the icon.
Comment #28
BerdirComment #29
toncic CreditAttribution: toncic at MD Systems GmbH commentedChanged css class name for icon field.
Comment #30
miro_dietikerFrom the image above i can see that the icon adds some padding below and that's why the padding / white room is not balanced.
Please check the vertical paddings / margins and adjust them.
Comment #31
toncic CreditAttribution: toncic at MD Systems GmbH commentedCentering image.
Comment #32
toncic CreditAttribution: toncic at MD Systems GmbH commentedChanged indentation in css.
Comment #33
toncic CreditAttribution: toncic at MD Systems GmbH commentedAfter discussion with Sascha and Ivica we deal to do on this way.
Comment #34
johnchqueLooks good.
Comment #35
gpap CreditAttribution: gpap at Brainsum for Tieto commentedFixed the last patch, as it failed for me in src/Form/ParagraphsTypeForm.php, at line 73. Patch #33 has this:
if ($behavior_plugins = $this->paragraphsBehaviorManager->getDefinitions()) {
As opposed to this (8.x-1.x-dev):
if ($behavior_plugins = $this->paragraphsBehaviorManager->getApplicableDefinitions($paragraphs_type)) {
It was changed here: http://cgit.drupalcode.org/paragraphs/commit/?id=7aaa294ec7284daebe4eb3d...
I could not create an interdiff as #33 breaks, but I fixed this line,
a typo and removed an extra space.Comment #38
miro_dietikerCan't stay at RTBC without interdiff or another review by someone.
Comment #39
gpap CreditAttribution: gpap at Brainsum for Tieto commented@miro_dietiker
The only difference between patch #33 and #35 is this line:
if ($behavior_plugins = $this->paragraphsBehaviorManager->getDefinitions()) {
to this:
if ($behavior_plugins = $this->paragraphsBehaviorManager->getApplicableDefinitions($paragraphs_type)) {
Ran with
$ diff add_a_thumbnail_icon-2830016-33.patch add_a_thumbnail_icon-2830016-35.patch
command.Comment #40
tduong CreditAttribution: tduong at MD Systems GmbH commentedNow this needs a reroll as there is a conflict in ParagraphsTypeForm. Just tested if the patch works otherwise: not sure if I'm missing a step, but after enabling paragraphs_demo (on a clean env), applying the patch and then running drush updb, it gives me the following exception:
Comment #41
toncic CreditAttribution: toncic at MD Systems GmbH commentedRebasing patch,
@gpap:
That is fixed in some previous patch.
@tduong:
For me works fine, I can't reproduce that error.
Comment #42
toncic CreditAttribution: toncic at MD Systems GmbH commentedRebasing again, experimental widget are committed.
Comment #43
johnchqueLet's organize this.
Comment #44
miro_dietikerNo, the icon field will be there always and affect every Paragraphs user.
We will only use the field in the experimental widget, but that's a different issue.
Comment #45
jeroen.b CreditAttribution: jeroen.b at .VDMi/ commented@miro_dietiker, what do we need to do to get this in?
Comment #46
seanBUnrelated change, but I agree this should be done.
This is weird, the getDependencies method is now responsible for adding dependencies. Should this not be calculateDependencies?
Do we really need to add these to
ParagraphsTypeInterface
andParagraphsType
?calculateDependencies
is already inConfigEntityInterface
.getIconFile
andgetIconUrl
contain very little code, having extra methods to return these oneliners seems kind of pointless?Comment #47
miro_dietikerThis is already part of ConfigEntityInterface.
Comment #48
miro_dietikerNow that the release is out, this should be the next step to unlock use of icons.
Comment #49
seanBThis should be file_validate_extensions
This doesn't apply? Not sure why but we should check that.
Besides that there is an issue with the configuration. The uuid for the file is exported, but the file it is actually linked to isn't. This way you get a broken icon after a release.
This makes me think about the whole approach of using file uploads for this. I guess this is done so you don't have to write code to get a icon? But now you need to know where to find icons, and somehow match them to the admin theme you are using. Even if we find a way to deploy icons, uploading icons for each paragraph type is not a very friendly way to do this.
We've had a short discussion here at the paragraphs sprint and came to the following conclusions:
I guess we should now discuss what the best way is to move forward.
Comment #50
seanBAfter discussion at the paragraphs sprint with jurcello, sutharsan and marcvangend we came to the following proposal.
What we need at a minimum:
How can we do it:
Example of [module/theme name].paragraphs.icons.yml:
Comment #51
seanBCopy/paste from Slack:
-----------
sutharsan
@seanb I do not understand “… + the icon with the heighest weight (can be module or theme).” in "We add a configuration settings for a icon base dir (can be set from the interface like media entity) and copy all theme icons to the base dir on discovery + the icon with the heighest weight (can be module or theme).”
@seanb About "We change icon names with the module/theme name in the icon base dir like [icon name].[theme].[extension]. The heighest weight is just called [name].[extension].”
I think that you should explain that we want themes to be able to override base theme(s) and modules. But also allow fallback if the (final) theme does not provide an icon.
seanb
@sutharsan I can see how this might be confusing. Since multiple modules/themes can implement icons with a specific name, the proposal is to only care about the current theme, or the icon with the highest weight as a fallback. Hopefully copy/pasting this to the issue is a good explanation.
------------
As far as we could see, module/theme icons with lower weight/importance will not be used. Copying/returning/caching those seem pointless. We could off course be missing some edge cases here, so please let me know if there are examples where this could lead to undesired results.
Comment #52
miro_dietikerThank you for the proposal and discussing this at the NL sprint.
The proposal has a key problem: It adds huge complexity to handle a managed overridable set of icons. That dimension of complexity is a bad sign for an approach. If this doesn't exist yet, it should be introduced by a dedicated module (there is also project icon!) and otherwise we should focus on a minimum approach.
Using a file field is IMHO a much better start to iterate. It is simply available and users could start to upload icons. Then we could deal in follow-ups with...
- Providing a default action by code as a fallback for module shipped paragraph type
- Alter the widget to a predefined selection list (consider icon providers?)
- Support exporting references so that the icon is transported in export / import
I believe all these problems can be solved on top of the "icon as content" approach we proposed.
I'll pass the ball to Berdir to provide feedback too.
Comment #53
BerdirYes, this solution isn't perfect, but it's based on the embed.module and I agree that it is a useful starting point.
We can still add a separate field for a filename or selecting from different provided default icons later on. That's exactly why those getIconUrl() and so on methods are important and must be kept, because they can then deal with those additional options without making the public API more complicated.
Deploying content is a problem, but this one case of many and it needs a better general solution. Fabian Bircher actually mentioned that he is working on a module in his session at the mountain camp (https://drupalmountaincamp.ch/sessions/configuration-management-without-...) and that he will release something soon.
Comment #54
toncic CreditAttribution: toncic at MD Systems GmbH commentedSwitch to use calculateDependencies() instead of getDependencies(), that was my fault. Added test for calculateDependencies(). I agree with @Berdir that this is enough for starting point. Other stuff we can do in follow-ups.
Comment #55
johnchqueLet's create the follow-ups and get this in. :)
Comment #56
seanBI think we are almost there. It would be nice to link the follow-ups to remove the file field and replace it with some better way of selecting icons. We can at least continue the discussion about it in the other issue.
At least the SVG validation should be fixed.
I think this should be file_validate_extensions.
Nit: Is this just for buttons? Maybe we just remove the word button here.
Nit: TRUE if the plugin is enabled, FALSE otherwise.
Comment #57
miro_dietikerBTW i had the idea of a paragraph type "separator" in the collection that has a related problem:
#2854358: [META] Fundamental Type: Separator
Similar to icons, we could offer a selection of vector separators that a user could choose. Thus, we would need a similar provider / selectioin.
One difference though: Icons should primarily be chosen due to their meaning / semantics. The separator is likely being selected only because of its appearance.
Comment #58
toncic CreditAttribution: toncic at MD Systems GmbH commentedSmall changes from #56 and created follow-up #2854585: Improve icon selection in paragraphs type form.
Comment #59
toncic CreditAttribution: toncic at MD Systems GmbH commentedForgot to set on needs review.
Comment #61
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixing test failing.
After discussing with @Berdir added jpg and png as file extensions.
Comment #62
seanBThis is a small typo, but I think this can be fixed on commit. Nice work, RTBC!
I will create a follow up to discuss any improvements as suggested in #50.
Comment #63
toncic CreditAttribution: toncic at MD Systems GmbH commentedI already created one issue for discussing. Here it is : #2854585: Improve icon selection in paragraphs type form.
Comment #64
miro_dietikerSmall things, plz fix.
The keys don't match, but they should.
Does this distort the image if it is not square?
Too repetitive on table. The label is output separately. So for best accessibility this can even be an empty "".
https://www.w3.org/WAI/tutorials/images/decorative/
Comment #65
toncic CreditAttribution: toncic at MD Systems GmbH commented2. Yes.
Fixed stuff from previous comment and convert css into sass.
Comment #67
toncic CreditAttribution: toncic at MD Systems GmbH commentedFixing test failing.
Comment #68
johnchquedoes the image have a class img? I think you don't need the "."
Comment #69
toncic CreditAttribution: toncic at MD Systems GmbH commentedYou are right.
Comment #71
toncic CreditAttribution: toncic at MD Systems GmbH commentedOps, that was wrong patch.
Comment #72
tduong CreditAttribution: tduong at MD Systems GmbH commentedHere some feedback :P sorry for being too pedantic...
This doesn't break the 80 chars length rule, so you can do this in one line.
"... if a ..." not "an".
and "... UUID is specified."
Typo, but I would write "Paragraph type's icon." or even remove it since it doesn't say anything more useful than its title.
Better something like "Set the file UUID to the paragraph configuration."
Just save it, no need to assign it to any variable.
".. entity."
"The icon's file entity."
"Returns the icon's URL."
Copy/paste from EmbedButtonInterface.. Remove these lines since you don't provide any else-case.
"The icon's URL."
"Tests the paragraph type icon settings."
I wouldn't create a variable just to use it once.
If you are not going to check anything between the paragraph types overview and the add form, then just do drupalGet('admin/structure/paragraphs_type/add').
"Check if the icon has been saved."
"The alt attribute and image tag should be present."
But you should make it clearer in your assert that you are checking both alt and image tag values.
Not necessary. You are already on that page.
Comment #73
toncic CreditAttribution: toncic at MD Systems GmbH commented@tduong:
1. This is optional, sorry but I prefer like this.
2. This is debatable.
3. Typo?
Comment #74
tduong CreditAttribution: tduong at MD Systems GmbH commented2. it is "a UUID" and not "an UUID", see here the explanation/example ;)
3.
The typo that you've fixed, but again, this description doesn't say anything more than the title. There is even an issue to #2849207: Drop redundant descriptions.
12. and 13. are not addressed yet?
Comment #75
toncic CreditAttribution: toncic at MD Systems GmbH commented12. IMHO it is more readable like this and if I put in one line, there will be more than 80 characters.
Comment #76
Primsi CreditAttribution: Primsi at MD Systems GmbH for MD Systems GmbH commentedWe should have $this->entityTypeManager() here, should we use ...->getStorage('file')->loadByProperties() instead?
Same as above.
Also, do we want to add some of those icons to demo paragraph types? Maybe can be done in follow-up
Comment #77
toncic CreditAttribution: toncic at MD Systems GmbH commentedI hope this is what you mentioned.
Yes, would be nice if we add icons to paragraphs type in demo content, there is an issue #2860212: Add icons to paragraphs type in demo content.
Comment #78
toncic CreditAttribution: toncic at MD Systems GmbH commentedCorrect interdiff.
Comment #79
Primsi CreditAttribution: Primsi at MD Systems GmbH for MD Systems GmbH commentedNo need to count, empty arrays validate false. Also IMHO we should return FALSE here if we don't find a file. And the inteface docblock should be updated accordingly.
Comment #80
toncic CreditAttribution: toncic at MD Systems GmbH commentedYes, you are right.
Comment #81
tduong CreditAttribution: tduong at MD Systems GmbH commentedA few things:
Don't assign to any variable if you just want to return it.
If getIconFile() else-case returns FALSE, shouldn't this method return FALSE as well?
"The icon's URL, FALSE if no icon file is found."
EDIT: and needs a reroll
Comment #82
toncic CreditAttribution: toncic at MD Systems GmbH commentedMade changes from #81.
Comment #83
tduong CreditAttribution: tduong at MD Systems GmbH commentedJust a small thing:
Rethinking about this, I would just create
$files = [];
and do a single return line likereturn $files ? array_shift($files) : FALSE;
Comment #84
Primsi CreditAttribution: Primsi at MD Systems GmbH for MD Systems GmbH commentedWhy are we setting/saving stuff in validate()? Is there a reason we don't do this in save()?
If we also return FALSE, this should be reflected here.
Same here
Also we could open a follow up to discuss how we should output the icon as mentioned in one of the comments. We just output the full size now.
Comment #85
toncic CreditAttribution: toncic at MD Systems GmbH commentedImplemented comm #84 and created follow-up #2863592: Change how we output the paragraph type icon
Comment #86
toncic CreditAttribution: toncic at MD Systems GmbH commentedComment #88
Primsi CreditAttribution: Primsi at MD Systems GmbH for MD Systems GmbH commentedCommitted, thanks to everyone!
@toncic Could you open a follow up issue in paragraphs collection for that too?
Comment #89
toncic CreditAttribution: toncic at MD Systems GmbH commentedAdded some follow-ups.