Page 1 of 1

[solved] Template logic for special calendar layout

Posted: Wed Aug 27, 2014 2:17 pm
by 10010110
Hey, I’d like to get some input on the right template logic for a calendar (upcoming events list) that works like this:

Code: Select all

September 20th
--------------------
10am  |  Event name
12pm  |  Event name
--------------------
September 21st
--------------------
4pm  |  Event name
6pm  |  Event name
To make things even more complicated, it should display all events of the current day and if there are less than five events on this day then show as many events of next day(s) to fill up a total of five events.

I don’t expect you to write the entire code for me, I just need a general logic for the start.
I suppose I need to get the current day with Smarty (server time is OK, it’s a site addressing local people) and compare that to $event.event_date_start. I need to have a counter that checks for the amount of events that return true for this comparison and if it’s greater than five, stop if the day comparison returns false, else continue until the counter reaches 5. Am I right so far or is there a simpler way?

Re: Template logic for special calendar layout

Posted: Wed Aug 27, 2014 2:37 pm
by JohnnyB
Here's an UDT that can take a date and make it a timestamp. Then, compare your event date (timestamp) to whatever end date timestamp is needed or $smarty.now.

Code: Select all

if (isset($params['EventDate'])) {
$eDate=$params['EventDate'];
print strtotime($eDate);
}
if (isset($params['Yesterday'])) {
print strtotime('-1 day');
}
if (isset($params['ThreeDaysAgo'])) {
print strtotime('-3 day');
}
// use yyyy-mm-dd
call it what you want.. then use the EventDate param in the tag using the calendar event date formatted as yyyy-mm-dd

note- if param Yesterday is set, the timestamp sent is 1 day old... if the ThreeDaysAgo param is set, then the timestamp sent is 3 days old.

Re: Template logic for special calendar layout

Posted: Wed Aug 27, 2014 2:58 pm
by calguy1000
You need a counter, and also logic to check for the date change. Something like this should output a maximum of 5 events, with separate headers for each date if the date changes.

pseudo code:

Code: Select all

{$counter=0}
{$date='1970-01-01'}
{foreach event}
    {if $counter < 5}
       {$thedate='event date formatted as year-month-day'}
       {if $date != $thedate}
          {* do header *}
          <h3>{$thedate}</h3>
       {/if}
       {* do event output *}
       {$date=$thedate}
       {$counter=$counter+1}
    {/if}
{/foreach}

Re: Template logic for special calendar layout

Posted: Wed Aug 27, 2014 3:11 pm
by chandra
There's no need of a additional counter ;) - you can use the internal foreach counter.

Code: Select all

 
{if $event@iteration < 5}

Re: Template logic for special calendar layout

Posted: Wed Aug 27, 2014 5:29 pm
by 10010110
Thanks for your quick replies, very useful info here. The intricacy here is that the current (or first upcoming) day can have more than five events. It should show all events of the first upcoming/current day in any case, even if that means displaying ten events. And if there are more than four events it should show the first upcoming/currend day’s events only, and only in case there are less than five it should display events of following days to a total amount of five events.

In the meantime I’ve (apparently) solved it with this approach (enhanced with chandra’s suggestion afterwards):

Code: Select all

<table>
	<tbody>
{foreach from=$events key=key item=event}
	{if $event.event_date_start|strtotime >= $smarty.now}
		{if !$stop}
			{if $event@iteration === 1}
				{assign var="initial_date" value=$event.event_date_start|date_format:'%d'}
			{/if}
			{if $event.event_date_start|date_format:'%d' !== $startdate}
				{assign var="startdate" value=$event.event_date_start|date_format:'%d'}
		<tr>
			<th colspan="2">{$event.event_date_start|date_format:'%d. %B'}</th>
		</tr>
			{/if}
		<tr>
			<td>{$event.event_date_start|date_format:'%H:%M'}</td>
			<td>{$event.event_title}</td>
		</tr>
			{if $event@iteration === 5 && $event.event_date_start|date_format:'%d' !== $initial_date}{$stop = true}{/if}
		{/if}
	{/if}
{/foreach}
	</tbody>
</table>
What it does is it stores the initial day number in a variable on the first iteration and the current iteration’s day in another variable. if the current iteration’s day is different from the previous iteration’s day it prints the day as header row. After five iterations it checks whether the current iteration’s day is still the same as the inital day and if not it stops printing.

How’s that? ;D

I can perhaps even scrap the if statement: {if $event.event_date_start|strtotime >= $smarty.now} since it starts with upcoming events anyway.