I have a site using layout builder in which some elements are full width and others are not, due to the full width, we do not contain the region itself, it'd be great to have an option in the layouts where there could be an additional wrapper of the 'row' wrapper that allows the container class.
| Comment | File | Size | Author |
|---|---|---|---|
| #25 | row_container_and_wrapper.png | 24.76 KB | albertski |
| #25 | row_and_container_only.png | 14.96 KB | albertski |
| #25 | row_only.png | 10.9 KB | albertski |
| #23 | interdiff_21_23.txt | 1.31 KB | albertski |
| #23 | 3010952-bootstrap-container-23.patch | 47.88 KB | albertski |
Comments
Comment #2
b_sharpe commentedAdds a container option.
Comment #3
b_sharpe commentedAdded attributes for the section when a container is used so full width sections can have specific style before a container is applied.
Comment #4
m.abdulqader commentedGreat patch thank you.
Comment #5
chertzogWorks as designed. +1 RTBC
Comment #6
markhalliwellThis isn't just adding a "container", but also a "section".
I think this is a bit overkill. Or perhaps it's backward.
The layout/wrapper itself should be able to be the "section". Then the container should be just inside the layout/wrapper surrounding the regions.
Anything more seems like a site-specific requirement.
This should become
container_attributesand default to having acontainerclass inside it.Comment #7
b_sharpe commented@markcarver The scenario I'm trying to solve here is where you have multiple LB "Sections" in which some are full width and others are not. Since the module currently starts at the "Row" level, it is assuming you are either contained or not which doesn't allow for this, so we added a container.
The level ABOVE the container is needed so a user can add additional attributes such as a BG Color class (i.e. bg-primary) to the main section which is full width, and then still be contained before the row starts for the content. I think this is pretty common in design and not really site-specific.
Let me know your thoughts, I am happy to contribute here and would love to move this forward as we have multiple sites currently using this functionality.
Comment #8
markhalliwellSee #6.
Comment #9
b_sharpe commentedI'm not sure what you mean? My response in regards to #6...
How does #6 allow for adding attributes to the level above the container? I see this all the time with Bootstrap, where there are alternating sections of contained and not, many with the need to use utility classes in between.
For example, you can not currently achieve this with the module: https://codepen.io/bsharpe/pen/NVwymp
Comment #10
b_sharpe commentedContinuing in this direction until a better alternative is available. Patch adds the Class select to the section.
Comment #11
markhalliwellThe need for a new "section" element/wrapper is unnecessary.
Just add
<div class="container">inside the layout (which still needs its own attributes variable) that wraps the layout's regions.Then you can use the existing layout element and its attributes as what you're currently calling the "section".
Like I said in #6, you're doing this backwards.
Comment #12
b_sharpe commented@markcarver I understand what you are saying, but that's not how flexbox works.
From BS Docs:
So if we use the wrapper as the "section" then add a container, then we'd have to also add a row to wrap the columns. Either way, there are TWO more divs needed to do what we're trying to do here.
I agree it makes more sense to have better naming here, but you've already named "Wrapper" as what is the default row, so a patch changing that would mean a lot of confusion for existing users, and likely a migration of data in an update hook.
I'm wondering if this is almost best served as a rewrite for BS4? Like I mentioned I'm more than willing to help contribute here and move this forward, so let me know your thoughts
Comment #13
markhalliwellI see.
Regardless, anything we do here will need to be added inside the existing layout wrapper element.
For a BC approach, we should probably just introduce two new settings/UI toggles (
containerandrow), each named something like "Add separate container element" and "Add separate row element".Then create new attributes (
container_attributesandrow_attributes) and accompanying UI customization for said elements and attributes as if they were their own regions.Both of these customizations areas (likely additional vertical tabs) should only be shown if the relevant UI toggle is checked, thus this will need some
#statescode.I think that will give anyone the flexibility to do whatever they desire.
Comment #14
philyPardon me if I'm wrong but there is a difference between having a 'no container' wrapper or a 'container-fluid' wrapper: the latter has left and right paddings of 15px so the content is slightly away for the browser sides while the 'background' is still touching them.
So, shouldn't we have 3 options to choose from for the section class: nothing, 'container' or 'container-fluid'?
Comment #15
albertski commentedHi Mark, the attached patch provides configuration for enabling/customizing the following wrappers:
I added a checkbox "Add .... element". This way, you can configure and only enable to your liking. By default, it matches the current behavior of only adding the row element.
I know you mentioned earlier that we should reuse the existing layout element, but I wasn't able to figure out a way of adding nested elements into that one element so I created 3 separate elements in the template.
Let me know if you were thinking of going in a different direction?
Comment #16
albertski commentedComment #17
albertski commentedFixed issue with container items not displaying after save.
Comment #18
albertski commentedFound missing ending tags in the 1 column layout.
Comment #19
markhalliwellThanks for the patches @albertski! Awesome work.
A few questions and concerns:
This seems like a ton of more work than is necessary. Can we just return the entire array of the wrapper settings? Then, in the template, you can just use dot notation (e.g.
wrapper.enabled,wrapper.element,wrapper.attributes, etc.).I will say this again:
1) NestedArray cannot be used on attributes; classes have to be handled differently.
2) We need a helper method that extracts the layout settings and when it encounters a property named "attributes" or ends with "attributes", that it automatically converts it into an attributes array.
It could reduce duplication of this entire block of code down to just three lines; one for each: wrapper, container, row.
Why is this being changed from
divtosection?Why are these properties prefixed with the name of their parent? Isn't that the point of being able to nest arrays? I think there may be some confusion from when I originally suggested adding some additional properties, but they were just one or two at the root level. If we're going to nest them, there shouldn't be any need to prefix them too.
Comment #20
albertski commentedThank you for your feedback @markcarver. I have updated the patch to fix the items you pointed out:
1 - I went ahead and went that route of returning the entire wrapper settings like you suggested. I agree. It makes better sense.
2 - I removed the NestedArray call and verified classes/ids are getting added. Also, I created the helper method `_bootstrap_layouts_process_attributes()`.
3 - I went back to `div`. Not sure why I decided to go to `section` earlier.
4 - Good idea on removing the prefix. There was no need for prefixes, and in fact, I was able to reduce duplication in the form by creating the form elements in an array.
Comment #21
markhalliwellI started to make a lot of review comments but decided it may just be easier for me to do a little bit of the work to show what I meant. So here's a patch that helps clean things up a bit more.
Mind you, I didn't actually test this on a running instance, just relied on PhpStorm's inspections to catch any errors. Needs to be reviewed and tested on a real instance.
Comment #22
markhalliwellWhile we're here, we may as well rename the "wrapper" region variable to "element" as well (if only to not confuse things more).
https://git.drupalcode.org/project/bootstrap_layouts/-/blob/8.x-5.x/src/...
These "attributes" are now actually being ignored since it's using the "wrapper.attributes" in templates.
So... this is technically a breaking change. Which means I'll have to bump the major version of the project. I'm ok with for the most part, but I'm still a little confused as to why this is necessary.
This is what I meant above by the fact that it appears that the "wrapper" wrapper being added here is redundant, the layout settings themselves are there for the "wrapper" around the regions.
Comment #23
albertski commentedThanks, @markcarver. I took a look and tested and everything looks good. I had to make one minor fix:
$value->value()instead of$value->getValue(). Also, on form submission I had some prefixes left over that I cleaned up.I'm currently using this in Layout Builder, and I always run into cases where one section needs to be edge to edge and one section that needs to be in a container. With the current implementation (prior to the patch), you don't have that ability and only are stuck with whatever your entire page layout is set to.
If you are okay with going forward, I think we can proceed with renaming the wrapper to element for regions.
Comment #24
markhalliwellAh, great catch!
That's what this extra container (and row) wrapper is supposed to be for. You can put the container class on one and not the other. If you need to style the element around that, you should target whatever the layout is actually in.
Layouts (in this sense) aren't typically supposed to be root-level components; there's always some sort of low-level element that encompasses them (entity, view, paragraph, field, block, theme region, whatever...).
I'm still not convinced having, potentially, 3 wrappers for every single layout is an absolute necessity. This is already bad enough with 2.
The only real reason I'm even considering the two (container and row) is mostly due to BS3 restrictions in its overuse of child and general/adjacent sibling combinators. Even BS4 (and soon to be BS5) have reduced the number of elements necessary with the advents of CSS (flex/grid).
If anything, I would argue that the majority who think of this as "needed" could just as easily redesign or improve it through discovering more modern CSS functionality.
I'm sorry, but given that cases of divitis are seemingly a neverending battle, I really don't want to help it come back if I can actively prevent it.
The goal of any project on d.o should be to provide quality code and the ability to extend it.
I'm looking at this with targeting the 99.999% of use cases.
On the off chance, if someone really believes (or even proves) that they need a 3rd or 4th wrapper they can always create one in a module or theme. It doesn't mean we have to give people an easier way to shoot themselves in the foot out-of-the-box; those unique situations should be handled on a case-by-case basis.
Comment #25
albertski commentedIs there a way that we can have a container wrapper around the row div with the current implementation? I didn't think there was a way to do that.
Let me see if I can convince you why we need the three wrapper options.
Row Only Option
With the row only option (current implementation) we have to rely on the main page to add a container and then we would have to have every section be the same width.
Row and Container Option
Now we have more control and we can have some sections wrapped in a container and some not.
Wrapper, Container and Row Option
Now we have the flexibility to add styling outside the container like add a background color.
Let me know what you think?
Comment #26
markhalliwellAs I stated above, I understand the use cases for the first two; unfortunately unavoidable due to how Bootstrap works.
It's this third case (wrapper) that is redundant. Even with this use-case stated here, you used the word "like", implying this is still just a hypothetical "gain". The first two use-cases are based on actual requirements/restrictions of the Bootstrap framework and how it technically functions.
This hypothetical background can still be easily styled on the container it's in, whether it be a paragraph/field, block, theme region or whatever.
I'm also approaching this from years of experience where designers typically follow some sort of pattern. This usually means that if there is some variation, in say a background around an element, it's typically done so using numerated logic (i.e. first, last, odd/even, etc.). These can easily be targeted and coupled with modern CSS, allow an element to be styled as desired:
Note: the above is likely to have some flaws, I simply wrote it here off the top of my head from work I've done in the past. This concept, while still a rather extremely rare use-case, does work though.
If a more complex design truly requires the use of a 3rd (or more) wrapper around a single layout, then that is the time to create a custom layout to be used on a site. This also has the added benefit of reducing complications during upgrades as the layout was designed with a specific use case in mind and is siloed outside a generic module.
If we keep adding wrappers just for the sake of adding wrappers, this module runs the risk of being 1) too customizable and ultimately confusing and 2) Non-Bootstrap specific, which one could already argue could already be the case; especially with this issue adding even more variety.
Sorry, I'm still not convinced that a "wrapper" is necessary now that there is a container; it's redundant.
Also, these attributes are still being lost. They will need to be merged into the container now instead. We'll also need to add a caveat description to the form that indicates that disabling the container will prevent any attributes added to the layout (externally via a preprocess) from appearing.