MarcC Posted November 10, 2011 Share Posted November 10, 2011 A client has asked for a grid (table-based) calendar display on their website. I don't want to spend hours reinventing the wheel, so I thought I'd ask: Does anyone know of existing calendar software that could integrate with Processwire? I found this example and it seems like it may be a good start, but I'm not sure how to use it with PW. Any suggestions would be welcome. Thanks. 2 Link to comment Share on other sites More sharing options...
Pete Posted November 10, 2011 Share Posted November 10, 2011 If they don't mind using something a bit external, you can display a Google calendar in a web page pretty easily from what I remember. There are advantages and disadvantages to doing so (we're going back a few years here so it might just be advantages by now) but you certainly get the benefit of a calendar you can sync with a smartphone or your favourite email software rather than one that has to be updated manually on the website. Beyond that, there seem to be a variety of calendar packages out there but none of the ones I've looked at were that straightforward. Link to comment Share on other sites More sharing options...
ryan Posted November 10, 2011 Share Posted November 10, 2011 Here was Ryan's example code for calendar, until I (apeisa) modified it instead of quoting... I got the original back from my editor, I post it here as reference. Ryan - sorry I lost your message here. You wrote something about that it is fun to code calendars -apeisa <?php $year = (int) $input->urlSegment1; $month = (int) $input->urlSegment2; if(!$month) $month = date('n'); // if no month, use this month if(!$year) $year = date('Y'); // if no year, use this year $startTime = strtotime("$year-$month-01 00:00:00"); $endTime = strtotime("+1 month", $startTime); // find all events that fall in the given month and year $events = $page->children("date>=$startTime, date<$endTime"); // get all the info you need to draw a grid calendar $weekDayNames = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'); $firstDayName = date('D', $startTime); // i.e. Tue $daysInMonth = date('t', $startTime); // 28 through 31 // make the calendar headline $out = "<h1>" . date('F Y') . "</h1>"; // i.e. October 2011 // create the calendar header with weekday names $out .= "<table><thead><tr>"; foreach($weekDayNames as $name) $out .= "<th>$name</th>"; $out .= "</tr></thead><tbody><tr>"; // fill in blank days from last month till we get to first day in this month foreach($weekDayNames as $name) { if($name == $firstDayName) break; $out .= "<td> </td>"; } // draw the calendar for($day = 1; $day <= $daysInMonth; $day++) { // get the time info that we need for this day $startTime = strtotime("$year-$month-$day 00:00:00"); $endTime = strtotime("+1 day", $startTime); $dayName = date('D', $startTime); // if we're at the beginning of a week, start a new row if($day > 1 && $dayName == 'Sun') $out .= "<tr>"; // create the list of events for this day (if any) $list = ''; foreach($events->find("date>=$startTime, date<$endTime") as $event) { $list .= "<li><a href='{$event->url}'>{$event->title}</a></li>"; } // if any events were found for this day, wrap it in <ul> tag if($list) $list = "<ul>$list</ul>"; // make the day column with day number as header and event list as body $out .= "<td><h2>$day</h2>$list</td>"; // if last day in week, then close out the row if($dayName == 'Sun') $out .= "</tr>"; } // finish out the week with blank days for next month $key = array_search($dayName, $weekDayNames); while(isset($weekDayNames[++$key])) { $out .= "<td> </td>"; } // close the last row and table $out .= "</tr></tbody></table>"; // output the calendar echo $out; 3 Link to comment Share on other sites More sharing options...
MarcC Posted November 11, 2011 Author Share Posted November 11, 2011 Wow, thanks Ryan. I didn't even know URL segments existed I'll have a look. Meanwhile, the client was asking for some pretty impressive features, so I asked for an example of what they needed. It turned out the example was a JPG image of an MS Publisher calendar on somebody's website. "Can do" Link to comment Share on other sites More sharing options...
apeisa Posted November 15, 2011 Share Posted November 15, 2011 Ok, I tried to quote Ryan's post above, but accidentally modified it and overwrote with my own message. Ryan's code worked almost perfectly (it outputted sundays as their own row), so here is only minor changes to the original: <?php function renderCalendar($page, $year, $month, $field = 'startdate') { $year = (int) $year; $month = (int) $month; $startTime = strtotime("$year-$month-01 00:00:00"); $endTime = strtotime("+1 month", $startTime); // find all events that fall in the given month and year $events = $page->children("$field>=$startTime,$field<$endTime"); // get all the info you need to draw a grid calendar $weekDayNames = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'); $firstDayName = date('D', $startTime); // i.e. Tue $daysInMonth = date('t', $startTime); // 28 through 31 // make the calendar headline // $out = "<h1>" . date('F Y') . "</h1>"; // i.e. October 2011 // create the calendar header with weekday names $out .= "<table><thead><tr>"; foreach($weekDayNames as $name) $out .= "<th>$name</th>"; $out .= "</tr></thead><tbody><tr>"; // fill in blank days from last month till we get to first day in this month foreach($weekDayNames as $name) { if($name == $firstDayName) break; $out .= "<td> </td>"; } // draw the calendar for($day = 1; $day <= $daysInMonth; $day++) { // get the time info that we need for this day $startTime = strtotime("$year-$month-$day 00:00:00"); $endTime = strtotime("+1 day", $startTime); $dayName = date('D', $startTime); // if we're at the beginning of a week, start a new row if($day > 1 && $dayName == 'Mon') $out .= "<tr>"; // create the list of events for this day (if any) $list = ''; foreach($page->children("$field>=$startTime, $field<$endTime") as $event) { $list .= "<li><a href='{$event->url}'>{$event->title}</a></li>"; } // if any events were found for this day, wrap it in <ul> tag if($list) $list = "<ul>$list</ul>"; // make the day column with day number as header and event list as body $out .= "<td><h2>$day</h2>$list</td>"; // if last day in week, then close out the row if($dayName == 'Sun') $out .= "</tr>"; } // finish out the week with blank days for next month $key = array_search($dayName, $weekDayNames); while(isset($weekDayNames[++$key])) { $out .= "<td> </td>"; } // close the last row and table $out .= "</tr></tbody></table>"; // output the calendar return $out; } 1 Link to comment Share on other sites More sharing options...
apeisa Posted November 15, 2011 Share Posted November 15, 2011 Updated this to support localized day titles and simple prev/next navigation. <?php function renderCalendar($page, $year, $month, $field = 'startdate') { // This feels little dirty, there is probably much more efficient way to get local day name? $mon = strftime('%a', strtotime("2011-11-14 00:00:00")); $tue = strftime('%a', strtotime("2011-11-15 00:00:00")); $wed = strftime('%a', strtotime("2011-11-16 00:00:00")); $thu = strftime('%a', strtotime("2011-11-17 00:00:00")); $fri = strftime('%a', strtotime("2011-11-18 00:00:00")); $sat = strftime('%a', strtotime("2011-11-19 00:00:00")); $sun = strftime('%a', strtotime("2011-11-20 00:00:00")); $year = (int) $year; $month = (int) $month; $startTime = strtotime("$year-$month-01 00:00:00"); $endTime = strtotime("+1 month", $startTime); $lastMonth = strtotime("-1 month", $startTime); // find all events that fall in the given month and year $events = $page->children("$field>=$startTime,$field<$endTime"); // get all the info you need to draw a grid calendar $weekDayNames = array($mon, $tue, $wed, $thu, $fri, $sat, $sun); $firstDayName = strftime('%a', $startTime); // i.e. "Tue" (Eng) or "ti" (Fin) $daysInMonth = date('t', $startTime); // 28 through 31 // make the calendar headline $out = "<h1>" . strftime('%B %Y', $startTime) . "</h1>"; // i.e. October 2011 $out .= "<div class='nav'>"; $out .= "<a href='../../". date('Y', $lastMonth) ."/". date('m', $lastMonth) ."/'>←</a>"; $out .= "<a href='../../". date('Y', $endTime) ."/". date('m', $endTime) ."/'>→</a>"; $out .= "</div>"; // create the calendar header with weekday names $out .= "<table class='calendar'><thead><tr>"; foreach($weekDayNames as $name) $out .= "<th>$name</th>"; $out .= "</tr></thead><tbody><tr>"; // fill in blank days from last month till we get to first day in this month foreach($weekDayNames as $name) { if($name == $firstDayName) break; $out .= "<td> </td>"; } // draw the calendar for($day = 1; $day <= $daysInMonth; $day++) { // get the time info that we need for this day $startTime = strtotime("$year-$month-$day 00:00:00"); $endTime = strtotime("+1 day", $startTime); $dayName = strftime('%a', $startTime); // if we're at the beginning of a week, start a new row if($day > 1 && $dayName == $mon) $out .= "<tr>"; // create the list of events for this day (if any) $list = ''; foreach($page->children("$field>=$startTime, $field<$endTime") as $event) { $list .= "<li><a href='{$event->url}'>{$event->title}</a><p>{$event->location->title}, <span class='city'>{$event->location->city->title}</span></p></li>"; } // if any events were found for this day, wrap it in <ul> tag if($list) $list = "<ul>$list</ul>"; // make the day column with day number as header and event list as body $out .= "<td valign='top'><h2>$day</h2>$list</td>"; // if last day in week, then close out the row if($dayName == $sun) $out .= "</tr>"; } // finish out the week with blank days for next month $key = array_search($dayName, $weekDayNames); while(isset($weekDayNames[++$key])) { $out .= "<td> </td>"; } // close the last row and table $out .= "</tr></tbody></table>"; // output the calendar return $out; } 2 Link to comment Share on other sites More sharing options...
ryan Posted November 15, 2011 Share Posted November 15, 2011 Nice update for localization! I don't know of a better way to get those local day names, but this would be one way to potentially improve the existing method. In this snippet, I'm just putting the localized day names directly into the $weekDayNames array, since that's where they go anyway. <?php $weekDayNames = array(); $time = strtotime("2011-11-14 00:00:00"); // a known Monday for($day = 1; $day <= 7; $day++) { $weekDayNames[$day] = strftime('%a', $time); $time += 86400; // +1 day } Link to comment Share on other sites More sharing options...
kixe Posted April 26, 2013 Share Posted April 26, 2013 A known monday is also the day after last sunday! Isn't it? $weekDayNames=array(); $i=0; while($i++ < 7) array_push($weekDayNames, strftime('%a', strtotime('last Sunday + '.$i.' day'))); change this // if we're at the beginning of a week, start a new row if($day > 1 && $dayName == $weekDayNames[0]) $out .= "<tr>"; and that // if last day in week, then close out the row if($dayName == $weekDayNames[6]) $out .= "</tr>"; kixe Link to comment Share on other sites More sharing options...
kixe Posted April 26, 2013 Share Posted April 26, 2013 While trying out language switcher together with the calendar. I put this to the beginning of the script: $lang = substr($page->url,1,2); $lang_code = ($lang=='en')?'en_US':$lang.'_'.strtoupper($lang);//works not for all countries but most of them (fr, de, it, nl, is, ru, es, tr) setlocale(LC_TIME, $lang_code); and changed the forward backward links: $out .= "<a href='/".$lang."/calendar/". date('Y', $lastMonth) ."/". date('m', $lastMonth) ."/'>←</a>"; $out .= "<a href='/".$lang."/calendar/". date('Y', $endTime) ."/". date('m', $endTime) ."/'>→</a>"; I am using url-segments for year and month, like ryan recommended $year = ($input->urlSegment1)?$input->urlSegment1:date('Y'); $month = ($input->urlSegment2)?$input->urlSegment2:date('m'); this will put out the current month as standard under the url en/calendar/ echo renderCalendar($page, $year, $month, $field = 'startdate'); its good to have such an easy going calendar. Thanks. Fun (while working with PW) has already started. kixe 2 Link to comment Share on other sites More sharing options...
joshuag Posted May 22, 2017 Share Posted May 22, 2017 For anyone following this thread or searching... https://processwire.com/talk/topic/16363-recurme-–-processwire-recurring-dates-field-custom-calendar-module/ Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now