Problem/Motivation
Sometimes we need different amount of paragraphs per language.
Proposed resolution
Instead of making the paragraphs field translatable, we could implement a Plugin, that makes it possible to restrict the visibility of the paragraph for each enabled language.
Remaining tasks
Create the plugin.
| Comment | File | Size | Author |
|---|---|---|---|
| #76 | new_plugin_visibility-2846682-76.patch | 16.21 KB | VladimirMarko |
| #76 | interdiff-2846682-73-76.txt | 2.22 KB | VladimirMarko |
| #76 | new_plugin_visibility-2846682-76-test.patch | 5.36 KB | VladimirMarko |
| #43 | Select2 nonsense.png | 16.4 KB | VladimirMarko |
| #32 | Chrome trouble.png | 51.49 KB | VladimirMarko |
Comments
Comment #2
thenchev commentedLooked at this, this morning. Not sure how complex this can get but here are some ideas. *Not tested*
1. In the global configuration choose what languages should be allowed. Multi select widget.
2. Expose the allowed languages in behavior form so user can select on what languages this paragraph should be visible on. Multi select or maybe check boxes?
3. In view restrict access to the paragraph with #access when the current language doesn't match the user selected ones.
Comment #3
megadesk3000 commentedAlready started implementing it. Will provide a first draft as soon as i find time.
Comment #4
primsi commentedIt would be great if you could post the wip patch here given that the specifics are still a bit foggy :)
Comment #5
miro_dietiker@dencev
1) Drupal maintains a site language list as configuration. All languages defined there will be relevant. We don't need additional configuration.
2) Defining this logic is the challenging part...
The default is to show all languages in Drupal. It would be better to select the ones that hide it. But negative checkboxes are a UX antipattern.
Compared the problem with the core proposal for block visibility: #2284687: Redesign UI for better management of block visibility
We think we should output
- A fieldset "Visibility per language" from the plugin
- A checkbox with 3 values: - Always - / Hide on / Show on
- A Select2 box that allows a user to easily pick some of the languages defined. This control is hidden if the checkbox before is on "- Always -"
The Select2 library is not yet used in core. We could also start with checkboxes only.
Comment #6
berdirLanguages
[ ] DE
[ ] FR
[ ] EN
Select languages to limit visibility. Visible for all languages if none are selected.
Not very fancy, but that's IMHO the standard pattern, and you can either implement that as a plugin or simply as a normal entity reference field to languages. If plugin, you could also include a switch to "Check to exclude" vs "Check to show", that's also sometimes helpful if only a few languages should be shown.
And then a bit of hook_entity_access().
Comment #7
miro_dietikerIt's likely you want to enable this behavior on many paragraph types if you need it... And the proposal above tried to find a way to not clutter the UI with checkboxes when you have many languages.
Comment #8
thenchev commentedI have some working example but need to do some injections, coding standards, remove some hardcoded values...
Went with select2 route. Made a plugin. On one image is the selection of languages, I'm displaying all languages but have optgroup in select to first show languages that are enabled on the website followed by all the others that are defined in drupal. Not sure about that, I can remove it if its not useful.
Comment #9
thenchev commentedOr do we want to skip select2 untill in core?
Comment #10
thenchev commentedHere is first draft, needs test, will cover that if the approach looks ok.
Comment #11
miro_dietikerIMHO we should convert the radio selection to a drop down. We want to see as few elements as possible in the UI.
Then the dashed notation is OK. (We typically don't use such a notation with radio boxes.)
Comment #12
thenchev commentedQuick update: changes radios to select.
Comment #13
miro_dietikerA UI update needs updated screenshots.
No. We don't need to do language discovery.
We just need to list the INSTALLED languages. Content can only exist in these languages.
We can also exit if visibility isn't set at all.
Comment what we do with this logic here.
Why on child level and not on current build level?
Also, Zero documentation, Zero test coverage, Zero examples.
Tests are always critical for new functionality.
Definition of done is also to have demo extended with every plugin and a feasible example.
Comment #14
miro_dietikerThis plugin will need to provide a summary for the collapsed display.
Such as "Hide on German" or "Show on French".
Comment #15
hoebekewim commentedI have some usability remarks about this solution:
If I understand correctly, this will force us to create all paragraphs inside a field. Then selecting which paragraph should be shown in which language.
If you do this, you will get a huge list of items per field on large websites (think about international websites that have a lot of languages), making the node edit form unusable. Even with 2 languages it would already become messy.
A node that is created in a certain language should not contain content from another language, unless the field is set as a non-translatable field, making the content be shared among the created language variants, and making it non-language dependent field.
Also think about the people that use this module as a page builder, the overview will completely be lost.
Further we also have to take into account that international websites a lot of times require a user to only be able to manage the content for a certain language.
By using this approach, this becomes impossible.
Further, this solution does not follow the default Drupal workflow for fields.
I suggest to reconsider the usage of the "Users may translate this field" checkbox on a field to localize a paragraph. This is the most logic solution in the eyes of Drupal best practice.
Comment #16
miro_dietiker@hoebekewim Thank you for your feedback!
IMHO Your inputs are not related to the use case we are addressing with this plugin.
This plugin is not intended to create content that highly varies per language.
It primarily is to suppress a paragraph for a certain language, for use cases where things overlap to >90%.
In these cases, managing separate entities in separate UI contexts leads to disconnect and losing overview.
BTW if you really need content that varies highly (such as in commerce and regionalization) you can always create multiple nodes and limit their visibility by region. Then you have your wanted independent management.
I'm not rejecting the original requirement: The translatable ERR field still makes sense, but it's a huge leap in UX and user awareness. We currently still need to define the next leap in the experimental Widget UX. Once we are there, we can investigate more about multingual UX.
This plugin is just one option more to approach the problem.
We should possibly explain the use case in its description and even put a warning.
Comment #17
VladimirMarko commentedComment #18
miro_dietikerLet's get this done with the fixes in #13
The plugin should only be available if the system has more than one language enabled.
Let's create a follow-up to make the demo multilingual and add a nice use-case for this plugin.
But we will need a mulilingual test for the plugin as part of this issue.
Comment #19
VladimirMarko commentedProgress thus far.
Everything except for the demo works.
Will move all demo content into
paragraphs_collection_demo_installand make use ofisApplicabletomorrow.Comment #20
miro_dietikerComment #23
VladimirMarko commentedDiscussed with Miro.
initialise placeholder with jquery from #description and hide the original description. Example from select2:
// @todo incomplete.
Should be on a separate line.
Write @todo on separate line and describe what to do.
Drop this description.
Set a variable and check that. Loop once to set the access.
Comment #24
VladimirMarko commentedProgress for today.
Some JS improvements.
Demo still needs more work.
I don't see how to activate a behavior plugin for a paragraphs type from
paragraphs_collection_demo_install. I would like some feedback on that, @Berdir.Comment #27
primsi commentedDo you mean how to enable a certain behavior on a specific paragraph?
$grid_paragraph->setBehaviorSettings('grid_layout', ['layout' => 'paragraphs_two_column']);And save it.
Comment #28
berdirThat's configuring one that is enabled. Enabling one is on the paragraph type.
You can see how that's done in \Drupal\paragraphs\Form\ParagraphsTypeForm::save(). get the behavior plugin, set at least the enabled key in configuration, save the paragraph type. That's it.
Comment #29
miro_dietikerDiscussed JS implementation and it seems we were on the wrong path.
We can simply set a static placeholder text in the select2() initialisation...
We should not use JS to show / hide things. We have states for this.
Also, we should not set width in JS initialisation. We should always try to do this with CSS.
An own type for "language" is a bad example. You better enable the Language plugin on the normal text paragraph type or some other demo type.
Comment #30
VladimirMarko commentedThe demo works now.
Added a
README.txtto document how to set up the needed Select2 library.Comment #31
miro_dietikerSee my comment above.
Comment #32
VladimirMarko commentedReplaced the JavaScript with CSS, as requested.
Looks pretty and works fine on Firefox.
Doesn't work well on Chrome as the screenshot show.
Specifically, if the paragraph is saved with visibility at "- Always visible -", the edit form is loaded with the language selection hidden. This confuses the "smart" Select2 JS which sets the input element width by the style attribute to a default (
style="width: 100px;").Comment #34
primsi commentedThis needs a re-roll first.
Comment #35
VladimirMarko commented@Primsi: Here you go.
Comment #37
primsi commentedThis needed another reroll. Also some additional feedback:
We have an issue for the readme file, that will add the missing information. As for select2 I would prefer to have the instructions here (where to download it and where to put it).
If those are language codes, core normally uses langcode (pl. langcodes).
Please add a follow up to provide a hook_library_info alter. See https://github.com/drupal-media/dropzonejs/blob/8.x-1.x/dropzonejs.modul...
Is "Language" descriptive enough? Maybe "Visibility per language"?
We could make visibility values constants.
Is there a reason for this ids and classes to be that long?
Comment #39
primsi commentedObviously already needs another :S
Comment #40
miro_dietikerComment #41
toncic commentedI will take care of this.
Comment #42
VladimirMarko commentedI have time for this now again and @toncic doesn't. Taking over.
I would still like some feedback on the issue with Chrome and Select2.
Comment #43
VladimirMarko commentedImplemented the changes @Primsi asked for.
The Select2 select box width is still wrong. Upon further inspection, it doesn't in any browser. I don't think this is doable without JavaScript.
Comment #44
VladimirMarko commentedComment #47
VladimirMarko commentedComment #48
VladimirMarko commentedComment #50
miro_dietikerThis indirection is not needed in a script language like PHP where you can use strings for values. For instance, it makes debugging harder: i always need to lookup the const to understand what string value in the stacktrace means what const.
See, we are simply using 'hide', 'show' string states.
Comment #51
VladimirMarko commentedAlright. Deleted the constants again.
Also, there is now a follow-up issue for the Select2 select box width problem: #2859251: Visibility per language Plugin: Select2 select box has a wrong width
Comment #53
miro_dietikerCombining this plugin with other plugins like Accordeon or fixed grid results in a severe problem.
The position of each paragraph defines its role - this allows us to flatten the hierarchy and improve the UX. We thought it's a good idea.
Conditionally removing an item results in a shift, making the editing user unaware of the situation or even validation wrong (we wanted to validate child count in grid and accordeon).
There are two possibilities:
a) The plugin is considered incompatible with plugins that have fixed functional / layout expectation based on delta positions.
b) We will never do the delta based role approach (and change how grid, accordeon works!)
c) In situation where deltas impact the child role, only allow special rules with a fallback and offer a special container for this behavior. Example: A personalised special case always has the default fallback. A language specific paragraph in a grid needs to define an unspecific fallback...
Fun stuff to resolve. :-)
Comment #54
badrange commentedBased on miro_dietiker's coment in #53 it doesn't seem like it is a good idea to start using this patch in a real project right now.
Any idea about timeframe? Can we expect this approach to be pursued further?
Comment #55
miro_dietiker@badrange Any funding of features such as this plugin would help to provide any timeframes.
We are only projecting timeframes if features are directly funded by projects.
Still prioritising up, because multilingual requirements are recently discussed more.
Comment #57
VladimirMarko commentedRe-roll.
Comment #58
primsi commentedComment #60
primsi commentedWhat if we limit the applicability of this plugin to just a certain set of paragraph types in config for now?
Comment #61
VladimirMarko commentedFixed the test. (There is a new permission required for editing behavior settings.)
Comment #62
miro_dietikerSo we should document in the layout plugin that it fits very well to row containers and individual content paragraph types. But if the parent is a container that applies to children semantic roles based on delta, it doesn't fit. We can't avoid this as we don't know which paragraph type acts like that.
Containers with a grid layout with fixed child modulo count do not fit. "Equal distributed" layouts would be ok.
We tried to avoid this pitfall for other applications such as an accordion where we added a accordion item with title and body child field instead of (odd/even) delta roles. It is a level of nesting more, but it is easier to apply constrains to limit what is allowed as title and UX is also better.
Lets get this in and then create a follow-up to avoid wrong selections by the user with better validation for the special cases.
Comment #63
primsi commentedOk, let's update README
Comment #64
miro_dietikerDon't forget to update the plugin description, so people are aware of the limitations in the plugin UI.
Comment #65
VladimirMarko commentedI have tested this with children of a Grid paragraphs type and I haven't seen any problems with any layout - whether fixed row length or "equal columns". There was just a hole in place of the invisible paragraph in each case.
Comment #66
VladimirMarko commentedStopped loading the Select2 library, if it doesn't exist.
Disabled the behavior form for sites with only one language and added test coverage for that.
Updated README.md and the plugin's description.
Comment #68
VladimirMarko commentedComment #69
miro_dietikerAnd that's the problem. It's conceptually incompatible. It breaks layout expectations and it is misleading to the user.
Thus the recommendation is to NOT use per-language-visibility plugin in combination with a grid layout that has a fixed child count expectation. And that's what we need to document in the plugin description.
Comment #71
primsi commentedThis needs the sort of fix that we did here: #2887748: Update tests with the recent changes
Comment #72
miro_dietikerThis plugin highly demands for the tristate issue. It leads to clutter of all Paragraphs and likely slow-down of the Paragraphs UI due to the large amount of UI elements it outputs (and then hides).
Comment #73
VladimirMarko commentedFixed the tests analogously to #2887748: Update tests with the recent changes.
Comment #75
primsi commentedBerdir pointed out there, that adding published status is not necessary, because it defaults to that.
Comment #76
VladimirMarko commentedFixed the tests. And cleaned them up a little bit.
Before we test this again, let's wait until #2855309: Create ParagraphsTestBaseTrait. reverts the API changes it introduced by expanding the list of required parameters for some functions.
Comment #77
VladimirMarko commentedComment #78
primsi commented#2855309: Create ParagraphsTestBaseTrait. was merged.
Comment #79
miro_dietikerComment #80
VladimirMarko commentedIt's passing the tests now.
Comment #81
miro_dietikerOk to get this in as is. But we need a new parent meta issue that cares about improving the multilingual UI.
That will be improved summary, published translation status fields, filtering elements on output, filtering on the translate tab and many more. We will need to create a special round of mock-ups also to design the resulting UX goals and sync with the old "translatable err field" wishes.
And to avoid the ui overload/clutter, we really need to have the tristate thing and should promote it.
Comment #83
primsi commentedCommitted. Thanks. Leaving open until the follow ups from #18 #37 and #62 are created
Comment #84
VladimirMarko commentedCreated the follow-ups:
#2893023: Make Paragraphs Collection Demo multilingual and add a usecase for the Visibility per language plugin
#2893027: Make the Visibility per language plugin use a hook_library_info_alter for the Select2 libraries
#2893019: Prevent ugly UI caused by the Visibility per language plugin by restricting its usage in containers
Comment #85
miro_dietikerThe new META issue is lacking any reference.