PHP code for variable numbers of modules in a sing

2019-08-31 01:40发布

问题:

I am creating a Joomla 3.8 template from scratch using Bootstrap 4.0. At the same time I am teaching myself both Bootstrap 4.0 and PHP as I go along, so please bear with me.

Under the main component area I have a full-width position which I have called 'feature_bottom'. At the moment, I have two modules assigned to that position. On a wide desktop screen they are stacked vertically, each full width, but I want them to be side-by-side until the smaller device break points. On another menu item there might be three or four modules in that position, so hard-coding the column width for the modules doesn't work.

In my index.php I have this code in the body:

<?php if ($this->countModules('featurebottom')) : ?>                          
  <div class="container-fluid">
       <div class="row">
        <div id="featurebottom" class="<?php echo $featurebottom_width; ?> featurebottom">
            <jdoc:include type="modules" name="featurebottom" style="xhtml"/>
        </div>
       </div>
    </div>
<?php endif; ?>            

What I can't work out is how and where to tell the template that on medium plus screens if there are two modules in the feature_bottom position then they should be side-by-side with col-md-6 each, if there are three modules they are side-by-side with col-md-4 each, four modules col-md-3 each and so on, up to twelve modules spread over three rows of col-md-4 each.

I have tried this code above the head tag (only up to 4 modules for testing purposes):

<?php if ($featurebottom == 2) {
    $featurebottom_width = "col-md-6";
} elseif ($featurebottom == 3) {
    $featurebottom_width = "col-md-4";
} elseif ($featurebottom == 4) {
    $featurebottom_width = "col-md-3";
} else {
    $featurebottom_width = "col-md-12";
}
?>

... but nothing happens. The two modules are still stacked above each other.

What am I doing wrong?

The template can be viewed here: https://www.vanillasponge.co.uk

Update: 27.02.18

If I edit the page manually via a browser's Web Developer > Inspector and add the class 'col-md' after 'moduletable' (for each instance) I can get exactly the effect I want (see image).

Screenshot of manually adjusted modules

If I add " col-md" as a Module Class Suffix in the Joomla module Advanced Tab then it also (sort of) works, but a) it double indents the main content underneath the module title, and b) I don't want to have to do this manually, mainly because my somewhat less techy clients may have to use a version of this module in the future when their current Joomla templates are updated by me in the next 18 months or so in order to work with Bootstrap 4. I can't guarantee that they would remember to add a module class suffix.

回答1:

I think you are close, see if this works for you?

Count the number of module items in featurebottom

The Joomla method for this logic is countModules https://docs.joomla.org/Counting_modules_in_a_given_module_position

<?php if($this->countModules('featurebottom') == 2){
    $featurebottom_items = "two";
} elseif ($this->countModules('featurebottom') == 3) {
    $featurebottom_items = "three";
} elseif ($this->countModules('featurebottom') == 4) {
    $featurebottom_items = "four";
} else {
    $featurebottom_items = "one";
}
?>

Apply the class from above to #featurebottom

<?php if ($this->countModules('featurebottom')) : ?>                          
  <div class="container-fluid">
       <div class="row">
        <div id="featurebottom" class="<?php echo $featurebottom_items; ?> featurebottom">
            <jdoc:include type="modules" name="featurebottom" style="xhtml"/>
        </div>
       </div>
    </div>
<?php endif; ?>  

Add a class to your modules

For each of the modules which will have output in featurebottom, go to module > advanced > module class suffix and add ' featurebottom_item' (no quotation marks, but with a leading space)

CSS to style the width of your modules

#featurebottom .featurebottom_item{
width:100%;
position: relative;   /* replicate Bootstap column styling */
padding-right: 15px;
padding-left: 15px;
} 

 @media (min-width: 992px){
 #featurebottom.one .featurebottom_item{
 width:100%;
 }

 #featurebottom.two .featurebottom_item{
 width:50%;
 float:left;
 }

 #featurebottom.three .featurebottom_item{
 width:33%;
 float:left;
 }

 #featurebottom.four .featurebottom_item{
 width:25%;
 float:left;
 }
 }

You'll probably have to play with paddings and margins in the CSS, and you may even need to add rules like display:inline-block;, and my php code is untested. You are so close though that I think you'll be able to take it from here.

Good luck!



回答2:

I've found the answer (with thanks to the jquery website). All it takes is a tiny jquery script added to the very bottom of my index.php file, just before the closing body tag (plus opening and closing script tags, which don't show here:

<script>
$( ".feature-bottom > div" ).addClass( "col-md" );
</script>

What this means, for those who know as little about Jquery as me, is:

  1. .feature-bottom is the class of the parent div,

  2. > div means child divs of the parent, and

  3. .addClass adds a predefined css class to those children. It is possible to add more than one class inside the double quotes, each separated with a space, just as you would in html.