3
\$\begingroup\$

I'm in the process of building some templates for Joomla, and although it all works as desired, I can't help thinking that there has to be a more elegant way to do this in PHP than my current approach. For the record, I'm still reasonably new to PHP!

Using collapsible module positions, I need to assign various CSS classes to a div depending on how many modules are published on a particular row. The code I wrote is below;

    if (($footer1 != "0") && ($footer2 == "0") && ($footer3 == "0")) {
    $footerWidth = 'full';
    }
    elseif (($footer1 == "0") && ($footer2 != "0") && ($footer3 == "0")) {
    $footerWidth = 'full';
    }
    elseif (($footer1 == "0") && ($footer2 == "0") && ($footer3 != "0")) {
    $footerWidth = 'full';
    }
    elseif (($footer1 != "0") && ($footer2 != "0") && ($footer3 == "0")) {
    $footerWidth = 'one_half';
    }
    elseif (($footer1 != "0") && ($footer2 == "0") && ($footer3 != "0")) {
    $footerWidth = 'one_half';
    }
    elseif (($footer1 == "0") && ($footer2 != "0") && ($footer3 != "0")) {
    $footerWidth = 'one_half';
    }
    else {
    $footerWidth = 'one_third';
    }

I then use the following code in the template itself to check for modules published;

    <?php if ($footer1 > 0) : ?>
                <div class="<?php echo htmlspecialchars($footerWidth); ?>">
                    <jdoc:include type="modules" name="footer1" style="html5" />
                </div>
    <?php endif; ?>
    <?php if ($footer2 > 0) : ?>
                <div class="<?php echo htmlspecialchars($footerWidth); ?>">
                    <jdoc:include type="modules" name="footer2" style="html5" />
                </div>
    <?php endif; ?>
    <?php if ($footer3 > 0) : ?>
                <div class="<?php echo htmlspecialchars($footerWidth); ?>">
                    <jdoc:include type="modules" name="footer3" style="html5" />
                </div>
    <?php endif; ?>

Can anyone suggest / recommend a better approach? It just seems like a lot of code for a simple function.

\$\endgroup\$
5
  • \$\begingroup\$ I'd imagine there as many ways to accomplish it as there are developers. We generally use Rockettheme templates. Most of them accomplish what you're trying to do, with the newer ones using the Gantry Framework. There are several free templates that you could download in review to see how they're doing it. \$\endgroup\$
    – GDP
    Jun 20 '12 at 15:48
  • \$\begingroup\$ The Joomla shop I work in uses these, they're pretty good. \$\endgroup\$ Jun 20 '12 at 15:50
  • \$\begingroup\$ Thanks, I'm familiar with RocketTheme and have used them in the past. I'm really looking to move away from bulky frameworks though. Plus, re-factoring RT templates to responsive designs is more work than building from scratch! \$\endgroup\$
    – Antony Doyle
    Jun 20 '12 at 15:59
  • \$\begingroup\$ no doubt, just thought their design might shed some light on how you're doing it - good luck! : ) \$\endgroup\$
    – GDP
    Jun 20 '12 at 16:00
  • \$\begingroup\$ Yeah, I did look over their stuff initially but, as it's a complex framework and my understanding of PHP is somewhat limited, I wound up even more confused! Thanks though :) \$\endgroup\$
    – Antony Doyle
    Jun 20 '12 at 17:35
1
\$\begingroup\$

I'm afraid I don't know what $footer1, $footer2, and $footer3 are. Either in PHP nor in HTML. These are just not that descriptive and I can't imagine a need for 3 footers, nor why their values would be numerical. I can imagine say, a copyright, bottom_nav_bar, and other similar things that might be mistaken as footers. But I digress, this is probably just example code.

Also, I can't tell if its just CR's code indentation is off again, or if you really have all those if/else statements and their contents on the same level. If the later, please indent your code whenever you enter a statement, loop, function, etc.. as it will make reading your code so much easier. If the former, you can ignore this part.

Now, on to the actual code. This suggestion is pretty similar to Jared's, and I agree with what I think he was driving at. These should really be set as booleans. However, there's probably a better way to get them as such without needing to typecast, such as changing them at the source. If their current values are important and that is not an option, maybe typecasting can't be helped. But depending on what the range of these values are, maybe it won't be necessary after all. Assuming it is either a value of 0 or 1, then you could do the following.

$footers = compact( 'footer1', 'footer2', 'footer3' );//get footers into array
sort( $footers );//sort array so it is in numerical order
$code = implode( '', $footers );//combine array to string for code to test

switch( $code ) {
    case '001': $footerWidth = 'full'; break;
    case '011': $footerWidth = 'one_half'; break;
    default: $footerWidth = 'one_third'; break;
}

This can be adapted for any single digit number (1-9), but I'm assuming the range is as above. Again, this can probably be simplified if I knew the application to which it was being applied. Hope this helps!

\$\endgroup\$
1
  • \$\begingroup\$ This is exactly the sort of thing I was looking for. Thank you. I'm fairly new to PHP, so the if/else statements seemed like the most logical approach. I never even considered using arrays. For reference, the $footer1, $footer2 & $footer3 refer to individual module "blocks" along a single footer row in a Joomla template. It allows the insertion of up to three columns within the footer. Probably not the most semantic approach, I know. Thanks again, this is very useful and far simpler than my approach! \$\endgroup\$ Jun 23 '12 at 11:01
2
\$\begingroup\$

Something somewhat confusing is the comparison to of each $footer# to the string '0' then later comparing it to greater than integer 0. This is practically the definition of weakly typed languages. If you know what $footer# variables actually contain you might be able to simplify this, but here is a fully functioning replacement to the first code block.

One could simplify this a bit, but the core concepts are there. '0' casts to False, and True casts to 1. There are plenty of other ways to accomplish the same thing, especially if you have significantly more incoming $footer#'s, or if they are stored in something iteratable like an array.

//$footer1 = '10';
//$footer2 = '-5';
//$footer3 = '0';

$footer1Bool = (bool) $footer1;
$footer2Bool = (bool) $footer2;
$footer3Bool = (bool) $footer3;

$footer1Int = (int) $footer1Bool;
$footer2Int = (int) $footer2Bool;
$footer3Int = (int) $footer3Bool;

$footerCombined = $footer1Int + $footer2Int + $footer3Int;

if ( $footerCombined >= 3 ) {
    $footerWidth = 'one_third';
} else if ( $footerCombined == 2 ) {
    $footerWidth = 'one_half';
} else {
    $footerWidth = 'full';
}
\$\endgroup\$
1
  • \$\begingroup\$ Though the casts explicitly state your intentions, given that we know they compare properly to '0', you could forget the bools and just go straight to integers as $footer1Int = ($footer1 == '0')? 0 : 1; etc for each of them. \$\endgroup\$
    – Jared Kipe
    Jun 22 '12 at 5:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.