Compact archives for sNews 1.7
filed under: sNews CMS / Hacks & Mods
Anyone that's running sNews and writes as many articles as me has no doubt encountered the limitations of the current archives page. Basically it's just an enormously long chronological list.
Here's a handy little replacement function to display the archives by year, with clickable months if in fact the month contains articles. A user can click a specific month to view listings from only that month, or by year to view the entire year's articles. View my archives page for a demo.
First add the following to your language file;
#compact archives $l['archive_by_date'] = 'By Date';
Now upload your language file.
OK, now for the logic, this is a simple drop-in replacement archive function, so the first step is ...as always... BACK-UP your snews.php file and work off of a copy. Now find the function archive and rename it, I always append "_orig" when renaming function, so I can easily go back, so rename it archive_orig. Now copy the new archive function into your snews.php file, again, I always put new functions at the bottom just above the closing php tag when possible, to separate from the original core code.
// ARCHIVE - COMPACT STYLE
function archive($start = 0, $size = 200) {
echo '<h2><a href="'._SITE.'archive/">'.l('archive').'</a>';
$break = explode("/",cleanXSS($_SERVER['REQUEST_URI']));
$count = count($break);
$months = array("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12");
if (in_array($break[$count-2], $months)) { //month is requested
$year = $break[$count-3];
$month = $break[$count-2];
} elseif(strlen($break[$count-2]) == '4') {//just the year requested
$year = $break[$count-2];
}
if ($year >= '1900' && $year <= date('Y')) { // not a BS year
$a1 = " AND YEAR(date) = $year";
echo ' / <a href="'._SITE.'archive/'.$year.'/">'.$year.'</a>';
}
if (checkdate($month,1,2001)) { // not a BS month
$date_placeholder = strtotime("$month/01/2001");
$a2 = " AND MONTH(date)=$month";
$month_name = strftime("%B", $date_placeholder); // Full month name, based on the locale
echo ' / '.$month_name;
}
if (!$a1 && !$a2) { // YEAR/Month not set, display front page
echo '</h2><h6>'.l('archive_by_date').'</h6><div class="archive_date"><p>';
$query = "SELECT DISTINCT YEAR(date) AS year FROM "._PRE."articles a, "._PRE."categories c
WHERE a.published='1'
AND a.visible='YES'
AND c.published='YES'
AND a.category=c.id
AND a.date <= NOW()
ORDER BY year DESC";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$i = "0";
$year = $row['year'];
echo '<a href="'._SITE.'archive/'.$year.'/" title="'.$year.'">'.$year.'</a> ';
$month_query = "SELECT DISTINCT MONTH(date) AS month FROM "._PRE."articles a, "._PRE."categories c
WHERE YEAR(date) = '$year'
AND a.published='1'
AND a.visible='YES'
AND c.published='YES'
AND a.category=c.id
AND a.date <= NOW()
ORDER BY month ASC";
$month_result = mysql_query($month_query);
$rows = array();
while($r = mysql_fetch_assoc($month_result)) {array_push($rows, $r);}
for ($month = 1; $month <= 12; $month += 1) {
$date_placeholder = strtotime("$month/01/2001");
$month_name = strftime("%B", $date_placeholder); // Full month name, based on the locale
$month_abbrev = strftime("%b", $date_placeholder);// Abbreviated month name, based on the locale
if ($rows[$i]['month'] == $month) {
echo ' <a href="archive/'.$year."/".$month.'/" title="'.$month_name.' '.$year.'">'.strtolower($month_abbrev).'</a> ';
$i++;
} else {
echo ' '.strtolower($month_abbrev).' ';
}
}
echo "<br />";
}
echo '</p></div>';
} else { // Year and/or Month selected, display the appropriate articles
echo '</h2>';
$query = 'SELECT id FROM '._PRE.'articles'.'
WHERE position = 1
AND published = 1
AND visible = \'YES\'
'.$a1.'
'.$a2.'
ORDER BY date DESC
LIMIT '."$start, $size";
$result = mysql_query($query);
$count = mysql_num_rows($result);
if ($count === 0) {
echo '<p>'.l('no_articles').'</p>';
} else {
while ($r = mysql_fetch_array($result)) {
$or_id[] = 'a.id ='.$r['id'];
}
$or_id = implode(' OR ',$or_id);
$query = 'SELECT
title,a.seftitle AS asef,a.date AS date,
c.name AS name,c.seftitle AS csef,
x.name AS xname,x.seftitle AS xsef
FROM '._PRE.'articles'.' AS a
LEFT OUTER JOIN '._PRE.'categories'.' as c
ON category = c.id
LEFT OUTER JOIN '._PRE.'categories'.' as x
ON c.subcat = x.id
WHERE ('.$or_id.')
AND a.published = 1
AND c.published =\'YES\'
AND (x.published =\'YES\' || x.published IS NULL)
ORDER BY date DESC
LIMIT '."$start, $size";
$result = mysql_query($query);
$month_names = explode(', ', l('month_names'));
echo '<div class="arc_list"><p>';
while ($r = mysql_fetch_array($result)) {
$year = substr($r['date'], 0, 4);
$month = substr($r['date'], 5, 2) -1;
$day = substr($r['date'], 8, 2);
$month_name = (substr($month, 0, 1) == 0) ? $month_names[substr($month, 1, 1)] : $month_names[$month];
if ($last <> $year.$month) {
echo '<strong>'.$month_name.', '.$year.'</strong><br />';
}
$last = $year.$month;
$link = isset($r['xsef']) ? $r['xsef'].'/'.$r['csef'] : $r['csef'];
echo l('divider').' <a href="'._SITE.$link.'/'.$r['asef'].'/">
'.$r['title'].' ('.$r['name'].')</a><br />';
}
echo'</p></div>';
}
}
}
OK, now upload your modified sNews.php file and then check out your archive page, it should look similar to mine now.
You may also add styles to your archive, the DIV containing the date list on the front page has a class of archive_date, and the actual article listings are inside a div with the class of arc_list, these are the styles I use, feel free to use this code if you like;
.archive_date p {
line-height:1.6em;
font-family:"lucida console";
font-size:1.1em;
text-transform:uppercase;
text-align:justify;
}
.arc_list p {
text-align:left;
}
.arc_list p a {
color:#386E80;
}
21 comments
Add a new comment »Categories
Recent Entries
Recent Comments
- Dede (I checked it today in a shop. GT2 had some troubles with six ...)
- Matt (Bintang, You need to re-direct the url, try ...)
- jesth (Ohh.. why didn't I think of that, thanks alot.)
- Matt (Dede, I don't have Gran Turismo 2, any of the 2nd+ generation ...)
- Matt (Jesth, Just change the if condition, instead of looking for ...)
- jesth (Hi (again) Was wondering, is it possible to make it ...)
- Bintang Sembilan (Matt, thanks for your modd. I have apply it to my ...)
- Dede (Hello there. Can you check something for me? I want to buy ...)
- Matt (I think it's a driver issue Terrence, or it was a driver issue. ...)
Popular Entries
- Light-weight related articles mod for sNews 1.7 (4.5/5)
- Image / math hybrid captcha version 2, vastly improved (4.42/5)
- 1024x600 netbook wallpapers of Evangeline Lilly (4.4/5)
- Compact archives for sNews 1.7 (4.4/5)
- sNews Ajax Polls mod now available (4.38/5)
- Pretty date and comments bars in sNews CMS (4.35/5)
- Page caching mod for sNews 1.7 (4.33/5)
- Gravatar mod for sNews 1.7 (4.29/5)
- An improved tag cloud for sNews 1.7 (4.29/5)
Apr 9th, 2009 at 2:45 am
Nice job, working perfectly, actually alot better than my original idea, which was adding all months in my sidebare, I know made a link for 2009 instead, which is more simpler, so again, thanks alot for your efforts.
Apr 10th, 2009 at 7:38 am
Thanks asundrus, I'm glad you found it useful. Your idea about the sidebar isn't a bad idea either, it shouldn't be too hard to make a WordPress style sidebar "archives" list function that works in conjunction with this one.
Apr 10th, 2009 at 5:35 pm
As always great job Matt.
Thanks,
PP
Apr 17th, 2009 at 9:31 am
As usual, it doesn't work for me. :-D
Nothing is extracted:
(http://carnet.hiseo.fr/archive/)
Another bug due to the DB prefix?
Apr 17th, 2009 at 11:03 am
Sven, yep, it's the DB prefix again :), I threw this one up in a real hurry too, so I was expecting problems.
I've updated the function now.
Apr 17th, 2009 at 11:15 am
"(...) so I was expecting problems."
And I came.
Thanks a lot Matt. It's working like a charme now.
Apr 17th, 2009 at 11:36 am
Sven,
Looks good, ecept it appears your PHP locale is set to English, which results in "March" instead of "Mars".
This is an easy runtime fix; you can either add this to the top of your snews.php file to make it run French (I assume that's French :P) language;
or add this on the first line of the archives function to just make date/time localized to French;
Let me know if that doesn't make sense, or you need any help.
Apr 23rd, 2009 at 2:25 am
That makes sense, Matt. I placed setlocale(LC_ALL, 'fr_FR.utf8'); at the top of my snews.
And now my snews speaks french better than inspecteur Clouseau. :-D
Have a nice day pal.
May 4th, 2009 at 7:44 pm
Matt,
I have a problem with this mod.
The years and months are correctly displayed on the archive page.
But when I click a month or a year, nothing happens..
I use a db prefix.
Online at http://nieuwerkerken-aalst.be/snews/archive/
PP
May 4th, 2009 at 7:56 pm
Hey PP, I see the problem, it's b/c your install is in a subfolder, that subfolder is part of the request_uri.
I have updated this function to work with subfolders now. Should work no matter no many folders deep you install sNews now.
May 4th, 2009 at 9:31 pm
Yes yes yes that's it... :-)
Thanks again Matt.
PP
Aug 10th, 2009 at 9:46 am
Thanks for this Matt. Very useful and ever so easy to hack for own purposes (I needed output in lists and with long month names but that's a cinch with the things included in the setup.)
Aug 25th, 2009 at 11:39 am
Just found that mod, which is another great one!!
Thanks again for all your work for the snews community ;)
Jan 25th, 2010 at 9:42 am
Damn this was a better one...
Feb 19th, 2010 at 10:13 am
Uh oh.
Hey Matt when you got time check out my archive.
http://on-air.hiseo.fr/archive
There's a bug with this extra line withe a year=0.
There's something to see with the server: locally I don't have this extra line.
Weirdo.
Feb 19th, 2010 at 11:20 am
Sven, something must be wrong with an article date, as that part is as simple as it gets. Try running this SQL command in your DB admin tool;
SELECT DISTINCT YEAR(date) AS year FROM articles ORDER BY year DESC;See what that returns, and don't forget your table prefix :)
Oh yeah, and check your spam folder for the email comment notification stuff, seems like a lot the notification emails are ending up in people's spam folders... :/
Feb 20th, 2010 at 3:02 am
As usual it was a Sven bug which has been corrected now. Thanks a lot for having helped.
I just checked my spam folder: there is no mail from you in it. ???
Feb 20th, 2010 at 10:13 am
Looks like 1and1 didn't like my MX record and kicked it back, I think I've fixed that now. I've removed your notification entry, so next time you try to subscribe, it should hopefully send you the verify email.
That's why it's still very beta :P
Feb 21st, 2010 at 5:01 am
Oh okey. I was wondering if it was sent by sea or airmail. I'll be waiting for internet in Europe.
Feb 21st, 2010 at 5:03 am
Man you're a genious!!!
It works and it's damn great!
Where do I send my karma?
Feb 21st, 2010 at 8:19 am
LOL Sven, thanks.
There's still a few features I need to finish on the notification mod, once I finish and release my spam mod I'll get back to working on it again.
I use a cronjob to send batch notifications, as an example, if you're subscribed to 3 articles and they each get 2 new comments before the cronjob, then you'll only get 1 email, notifying you of the new comments, with the links to each article, etc.
Another thing you may notice is if you respond to a new comment before the cronjob is run, it won't send that one to you, as you've obviously seen it if you've already responded to it.