Over the last few weeks I have been rebuilding a joomla website that was built with a pagebuilder using just core Joomla and the core Cassiopeia template. This wasn't for a client, it was just as an exercise to satisfy my own belief that you don't need a pagebuilder.
Every time that I see someone advocating using a pagebuilder with Joomla the hairs on the back of my neck stand up. For me it reminds me of the days when I built a website with frontpage or Dreamweaver. Every page is standalone, the performance can be terrible and it's unnecessarily time consuming when a client wants to update the content.
I was fully prepared to encounter things that would be a challenge to achieve but so far, I am about 80% complete, the biggest challenge has been to find a way to create full width modules inside content.
The problem being faced is that we can only insert a module inside the container of the content. In order to make the module (or its background) expand out of the container to fill the entire width of the page we will need to do a little more work. After a little research, I discovered it could be achieved by adding one div and a single CSS class.
Modules Inside Content
Including any module inside an article is easy to do. My personal workflow for this is as follows.
- Create the module I want in the normal way but put it in a custom named module position eg articlepraisequote
- Inside the article I use the CMSContent button and select module and then select the module to insert.
- Joomla will then insert a string that looks similar to { loadmoduleid 128 } and the selected module will be rendered in the article.
Custom Named Module Position
By using a custom named module position I can be confident that it won't be accidentally displayed on additional pages and I don't have to waste time assigning the module to a specific menu item - which if course is something that you can not do until after you have created the menu item.
Creating the position is something that is simple to do and very useful but its also not something you will usually come across in a tutorial. All you have to do is to go to the module position select box and type in the name of the position that you want to create and press enter. That's all - the module position is now saved - and as its not present in the template itself it will never be displayed except where you have specifically called it as above.
Styling the Module
There are a few different ways to style the module.
- add CSS classes to the module options
- create a layout override for the module
- create a new layout for the module
However all of these are specific to the module and I want to create the ability to add any module into the content and to make it full width.
Module Chrome (Module Style)
Before making any changes you need to understand the module chrome and the html markup it creates. Yes it's confusing two different names for the same thing. The User Interface calls it module style but the files are located in layouts/chromes.
In the most basic terms the module chrome is markup that wraps around the module. The objective behind the concept of Module Styles is to add a consistency to the display of any and all modules across the site. Most of the settings in the advanced tab that you will see when creating a module apply to the module chrome and not the specific module. (Unfortunately not all of these options are implemented in every chrome.)
Usually the chrome to be used is defined in the template for the specific module position and we never change it.
<jdoc:include type="modules" name="top-a" style="card" />
Joomla includes four module chromes and the Cassiopeia template has an additional two, card and noCard.
When you create a module the default setting is inherit which means it will use the style defined in the template for that module position but you can also manually select a different style from the dropdown.
As we are inserting the module into an article in a custom named module position there is no chrome defined for the position so if we leave it at the default setting no chrome will be applied.
Creating a Full Width Module Chrome
The existing Cassiopeia chrome noCard.php is going to be the cleanest to use as our base as it applies simple html markup and also implements all the options available for the module.
Using the template manager (or an IDE) copy the file templates\cassiopeia\html\layouts\chromes\noCard.php to templates\cassiopeia\html\layouts\chromes\fullWidth.php
After ensuring you are editing the newly created file change the markup by editing $moduleAttribs['class']
$moduleAttribs['class'] = $module->position . ' fullwidth ' . htmlspecialchars($params->get('moduleclass_sfx', ''), ENT_QUOTES, 'UTF-8');
and then adding an additional div with a class of container as shown below.
<<?php echo $moduleTag; ?> <?php echo ArrayHelper::toString($moduleAttribs); ?>>
<div class="container">
<?php if ($module->showtitle) : ?>
<?php echo $header; ?>
<?php endif; ?>
<?php echo $module->content; ?>
</div>
</<?php echo $moduleTag; ?>>
Adding the Full Width Module Class
A new class was added to the chrome and we now need to add the CSS for that class.
Using the template manager (or an IDE) create the file media/templates/site/cassiopeia/css/user.css - or open the existing user.css if you have already created it.
Now you should add the following class
.fullwidth {
margin-left: calc( -50vw + 50% + 10px );
margin-right: calc( -50vw + 50% );
max-width: calc( 100vw - 20px );
padding-top: 30px;
padding-bottom: 20px;
}
This CSS lets the module break out of the normal content width constraints and span the entire width of the viewport, such as full-width image banners, carousels, or other feature sections. The small margins ensure there is some spacing between the full-width element and the edges of the viewport, preventing it from touching the edges directly.
Putting it all together
- Create the module that you wish to insert in the content
- Add the custom position
- Change the Module Style from inherit to fullwidth
- Add a class or classes to the Module Class Suffix eg text-bg-primary text-center
- Insert the module into the content.