HiveBrain v1.2.0
Get Started
← Back to all entries
patternphpMajor

Displaying courses in an HTML calendar

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
coursescalendarhtmldisplaying

Problem

I'm struggling for a while now with the readability of my code, I after I tried to get as much insight as possible (for my standards). On my level, I think I understand and use it all right for my level.

But I'm still having big chunks of mixed html/css in the presentation. Often I have a mediocre complex multi-dimensional array as a return value and on the actual presentation page, I iterate through it, but still do a lot of stuff with it.

So I'm looking now into template engines like Smarty, but I can't get my head around it, how I would save some actual code with it in examples like the following where I iterate and work with the array in the presentation:

```
$courseinfo = new courseinfo($_SESSION['course_short']);
$row = $courseinfo->get_all();
$default = $courseinfo->get_default();
$prices = $courseinfo->get_prices();
$month_min_show = 5;

//color settings for prices
$colorlow = '#6F6';
$colormid = '#09F';
$colorhigh = '#F90';
$colorspecial = '#F0F';
$colorfull = 'rgba(255,0,0,0.3)';

/* CONTENT CALENDAR
-----------------
-----------------
*/

echo '';
$count['month'] = 0;
foreach($row as $month)
{
$lastcourse = end($month['course']);
$laststart = $lastcourse['date'];
$enddate = new DateTime($laststart);
$enddate->modify('+ '.($lastcourse['length']-1).' days');
$iterate = new DateTime('01-'.date('m',strtotime($laststart)).'-'.$month['year']);
if (!isset($stored['year']) || isset($stored['year']) && $stored['year'] != $month['year'])
{

if($count['month'] > $month_min_show) { break;} // don't show next year if $month_min_show months already displayed
if(isset($stored['year'])) { echo '';}
echo ''.$month['year'].'';
echo '';
echo 'PRICES '.$month['year'].'';

echo 'fully booked';
if (in_array('low',$prices[$month['year']])) { echo ''.$default['price_low'].' €'; }
if (in_array('mid',$prices[$month['year']])) { echo ''.$default['price_mid'].' €'; }
if (i

Solution

Thank you for the perfect example of the real-life piece of presentation logic.

Most people pushing some primitive templating solutions just have no idea of such a complex cases existence.

Three rules for you to get it right:

  • Use PHP as a template engine.



  • Output not an HTML tag nor text constant using PHP echo but use straight HTML only.



  • Move ALL data preparations to the business logic part.



Format ALL your data in the business logic.

Pass only scalars to the template. No datetime objects!

No complex logic - use only basic PHP syntax in the template.

So, foreach your data twice:

  • first time to do all the data preparations and formatting.



  • and next time to do the actual output in the template.



So, PHP code become like this

$count['month'] = 0;
foreach($row as $i => $month)
{
    $month['lastcourse'] = end($month['course']);
    $month['laststart']  = $month['lastcourse']['date'];
    $month['enddate']    = new DateTime($month['laststart']);
    $month['enddate']->modify('+ '.($month['lastcourse']['length']-1).' days');
    $month['iterate']    = new DateTime('01-'.date('m',strtotime($month['laststart'])).'-'.$month['year']);
    $month['showyear']   = (!isset($stored['year']) || isset($stored['year']) && $stored['year'] != $month['year']);
    $month['monthname']  = mb_strtoupper($month['monthname'],'UTF-8');
    $row[$i]             = $month;
}


while template as clean as this


  
    
        
    
        
        
        PRICES 
        ">fully booked
        some code removed
        
  
        
        
        
    
     


I am not going to reformat all your code, but just to give you an idea.

Code Snippets

$count['month'] = 0;
foreach($row as $i => $month)
{
    $month['lastcourse'] = end($month['course']);
    $month['laststart']  = $month['lastcourse']['date'];
    $month['enddate']    = new DateTime($month['laststart']);
    $month['enddate']->modify('+ '.($month['lastcourse']['length']-1).' days');
    $month['iterate']    = new DateTime('01-'.date('m',strtotime($month['laststart'])).'-'.$month['year']);
    $month['showyear']   = (!isset($stored['year']) || isset($stored['year']) && $stored['year'] != $month['year']);
    $month['monthname']  = mb_strtoupper($month['monthname'],'UTF-8');
    $row[$i]             = $month;
}
<div id="calendar">
<?php foreach($row as $month): ?>
  <?php if ($month['showyear']): ?>
    <?php if ($stored['year']): ?>
        <br /><br /><br /><div style="margin-top:-10px"></div>
    <?php endif ?>
        <span class="year" style="float:left;"><?=$month['year']?></span>
        <div style="float:right;margin-top:-20px;padding-right:5px;">
        <div style="float:left;font-size:12px;font-weight:bold;">PRICES <?=$month['year']?></div>
        <div class="pricelegend" style="background-color:<?=$colorfull?>">fully booked</div>
        some code removed
        </div><div style="clear:both;"></div><hr width="800px;" align="left"/>
  <?php endif ?>
        <div class="m_start"><?=$month['monthname']?><br />
        <span class="yearsmall"><?=$month['year']?></span>
        </div>
    <div class="courses">
    <div style="float:left;width:10px;">&nbsp;</div>
<?php endforeach ?>
</div>

Context

StackExchange Code Review Q#6359, answer score: 31

Revisions (0)

No revisions yet.