Esti blogger de Blogger? Expune-ti arhiva intr-un calendar!

Cum ziceam, este important, chiar esential, ca articolele tale sa fie usor de gasit pe site - in special daca-s bune. Cu cat oferi cititorului mai multe moduri de a cauta si a gasi, cu atat mai bine. In aceasta idee ne-am uitat in trecut la Tag Cloud si Blogumus si la articole aleatoare si azi ne uitam la arhiva sub forma de calendar.

Intreaga serie lucrand la fatada slujeste scopul unei prezentari mai la obiect. Azi ne uitam la cum sa-ti prezinti arhiva articolelor sub forma de calendar. Blogger ofera (cel putin in momentul de fata) 3 modalitati de prezentare a arhivei. Prima si cea mai draguta este o ierarhie tip "tree" (copac), unde fiecare luna este o tulpina expandabila apasand pe triunghiul din dreptul ei. Problema cu aceasta prezentare este ca ocupa un spatiu variabil ca lungime, in functie de cate articole ai scris in luna respectiva. Asta produce variatii indezirabile in lungimea coloanei in care se afla acest modul, in special la inceputul unei noi luni, dand impresia de mizerie (ca sa folosesc un cuvant extrem de popular). Nici celelalte posibilitati nu sunt nemaipomenite. Desi ocupa un spatiu fix, sunt mai dificil de folosit.

Cand prezinti arhiva sub forma de calendar, oferi o metafora vizuala pe care cititorii tai o vor intelege, in masura in care sunt oameni si nu bots. Un calendar este usor de folosit si este chiar fun, incurajand explorarea: "hmm, acum 18 zile eu intram in ciclu si-nfigeam agrafe in coitzele motanului - ia sa vedem, ce-a scris el atunci?".

Din fericire, au si altii motani si cineva a stat sa creeze un astfel de hack. Hack-ul consta in doua parti. In prima, pui niste javascript in sectiunea de inceput a sablonului (deasupra lu' </head>), iar in cea de-a doua pui codul propriu-zis de arhiva. Eu voi prezenta un mod de instalare mai simplu decat cel din sursa pe care il voi testa pe propriul sablon.

Prima miscare este sa copiezi scripturile si variabilele in capul sablonului. Pentru asta, poti folosi punctele 1-6 de la articoul despre Tag Clouds, facand urmatoarele substitutii: la 3, vei cauta </head>, iar la 4 vei pune urmatorul cod deasupra lui </head>, dupa cum apare-n poza:

baga codul intre /head si b:skin

Iata si codul. Selecteaza-l pe tot, copiaza-l si pune-l deasupra tagului </head>:

<!-- 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 = '&#9668;';
var bcArchiveNavNext = '&#9658;';
var headDays = ["Duminica","Luni","Marti","Miercuri","Joi","Vineri","Sambata"];
var headInitial = ["Du","Lu","Ma","Mi","Jo","Vi","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];
      for (var j = 0; j < entry.link.length; ++j) {
       if (entry.link[j].rel == "alternate") {
       var link = entry.link[j].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&amp;alt=json-in-script&amp;callback=timezoneSet'></script>
<!-- End Blogger Archive Calendar -->

Salveaza sablonul, si pregateste-te spiritual pentru urmatorul pas care este el. Care este el?

A doua miscare este sa selectezi in intregime si apoi sa copiezi (Ctrl+C) codul de mai jos.

<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>

Cauti apoi codul pentru arhiva existenta (ai una, nu? daca nu, fa-ti) si-o inlocuiesti dupa cum urmeaza. Cauta <b:widget id=BlogArchive folosind Ctrl+F sau ce functie de cautat in pagina are browserul tau. Cand o gasesti, selecteaza intreaga linie astfel:

cauta <b:widget id=BlogArchive si selecteaza intreaga linie astfel:

Codul poate arata un pic diferit de ce vezi mai sus, dar nu-i bai cata vreme este 90% identic. Dupa ce-ai selectat, faci paste la codul de deasupra (pe care l-ai copiat mai devreme).

Salveaza iar sablonul. Daca ai vreo eroare, verifica daca ai copiat codul in intregime.

Ultimul pas este sa te duci in Dashboard -> Layout -> Page Layout si sa modifici Arhiva dupa cum urmeaza (poate e bine sa-ncepi cu asta, dar chiar dac-ai inceput cu asta, mai mergi o data sa fii sigur c-o poti accesa). Poti desigur sa schimbi titlul cum iti place, dar ai grija sa indeplinesti urmatoarele conditii, dupa cum apare in puoza:

poza proprietatilor Arhive de blog

In sumar:

titlul poate fi orice

stilul TREBUIE sa fie Flat List

"Show Oldest Posts First" tre' sa fie unchecked (articolele sa fie in ordine cronologica)

Frecventa arhivarii tre sa fie monthly (lunara)

Formatul datei poate fi iarasi orice

Daca ai urmat aceste instructiuni si-au mers, spune-mi. Dar multurmirile adreseaza-le autorului, ca el si-a muncit creierii Smile

20090810 UPDATE: Vrei mai multe articole tehnice pentru Blogger / Blogspot? Este modificarea de aici curenta, sau am facut una noua, cu acelasi efect, dar mai buna? Toate modificarile aduse de mine acestui sablon (template) pot fi gasite in Zamolxis ChangeLog. Seria lucrand la fatada va gazdui de-acu’ incolo articole despre PR, media persuasion si eventual imaginea Romaniei.

8 comments:

  1. Salutare.
    E foarte bun codul.
    Vreau sa fac un blog numai pentru audiofili: www.audio-muzica.blogspot.com si nu reusesc sa pun categorii. Daca poti sa ma ajuti un pic.
    Mersi

    ReplyDelete
  2. sigur ca da! spune-mi ce-ai incercat si ce s-a-ntamplat.

    ReplyDelete
  3. salut,sunt nistor george si as avea nevoie de ajutorul tau, nu stiu cum sa postez in categorie, ma refer la meniu, am meniu tot ce trebuie la aceasta tema(blogpot) practic cred ca este vorba de arhiva ,cred ca de acolo ar trebui luat link-ul care trebuie introdus in categoria respectiva, te rog frumos sa ma ajuti, am luat contactul cu tine pe mess, daca mai tii minte....multumesc....ma ajuti? id-ul meu corleone115

    ReplyDelete
  4. @george: voi scrie un articol pentru Sambata unde voi incerca sa raspund pe larg intrebarii.

    ReplyDelete
  5. ioi ce coduri!am ramas socat cand le-am copiat in notepad..am facut pt blogul meu si a mers. i'm happy. Multumesc

    ReplyDelete

Thank you for commenting, but comments entered in this version may not appear.
Felicitări pentru decizia de a comenta! Orice comentariu este bine-venit :).
Din moment ce vezi acest mesaj, accesezi pagina printr-o metoda alternativa si este posibil sa comentezi neobservat(a). Metoda preferabila este prin pagina normala, care contine Disqus; odata inregistrat, acesta iti permite sa comentezi prin reply la email.
Dacă ai intrebări, există răspunsuri - FAQ.
Baftă!