Blogger Archive Calendar
Comments and Problems can be reported at the home post for this at
Blogger
Archive Calendar
This is for New Blogger using Layouts templates only (blogspot or
custom domain). Classic Templates not supported.
As with any template modifications, always make a backup before
preceding!
Also, feeds for posts must be enabled in your settings
(Blogger>Dashboard>Settings>Site Feed> Post
Feed can either be set at Full or Short). Private blogs do not have
feeds, so they are not supported.
Step #1
Go to Template>Edit HTML. Leave the Expand Widget Templates
box
UNCHECKED
(default)
This code will replace your Archive widget. Scroll down and find yours
in your template. Will look something like this.
Copy the following code, then highlight the archive widget as shown and
replace it with a paste.
<b:widget
id='BlogArchive1'
locked='false' title='Blog Archive' type='BlogArchive'>
<b:includable id='main'>
<b:if cond='data:title'>
<h2><data:title/></h2>
</b:if>
<div class='widget-content'>
<div id='ArchiveList'>
<div expr:id='data:widget.instanceId +
"_ArchiveList"'>
<b:if cond='data:style ==
"HIERARCHY"'>
<b:include data='data'
name='interval'/>
</b:if>
<b:if cond='data:style ==
"FLAT"'>
<b:include
data='data' name='flat'/>
</b:if>
<b:if cond='data:style ==
"MENU"'>
<b:include
data='data' name='menu'/>
</b:if>
</div>
</div>
<b:include name='quickedit'/>
</div>
</b:includable>
<b:includable id='toggle' var='interval'>
<!-- Toggle not needed for Calendar -->
</b:includable>
<b:includable id='flat' var='data'>
<div id='bloggerCalendarList'>
<ul>
<b:loop values='data:data'
var='i'>
<li
class='archivedate'>
<a
expr:href='data:i.url'><data:i.name/></a>
(<data:i.post-count/>)
</li>
</b:loop>
</ul>
</div>
<div id='blogger_calendar' style='display:none'>
<table id='bcalendar'><caption
id='bcaption'>
</caption>
<!-- Table Header -->
<thead id='bcHead'></thead>
<!-- Table Footer -->
<!-- Table Body -->
<tbody><tr><td id='cell1'>
</td><td id='cell2'>
</td><td id='cell3'>
</td><td id='cell4'>
</td><td id='cell5'>
</td><td id='cell6'>
</td><td id='cell7'>
</td></tr>
<tr><td id='cell8'>
</td><td id='cell9'>
</td><td id='cell10'>
</td><td id='cell11'>
</td><td id='cell12'>
</td><td id='cell13'>
</td><td id='cell14'>
</td></tr>
<tr><td id='cell15'>
</td><td id='cell16'>
</td><td id='cell17'>
</td><td id='cell18'>
</td><td id='cell19'>
</td><td id='cell20'>
</td><td id='cell21'>
</td></tr>
<tr><td id='cell22'>
</td><td id='cell23'>
</td><td id='cell24'>
</td><td id='cell25'>
</td><td id='cell26'>
</td><td id='cell27'>
</td><td id='cell28'>
</td></tr>
<tr><td id='cell29'>
</td><td id='cell30'>
</td><td id='cell31'>
</td><td id='cell32'>
</td><td id='cell33'>
</td><td id='cell34'>
</td><td id='cell35'>
</td></tr>
<tr id='lastRow'><td id='cell36'>
</td><td id='cell37'>
</td></tr>
</tbody>
</table>
<table id='bcNavigation'><tr>
<td id='bcFootPrev'></td>
<td id='bcFootAll'></td>
<td id='bcFootNext'></td>
</tr></table>
<div id='calLoadingStatus' style='display:none;
text-align:center;'>
<script
type='text/javascript'>bcLoadStatus();</script>
</div>
<div id='calendarDisplay'/>
</div>
<script type='text/javascript'>
initCal();</script>
</b:includable>
<b:includable id='posts' var='posts'>
<!-- posts not needed for Calendar -->
</b:includable>
<b:includable id='menu' var='data'>
Configure your calendar archive widget - Edit archive widget
- Flat List - Newest first - Choose any Month/Year Format
</b:includable>
<b:includable id='interval' var='intervalData'>
Configure your calendar archive widget - Edit archive widget
- Flat List - Newest first - Choose any Month/Year Format
</b:includable>
</b:widget>
At this point you may want to save the template. It should save without
any errors, if not then make sure you followed the above, and
copy/pasted correctly.
Now, we need to copy and paste the scripts themselves. If you have an
external server, you can copy the following scripts (removing the
beginning /ending script tags) and save it as a file with the .js
extension, then link to it from the head section. If that doesn't make
any sense to you, don't worry. Just do it this way.
Find in your template the ending
]]></b:skin> tag and the
ending
</head>
tag. It should look something like this in your template
I've highlighted them to show them off. But you want to copy the
following code, and paste it in between these two tags. Here's what you
need.
<!-- Blogger Archive Calendar -->
<script type='text/javascript'>
//<![CDATA[
var bcLoadingImage = "http://phydeauxredux.googlepages.com/loading-trans.gif";
var bcLoadingMessage = " Loading....";
var bcArchiveNavText = "View Archive";
var bcArchiveNavPrev = '◄';
var bcArchiveNavNext = '►';
var headDays = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var headInitial = ["Su","Mo","Tu","We","Th","Fr","Sa"];
// Nothing to configure past this point ----------------------------------
var timeOffset;
var bcBlogID;
var calMonth;
var calDay = 1;
var calYear;
var startIndex;
var callmth;
var bcNav = new Array ();
var bcList = new Array ();
//Initialize Fill Array
var fill = ["","31","28","31","30","31","30","31","31","30","31","30","31"];
function openStatus(){
document.getElementById('calLoadingStatus').style.display = 'block';
document.getElementById('calendarDisplay').innerHTML = '';
}
function closeStatus(){
document.getElementById('calLoadingStatus').style.display = 'none';
}
function bcLoadStatus(){
cls = document.getElementById('calLoadingStatus');
img = document.createElement('img');
img.src = bcLoadingImage;
img.style.verticalAlign = 'middle';
cls.appendChild(img);
txt = document.createTextNode(bcLoadingMessage);
cls.appendChild(txt);
}
function callArchive(mth,yr,nav){
// Check for Leap Years
if (((yr % 4 == 0) && (yr % 100 != 0)) || (yr % 400 == 0)) {
fill[2] = '29';
}
else {
fill[2] = '28';
}
calMonth = mth;
calYear = yr;
if(mth.charAt(0) == 0){
calMonth = mth.substring(1);
}
callmth = mth;
bcNavAll = document.getElementById('bcFootAll');
bcNavPrev = document.getElementById('bcFootPrev');
bcNavNext = document.getElementById('bcFootNext');
bcSelect = document.getElementById('bcSelection');
a = document.createElement('a');
at = document.createTextNode(bcArchiveNavText);
a.href = bcNav[nav];
a.appendChild(at);
bcNavAll.innerHTML = '';
bcNavAll.appendChild(a);
bcNavPrev.innerHTML = '';
bcNavNext.innerHTML = '';
if(nav < bcNav.length -1){
a = document.createElement('a');
a.innerHTML = bcArchiveNavPrev;
bcp = parseInt(nav,10) + 1;
a.href = bcNav[bcp];
a.title = 'Previous Archive';
prevSplit = bcList[bcp].split(',');
a.onclick =
function(){bcSelect.options[bcp].selected =
true;openStatus();callArchive(prevSplit[0],prevSplit[1],prevSplit[2]);return
false;};
bcNavPrev.appendChild(a);
}
if(nav > 0){
a = document.createElement('a');
a.innerHTML = bcArchiveNavNext;
bcn = parseInt(nav,10) - 1;
a.href = bcNav[bcn];
a.title = 'Next Archive';
nextSplit = bcList[bcn].split(',');
a.onclick =
function(){bcSelect.options[bcn].selected =
true;openStatus();callArchive(nextSplit[0],nextSplit[1],nextSplit[2]);return
false;};
bcNavNext.appendChild(a);
}
script = document.createElement('script');
script.src =
'http://www.blogger.com/feeds/'+bcBlogId+'/posts/summary?published-max='+calYear+'-'+callmth+'-'+fill[calMonth]+'T23%3A59%3A59'+timeOffset+'&published-min='+calYear+'-'+callmth+'-01T00%3A00%3A00'+timeOffset+'&max-results=100&orderby=published&alt=json-in-script&callback=cReadArchive';
document.getElementsByTagName('head')[0].appendChild(script);
}
function cReadArchive(root){
// Check for Leap Years
if (((calYear % 4 == 0) && (calYear % 100 != 0)) || (calYear % 400 == 0)) {
fill[2] = '29';
}
else {
fill[2] = '28';
}
closeStatus();
document.getElementById('lastRow').style.display = 'none';
calDis = document.getElementById('calendarDisplay');
var feed = root.feed;
var total = feed.openSearch$totalResults.$t;
var entries = feed.entry || [];
var fillDate = new Array();
var fillTitles = new Array();
fillTitles.length = 32;
var ul = document.createElement('ul');
ul.id = 'calendarUl';
for (var i = 0; i < feed.entry.length; ++i) {
var entry = feed.entry[i];
var link = entry.link[0].href;
var title = entry.title.$t;
var author = entry.author[0].name.$t;
var date = entry.published.$t;
var summary = entry.summary.$t;
isPublished = date.split('T')[0].split('-')[2];
if(isPublished.charAt(0) == '0'){
isPublished = isPublished.substring(1);
}
fillDate.push(isPublished);
if (fillTitles[isPublished]){
fillTitles[isPublished] = fillTitles[isPublished] + ' | ' + title;
}
else {
fillTitles[isPublished] = title;
}
li = document.createElement('li');
li.style.listType = 'none';
li.innerHTML = '<a href="'+link+'">'+title+'</a>';
ul.appendChild(li);
}
calDis.appendChild(ul);
var val1 = parseInt(calDay, 10)
var valxx = parseInt(calMonth, 10);
var val2 = valxx - 1;
var val3 = parseInt(calYear, 10);
var firstCalDay = new Date(val3,val2,1);
var val0 = firstCalDay.getDay();
startIndex = val0 + 1;
var dayCount = 1;
for (x =1; x < 38; x++){
var cell = document.getElementById('cell'+x);
if( x < startIndex){
cell.innerHTML = ' ';
cell.className = 'firstCell';
}
if( x >= startIndex){
cell.innerHTML = dayCount;
cell.className = 'filledCell';
for(p = 0; p < fillDate.length; p++){
if(dayCount == fillDate[p]){
if(fillDate[p].length == 1){
fillURL = '0'+fillDate[p];
}
else {
fillURL = fillDate[p];
}
cell.className = 'highlightCell';
cell.innerHTML = '<a
href="/search?updated-max='+calYear+'-'+callmth+'-'+fillURL+'T23%3A59%3A59'+timeOffset+'&updated-min='+calYear+'-'+callmth+'-'+fillURL+'T00%3A00%3A00'+timeOffset+'"
title="'+fillTitles[fillDate[p]].replace(/"/g,'\'')+'">'+dayCount+'</a>';
}
}
if( dayCount > fill[valxx]){
cell.innerHTML = ' ';
cell.className = 'emptyCell';
}
dayCount++;
}
}
visTotal = parseInt(startIndex) + parseInt(fill[valxx]) -1;
if(visTotal >35){
document.getElementById('lastRow').style.display = '';
}
}
function initCal(){
document.getElementById('blogger_calendar').style.display = 'block';
var bcInit = document.getElementById('bloggerCalendarList').getElementsByTagName('a');
var bcCount = document.getElementById('bloggerCalendarList').getElementsByTagName('li');
document.getElementById('bloggerCalendarList').style.display = 'none';
calHead = document.getElementById('bcHead');
tr = document.createElement('tr');
for(t = 0; t < 7; t++){
th = document.createElement('th');
th.abbr = headDays[t];
scope = 'col';
th.title = headDays[t];
th.innerHTML = headInitial[t];
tr.appendChild(th);
}
calHead.appendChild(tr);
for (x = 0; x <bcInit.length;x++){
var stripYear= bcInit[x].href.split('_')[0].split('/')[3];
var stripMonth = bcInit[x].href.split('_')[1];
bcList.push(stripMonth + ','+ stripYear + ',' + x);
bcNav.push(bcInit[x].href);
}
var sel = document.createElement('select');
sel.id = 'bcSelection';
sel.onchange = function(){var cSend =
this.options[this.selectedIndex].value.split(',');openStatus();callArchive(cSend[0],cSend[1],cSend[2]);};
q = 0;
for (r = 0; r <bcList.length; r++){
var selText = bcInit[r].innerHTML;
var selCount = bcCount[r].innerHTML.split('> (')[1];
var selValue = bcList[r];
sel.options[q] = new Option(selText + ' ('+selCount,selValue);
q++
}
document.getElementById('bcaption').appendChild(sel);
var m = bcList[0].split(',')[0];
var y = bcList[0].split(',')[1];
callArchive(m,y,'0');
}
function timezoneSet(root){
var feed = root.feed;
var updated = feed.updated.$t;
var id = feed.id.$t;
bcBlogId = id.split('blog-')[1];
upLength = updated.length;
if(updated.charAt(upLength-1) == "Z"){timeOffset = "+00:00";}
else {timeOffset = updated.substring(upLength-6,upLength);}
timeOffset = encodeURIComponent(timeOffset);
}
//]]>
</script>
<script src='/feeds/posts/summary?max-results=0&alt=json-in-script&callback=timezoneSet'></script>
<!-- End Blogger Archive Calendar -->
As of May 4 2007 the scripts will autodetect your timezone settings.
Nothing here has to be changed, but there are a few things that some
people may want to configure (especially non-English blogs) but for now
the defaults will do. If you want to change
some things (especially if you have a non-English blog) then check out
the full list at the
Blogger
Archive Calendar Settings Page
Now save your template. It should save without errors, if not recheck
your steps above. One more thing needs to be configured in your Archive
Widget. Goto the Page Elements page, find your Archive Widget, and
click to edit it. You'll see a screen like this
The title can be anything you want. The style MUST be Flat List as
show. Options should NOT have Show Oldest Posts firsts checked. Archive
Frequency MUST be Monthly. The Date Format can be anything you want.
The calendar will accept whatever you decide here.
Save the widget. Then try it out. Go view your blog and if everything
is correct you should have the calendar working now.
If you've made it this far, and it's working you'll note that without
any style associated with it the calendar is a bit plain. But we've got
some of that covered as well. Admire your work so far. Make sure it
seems to function.
To style the calendar, you can add some CSS entries. I've made up a few
default styles to choose from. If you are knowledgeable in CSS than you
can use the base ones to come up with your own. Or you can pick from
what I've already whipped up ( I may add a few more as time goes by).
All the styles I currently have are on their own page, with
instructions on how to use.
Check it out at
Blogger Archive Calendar Styles
Quicklinks to the code sections
Step 1
Step 2