#1
Posted 29 May 2012 - 08:30 PM
I have an existing PW site that has a news section and it's getting quite big. I'd like some pointers as to how to go about listing the entries: 1. by month for the current year and 2. by year for each year past eg 2011, 2010 etc. All the posts have date fields too if that makes it easier.
Any help would be great.
Thanks
Marty
#2
Posted 30 May 2012 - 01:23 AM
I guess that was pretty much what you had in mind? If so I'll dog out my code when I'm at my PC if someone doesn't beat me to it with their version.
#3
Posted 30 May 2012 - 01:52 AM
Yes that's close enough to what I need. I'd love a peek at your code
Thanks
Marty
#4
Posted 30 May 2012 - 04:06 AM
Something like this should be at the top of your news template before including the head.inc file, as if you put in a year with no articles manually into the address bar, or mis-spell a month name or type in garbage then it should redirect you to the root news page:
if ($input->urlSegment2 && strlen($input->urlSegment1) == 4) {
$input->urlSegment1 = (int)$input->urlSegment1;
$input->urlSegment2 = (string)$input->urlSegment2;
if (in_array(strtolower($input->urlSegment2), array('january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december'))) {
$monthnum = date('n', strtotime('1 ' . $input->urlSegment2 . ' ' . $input->urlSegment1));
$filter = ', publish_date>' . mktime(0,0,0,$monthnum,1,$input->urlSegment1) . ',publish_date<' . mktime(0,0,0,$monthnum+1,1,$input->urlSegment1);
} else {
$session->redirect($pages->get('/articles/')->url);
}
} elseif ($input->urlSegment1) {
$input->urlSegment1 = (int)$input->urlSegment1;
if (strlen($input->urlSegment1) == 4) {
$filter = ', publish_date>' . mktime(0,0,0,1,1,$input->urlSegment1) . ',publish_date<' . mktime(0,0,0,1,1,$input->urlSegment1+1);
} else {
$session->redirect($pages->get('/articles/')->url);
}
}And then where you want your archive links you'll want something like this to build an array of years and months:
$dates = array();
$articles = $pages->find('template=news, sort=-publish_date');
foreach ($articles as $article) {
$articletime = strtotime($article->publish_date);
$articleyear = date('Y', $articletime);
$articlemonth = date('F', $articletime);
if (!isset($dates[$articleyear])) {
$dates[$articleyear] = array($articlemonth);
} elseif (!in_array($articlemonth, $dates[$articleyear])) {
$dates[$articleyear][] = $articlemonth;
}
}And finally, to output your list of links, something like this (but check the $rootNewsPage variable):
<ul>
<?php
$rootNewsPage = '/news/'; // Set this here somehow - my code did something complicated so you'll want something simpler like this probably
foreach ($dates as $year => $months) {
$class = ($input->urlSegment1 == $year) ? ' class="active"' : '';
echo " <li><a href='" . $rootNewsPage . $year . "/'{$class}>" . $year . "</a>";
if ($input->urlSegment1 == $year || (empty($input->urlSegment1) && $year == date('Y', time()))) {
echo "<ul>";
foreach ($months as $month) {
$class = ($input->urlSegment2 == strtolower($month)) ? ' class="active"' : '';
echo "<li><a href='" . $rootNewsPage . $year . '/' . strtolower($month) . "/'{$class}>{$month}</a></li>";
}
echo "</ul>";
}
echo " </li>";
}
?>
</ul>That last bit should also put a class called "active" on the links so you can highlight which year/month you're viewing.
So there we go, not the prettiest but it should be more or less functional. I'd love to know if there's a better way than looping through all articles though, but I suspect that's a necessity.
The only way you'll be able to get around what seems like an expensive selector (especially if you end up running through thousands of articles further down the line) is to cache it somehow and make a module so that it's only ever re-built on page save or even via a CRON job - something I've been meaning to do for a while now. If you cached an array of the month then in theory such a module would simply need to read in that cache file and append a month and occasionally a year as necessary rather than iterating through ALL of the pages - much more efficient on larger sites so I might look into that.
Funnily enough I've already got a home-brewed module called ContentCache that caches various bits and pieces like this already
#5
Posted 30 May 2012 - 04:43 AM
Thanks
Marty
#6
Posted 30 May 2012 - 11:26 PM
<?php
$year = strtotime("$input->urlSegment1");
$today = time();
$blog = $page->children("sort=-publish_date, publish_date=$year");
foreach($blog as $blogitem) {
echo "...";
}
Regards
Marty
#7
Posted 31 May 2012 - 01:02 AM
Pete: no need to loop all the articles just to get all the years, you just need to know the first year there has been article published.
#8
Posted 31 May 2012 - 04:26 AM
$archives = $pages->find("template=blog, created>=$starttime, created<=$endtime");
#9
Posted 31 May 2012 - 05:12 AM
Pete: no need to loop all the articles just to get all the years, you just need to know the first year there has been article published.
That's true of my site nowadays, however this was used originally in an articles section where we went months without an article, so I didn't want to display links to months where there were none. It probably would have been easier to simply find the oldest article and display the links anyway and simply return zero results, but I didn't like that from a user point of view.
For the news section though it makes perfect sense and I'm kicking myself for not thinking of that earlier
#10
Posted 31 May 2012 - 11:57 AM
$year = (int) $input->urlSegment1;
$blog = $page->children("date>=$year-01-01, date<=$year-12-31");
#11
Posted 31 May 2012 - 03:32 PM
#12
Posted 02 June 2012 - 05:04 AM
I think I'll stick to archives by year. I was trying to setup a 'poor man's' way of outputting the year each article was published ad then link directly to each year (which I have working elsewhere via urlSegment1).
<?php
$today = time();
$bloglist = $pages->get("/journal/")->children("publish_date<$today");
foreach($bloglist as $blogyear) {
$pubyear = strtotime("{$blogyear->publish_date}");
$urlyear = date("Y", $pubyear);
$yeararray = array_map("unserialize", array_unique(array_map("serialize", $urlyear)));
echo "<a href='" . $urlyear . "'>$urlyear</a><br/>";
}
?>
From this I'm getting:
2012
2012
2012 etc
Is there a quick way of removing the duplicates?
Regards
Marty
#14
Posted 02 June 2012 - 06:05 PM
Thanks again to everyone for your help. This is what I've cobbled together for those interested:
Archive include - which outputs the years:
<?php
$today = time();
$bloglist = $pages->get("/journal/")->children("publish_date<$today");
foreach($bloglist as $blogyear) {
$pubyear = strtotime("{$blogyear->publish_date}");
$urlyear = date("Y", $pubyear);
if (!in_array($urlyear, $years)) {
echo "<a href='/journal/" . $urlyear . "'>$urlyear</a><br/>";
$years[] = $urlyear;
}
}
And my list page. My template has 'Allow URL Segments' set to on in the admin:
<?php
$thisyear = date("Y");
$year = (int) $input->urlSegment1;
$blog = $page->children("sort=-publish_date, publish_date>=$year-01-01, publish_date<=$year-12-31");
foreach($blog as $blogitem) {
$str = "{$blogitem->publish_date}";
$publishyear = strtotime($str);
$urlyear = date("Y", $publishyear);
echo "<h2><a href='{$blogitem->url}'>{$blogitem->title}<span class='date'>{$blogitem->publish_date}</span></a></h2>";
echo "<p class='summary'>{$blogitem->summary}</p>";
}
// For fun
if(!$blogitem AND $year<$thisyear) echo "<p class='summary'>" . $pages->get('/settings/no-entries')->setting . " $year.";
if(!$blogitem AND $year>$thisyear) echo "<p class='summary'>" . $pages->get('/settings/future-entries')->setting . "";
Regards
Marty
#16
Posted 03 June 2012 - 02:59 AM
If I did have an article for every ear, I'd probably hardcode the start and check the date of the latest article instead - not everyone manages to pen an article on January the 1st as some of us wake up feeling a bit groggy
Also tagged with one or more of these keywords: solved
Community Support →
Getting Started →
Why does $page->rootParent identify current section?Started by isellsoap, 27 Feb 2013 |
|
|
||
Community Support →
General Support →
Change default operator for ProcessPageSearch?Started by bcartier, 20 Dec 2012 |
|
|
||
Solved
Community Support →
General Support →
$image->size(); configuration questionsStarted by 97s, 02 Dec 2012 |
|
|
||
solved
Community Support →
Multi-Language Support →
Setting translated titleStarted by thomas.isberg, 30 Nov 2012 |
|
|
||
solved
Community Support →
Multi-Language Support →
Multi-Language support broken in dev-branchStarted by interrobang, 19 Nov 2012 |
|
|
0 user(s) are reading this topic
0 members, 0 guests, 0 anonymous users













