Hi, i want to show an event list on my blog.
I created a meta box with the custom field 'event_date' (format: dd/mm/yyyy).
I want to list these events (posts) grouped by month.
If a month has no events, he is not displayed.
--------------------------------------------------------------
Example:
<strong>MAY/2011</strong>
-Event Title
-Event Title
-Event Title
________________________
<strong>JUN/2011</strong>
-Event Title
-Event Title
________________________
<strong>OCT/2011</strong>
-Event Title
________________________
<strong>JAN/2012</strong>
-Event Title
-Event Title
________________________
Julian Lannigan answers:
So, one of the big things I suggest you do is change your event date into a format native to php's date formats. [[LINK href="http://www.php.net/manual/en/datetime.formats.date.php"]]http://www.php.net/manual/en/datetime.formats.date.php[[/LINK]]
But regardless the following script works with your current date format. Just if you use a native format you can harness the power of the strtotime function that will allow you to safely use different formats without breaking anything. If you want to use a native format all you have to do is uncomment the $cfEventDateConvert variable and the following if/then/else block. If you need me to send you the uncommented code I can do that. That if/then block tries to use the strtotime function, then if that fails, it reverts to converting your format into a format strtotime can understand.
The $customFieldName is just a variable that contains the custom field name/key. Just made it a little easier to change the key name if need be.
The display is very simple. I suggest using css to style the lists. Here is the structure of the output:<h2>MAY / 2011</h2>
<ul>
<li><a href="#">Event Name</a></li>
<li><a href="#">Event Name</a></li>
<li><a href="#">Event Name</a></li>
</ul>
<hr>
<h2>OCT / 2011</h2>
<ul>
<li><a href="#">Event Name</a></li>
<li><a href="#">Event Name</a></li>
</ul>
<hr>
To use the code, just place it in the location you want it to display, in other words, drop in a template file of your choosing. The snippet is pretty much independent of "The Loop" etc.
This snippet requires WP 3.1 or better. I am using the "meta_query" argument in the query to filter out the posts that do not have an event date.
You can see it working on my sandbox site: [[LINK href="http://testwp.jlconsulting.co/blog-posts/"]]http://testwp.jlconsulting.co/blog-posts/[[/LINK]]
I have posted the code on gist for easier reading: [[LINK href="https://gist.github.com/972433"]]https://gist.github.com/972433[[/LINK]]
<?php
// GET THE DATA
$customFieldName = 'event_date';
$outputData = array();
$queryArgs = array(
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => $customFieldName,
'value' => "",
'compare' => "!=",
'type' => 'CHAR'
)
)
);
$eventQuery = new WP_Query($queryArgs);
if ($eventQuery->have_posts()) {
foreach ($eventQuery->posts as $ePost) {
$pID = $ePost->ID;
$cfEventDate = get_post_meta($pID, $customFieldName, 1);
//First we will try to convert the date using PHP.
//$cfEventDateConvert = strtotime($cfEventDate);
//if ($cfEventDateConvert == false) {
//With the given format(assuming dd/mm/yyyy), we have to flip the date into a valid format specified here:
// http://www.php.net/manual/en/datetime.formats.date.php
//The following changes the format from dd/mm/yyyy to mm/dd/yyyy
$cfEventDate = explode("/", $cfEventDate);
if (count($cfEventDate) != 3) {
continue;
}
$EventDateDAY = $cfEventDate[0];
$EventDateMONTH = $cfEventDate[1];
$cfEventDate[0] = $EventDateMONTH;
$cfEventDate[1] = $EventDateDAY;
$cfEventDate = strtotime(implode("/", $cfEventDate));
if ($cfEventDate == false) {
continue;
}
//DONE with date conversion
//} else {
//Everything is good, you are using a supported PHP date format.
// $cfEventDate = $cfEventDateConvert;
//}
$keyDate = date('Ym', $cfEventDate);
if (!isset($outputData[$keyDate])) {
$outputData[$keyDate] = array();
}
$makeUnique = "";
if (isset($outputData[$keyDate][date('d',$cfEventDate)])) {
$makeUnique = ".".mt_rand();
}
$outputData[$keyDate][date('d',$cfEventDate).$makeUnique] = array('eventDate'=>$cfEventDate, 'post'=>$ePost);
asort($outputData[$keyDate], SORT_NUMERIC);
}
asort($outputData, SORT_NUMERIC);
}
//END DATA GET
//START DISPLAY OF DATA
foreach ($outputData as $yearMonth => $data) {
$oYear = substr($yearMonth, 0, 4);
$oMonth = substr($yearMonth, -2);
$oYearMonthTimestamp = mktime(0,0,0,$oMonth,1,$oYear);
//Display header for year/month
echo "<h2>".strtoupper(date("M / Y", $oYearMonthTimestamp))."</h2>";
//Display list of events in that year/month
echo "<ul>";
foreach ($data as $day => $postInfo) {
$oDay = substr($day, 0, 2);
echo "<li><a href=\"".get_permalink($postInfo['post']->ID)."\">";
echo "{$postInfo['post']->post_title}";
echo "</a></li>";
}
echo "</ul>";
echo "<hr>";
}
//END DISPLAY OF DATA
?>
Rodrigo F comments:
Great Julian! But there's a problem when I insert an event in 2012 year. Is being displayed:
MAY/2011
-Event Title
-Event Title
________________________
JUL/2011
-Event Title
________________________
SEP/2011
-Event Title
________________________
JAN/2012
-Event Title
________________________
OCT/2011
-Event Title
________________________
Rodrigo F comments:
I forgot a detail: how not display events in past months?
Julian Lannigan comments:
Oops, I used the wrong sort function. I changed it to [[LINK href="http://www.php.net/manual/en/function.ksort.php"]]ksort[[/LINK]]. I also added the old event if statement check. Check it out ([[LINK href="https://gist.github.com/972433"]]it on gist[[/LINK]]).
// GET THE DATA
$customFieldName = 'event_date';
$outputData = array();
$currentDate = time();
$queryArgs = array(
'posts_per_page' => -1,
'meta_query' => array(
array(
'key' => $customFieldName,
'value' => "",
'compare' => "!=",
'type' => 'CHAR'
)
)
);
$eventQuery = new WP_Query($queryArgs);
if ($eventQuery->have_posts()) {
foreach ($eventQuery->posts as $ePost) {
$pID = $ePost->ID;
$cfEventDate = get_post_meta($pID, $customFieldName, 1);
//First we will try to convert the date using PHP.
//$cfEventDateConvert = strtotime($cfEventDate);
//if ($cfEventDateConvert == false) {
//With the given format(assuming dd/mm/yyyy), we have to flip the date into a valid format specified here:
// http://www.php.net/manual/en/datetime.formats.date.php
//The following changes the format from dd/mm/yyyy to mm/dd/yyyy
$cfEventDate = explode("/", $cfEventDate);
if (count($cfEventDate) != 3) {
continue;
}
$EventDateDAY = $cfEventDate[0];
$EventDateMONTH = $cfEventDate[1];
$cfEventDate[0] = $EventDateMONTH;
$cfEventDate[1] = $EventDateDAY;
$cfEventDate = strtotime(implode("/", $cfEventDate));
if ($cfEventDate == false) {
continue;
}
//DONE with date conversion
//} else {
//Everything is good, you are using a supported PHP date format.
// $cfEventDate = $cfEventDateConvert;
//}
if ($cfEventDate < $currentDate) {
continue; //don't display old events
}
$keyDate = date('Ym', $cfEventDate);
if (!isset($outputData[$keyDate])) {
$outputData[$keyDate] = array();
}
$makeUnique = "";
if (isset($outputData[$keyDate][date('d',$cfEventDate)])) {
$makeUnique = ".".mt_rand();
}
$outputData[$keyDate][date('d',$cfEventDate).$makeUnique] = array('eventDate'=>$cfEventDate, 'post'=>$ePost);
ksort($outputData[$keyDate], SORT_NUMERIC);
}
ksort($outputData, SORT_NUMERIC);
}
//END DATA GET
//START DISPLAY OF DATA
foreach ($outputData as $yearMonth => $data) {
$oYear = substr($yearMonth, 0, 4);
$oMonth = substr($yearMonth, -2);
$oYearMonthTimestamp = mktime(0,0,0,$oMonth,1,$oYear);
//Display header for year/month
echo "<h2>".strtoupper(date("M / Y", $oYearMonthTimestamp))."</h2>";
//Display list of events in that year/month
echo "<ul>";
foreach ($data as $day => $postInfo) {
$oDay = substr($day, 0, 2);
echo "<li><a href=\"".get_permalink($postInfo['post']->ID)."\">";
echo "{$postInfo['post']->post_title}";
echo "</a></li>";
}
echo "</ul>";
echo "<hr>";
}
//END DISPLAY OF DATA
Rodrigo F comments:
Perfect!
Thanks!
Sébastien | French WordpressDesigner answers:
maybe could you increase the fee to 20$
Rodrigo F comments:
increased