Showing posts with label hack. Show all posts
Showing posts with label hack. Show all posts

Friday, April 20, 2007

Peek-A-Boo Modified: Add 'Summary only' at top

Peek-A-Boo is great! but I decide to add a extra 'summary only' link at top of the full post.

There is 2 thing I will have to do.
1. backup your template. ( always, always... trust me , I know..)
2. Adding a 'top link' into html.
Add the part in highlight into html (remeber to click 'Expand widget template'):
<blockquote class='code'><em><span id='hidelink2' style='display:none'>
<p><a expr:onclick='"javascript:hideFull(\"post-" + data:post.id + "\");"' href='javascript:void(0);'>Summary only (只顯示摘要)...</a></p>
</span>

<style>#fullpost {display:none;}</style>
<p><data:post.body/></p>
<span id='showlink'>
<p><a expr:onclick='"javascript:showFull(\"post-" + data:post.id + "\");"' href='javascript:void(0);'>Read More (全文);...</a></p>
</span>
<span id='hidelink' style='display:none'>
<p><a expr:onclick='"javascript:hideFull(\"post-" + data:post.id + "\");"' href='javascript:void(0);'>Summary only...</a></p>
</span>


2. Let javascript to turn it on or off depends on current stats.
Add the part in highlite into 'hackosphere.js'


function showFull(id) {
var post = document.getElementById(id);
var spans = post.getElementsByTagName('span');
for (var i = 0; i < spans.length; i++) {
if (spans[i].id == "fullpost")
spans[i].style.display = 'inline';
if (spans[i].id == "showlink")
spans[i].style.display = 'none';
if (spans[i].id == "hidelink")
spans[i].style.display = 'inline';
if (spans[i].id == "hidelink2")
spans[i].style.display = 'inline';

}
}




function hideFull(id) {
var post = document.getElementById(id);
var spans = post.getElementsByTagName('span');
for (var i = 0; i < spans.length; i++) {
if (spans[i].id == "fullpost")
spans[i].style.display = 'none';
if (spans[i].id == "showlink")
spans[i].style.display = 'inline';
if (spans[i].id == "hidelink")
spans[i].style.display = 'none';
if (spans[i].id == "hidelink2")
spans[i].style.display = 'none';

}
post.scrollIntoView(true);
}


Thursday, April 19, 2007

AJAX Label - Tuned 加強版

AJAX Label from Deepak 非常適用於帖數多的部落格。
由於AJAX Labels每次只抓取和標籤有關的帖子,因此就算帖數再多也不會造成下載拖牛車的情形。
我為一不滿的部分是AJAX Lables所顯示出來的資料中,相關標籤無法被click。
經過一番研究後,我將之改成所有傳回的相關標籤都可以被連結到新的標籤搜尋。

The AJAX Label from Deepak is great!
Especially if you have a couple hundreds of posts in your blog.
Since it only retrieve the label you chose from Blogger, it is capable to deal with large blogs.
But the label list in the result entry is not click able.
I took the liberty to add this feature into original code.

The file is ajaxlabels.js

find the line
catdisplay.innerHTML+=xentry.category[j].term;

and change it into
catdisplay.innerHTML+='<a href="javascript:getCat(\'' + xentry.category[j].term + '\')" >'+xentry.category[j].term+'</a>';

Wednesday, April 18, 2007

Searchable Blogger Labels 標籤搜尋




The problem with Blogger's label is after intensive usage it tends to grow to a size which is impossible to manage.

This Label Search function is an extension of Beautiful Beta's TOC widgets.
It will allow you to quick search any label you have.
Best of all is, this is case-sensitive partial search, so you can use 'Eng' or 'glis' it will all find 'English' for you.
Now all we need is an 'and' 'or' 'not' operand to this search..

ps. this opens a possibility of using my.favorite.photo as tag.
Since if you type in 'photo' the list will all the files containes
my.favorite.photo
2005.trip.photo
flower.photo.collected
it is much easy to chose from.
and if you are good , just type 'te.phot' you get 'my.favorite.photo'

Blogger標籤(labels) 最大的問題是經過大量的使用之後,標籤的數量變得龐大而且難以管理。
一如Google的作法,我擴充了Beautiful Beta的目錄原件(TOC Widget)增加了『標籤檢索』功能。
更重要的是,這個檢索是「部分檢索」因此鍵入「Chi」或「nes」都會讓你找到「Chinese」。
現在我們所需要的只是「或」「和」「非」等邏輯運算而已。

附註: 「部分檢索」提供了使用新標籤可能性。我們可以用 「my.favorite.photo」當標籤。
因為你只要鍵入「photo」就能找到以下的標籤
my.favorite.photo
2005.trip.photo
flower.photo.collected
標籤變得非常容易使用。
假如你真的要快的話,可以鍵入 「te.phot」 你就會找到 'my.favorite.photo'而不是其他的標籤。

<form action="#" name="label_search">
<input onkeyup=" javascript:filterPosts(document.label_search.target.value)"
name="target" type="TEXT"/>
</form>

Tuesday, April 17, 2007

Table of Content Installed

Thanks to Hans in Beautiful Beta, you are the man Hnas :)

instructions after the jump

Step 1: Back Up your Template.

Step 2: Add a HTML Page Element
Edit your template in HTML-mode, and look for the <b:section> with id=main. This is the section that holds the Blog posts.
Change that line as follows:

<b:section class='main' id='main' maxwidgets='2' showaddelement='yes'>


Save the template and switch to the Page Elements Tab.
Add a HTML page element above your Blog Posts element.
Leave the title blank. Add the following html:

<div id="toc"></div>


Save your template.

Step 3: Add a Sidebar HTML-element
Now add a HTML-element to the sidebar. Set the title to "TOC".
For the contents, enter:


<div id="toclink"><a href="javascript:showToc();">Show TOC</a><br/><br/></div>
<script style="text/javascript" src="http://home.planet.nl/~hansoosting/downloads/blogtoc.js"></script>
<script src="http://YOURBLOG.blogspot.com/feeds/posts/default?alt=json-in-script&max-results=999&callback=loadtoc"></script>


Replace YOURBLOG with the name of ...... exactly.
Oh yes, and save.

Step 4: Add custom styles to the skin of your template.
New id's and classes are:
#toc : the div-wrapper that contains the TOC
.toc-header-col1 : header of column 1
.toc-header-col2 : header of column 2
.toc-header-col3 : header of column 3
.toc-entry-col1 : cell in column 1
.toc-entry-col2 : cell in column 2
.toc-entry-col3 : cell in column 3

For your convenience: Beautiful Beta uses the following styling:

<style type="text/css">
#toc {
border: 0px solid #000000;
background: #ffffff;
padding: 5px;
width:500px;
margin-top:10px;
}
.toc-header-col1, .toc-header-col2, .toc-header-col3 {
background: #ffd595;
color: #000000;
padding-left: 5px;
width:250px;
}
.toc-header-col2 {
width:75px;
}
.toc-header-col3 {
width:125px;
}
.toc-header-col1 a:link, .toc-header-col1 a:visited, .toc-header-col2 a:link, .toc-header-col2 a:visited, .toc-header-col3 a:link, .toc-header-col3 a:visited {
font-size:80%;
text-decoration:none;
}
.toc-header-col1 a:hover, .toc-header-col2 a:hover, .toc-header-col3 a:hover {
font-size:80%;
text-decoration:underline;
}

.toc-entry-col1, .toc-entry-col2, .toc-entry-col3 {
padding-left: 5px;
font-size:70%;
}
</style>


You can add this to the <b:skin>-part of the template, or insert it in the sidebar widget.

If you have more than 100 posts, you have to duplicate the JSON-script-call that is in your sidebar several times, each time with a different start-index. If you have more than 100 posts, you need 2 calls like this:
<script src="http://YOURBLOG.blogspot.com/feeds/posts/default?alt=json-in-script&start-index=1&max-results=100&callback=loadtoc"></script>
<script src="http://YOURBLOG.blogspot.com/feeds/posts/default?alt=json-in-script&start-index=101&max-results=100&callback=loadtoc"></script>

Monday, April 16, 2007

PullQuote (格言引用)installed

這是『格言引用』模組
thiis is a pull quote example

<blockquote class="pullquote" >this is a pullquote</blockquote> :
this is a pullquote


<b><blockquote class="goodquote" >this is a goodquote</blockquote></b>:
this is a goodquote


<blockquote class="goodquote" >this is a goodquote</blockquote>
this is a goodquote


Since I disable float attribute, the text will be inlined.
<blockquote class="code" >this is a code segment</blockquote>
this is a code segment




To install a Pullquotes in Blogger

add following code in data definition area

<Variable name="pullquoteBgColor" description="PullQuote Bg Color"
type="color" default="#333" value="#333333">
<Variable name="pullquoteTextColor" description="PullQuote Text Color"
type="color" default="#333" value="#ffff66">
<Variable name="pullquoteBoarderColor" description="PullQuote Boarder Color"
type="color" default="#333" value="#333333">


then insert this code segment:
.pullquote {
width: 15%;
background-color:$pullquoteBgColor;
/* background-image: url(http://home.planet.nl/~hansoosting/images/quotes_grey.gif); */
background-image: url(http://fontalis.com/images/quotes_grey_small.gif);
background-repeat: no-repeat;
color:$pullquoteTextColor;
float: right;
border:1px solid $pullquoteBoarderColor;
font-weight:bold;
line-height:120%;
padding:40px 10px 10px 10px;
margin-top:10px;
margin-left:10px;
}

Thanks to Hans of Beatuful Beta

Calendar Archive Installed

Blogger Calendar Archive
by PurpleMoggy


Installation instructions:

Go to Template -> Edit HTML and add the following between the <head> tags

<script type="text/javascript" src="http://yui.yahooapis.com/2.2.0/build/yahoo-dom-event/yahoo-dom-event.js"></script>
<script type="text/javascript" src="http://yui.yahooapis.com/2.2.0/build/calendar/calendar-min.js"></script>
<link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.2.0/build/calendar/assets/calendar.css"/>

Now add the following between the <head> tags (beneath what you already added)

<script type="text/javascript">
//<![CDATA[
/*
Created by: PurpleMoggy
http://purplemoggy.blogspot.com
*/

var _yourBlogUrl = "http://purplemoggy.blogspot.com"; //edit this
var _yourBlogTimeZone = "-08:00"; //edit this

_yourBlogTimeZone = encodeURIComponent(_yourBlogTimeZone);

var _dayTitles = new Array("","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","");

YAHOO.namespace("example.calendar");

function cal1Init() {
YAHOO.example.calendar.cal1 = new YAHOO.widget.Calendar("cal1","cal1Container");
YAHOO.example.calendar.cal1.addMonthRenderer(1, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(2, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(3, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(4, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(5, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(6, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(7, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(8, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(9, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(10, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(11, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.addMonthRenderer(12, YAHOO.example.calendar.cal1.renderBodyCellRestricted);
YAHOO.example.calendar.cal1.selectEvent.subscribe(mySelectHandler, YAHOO.example.calendar.cal1, true);
YAHOO.example.calendar.cal1.changePageEvent.subscribe(myChangePageHandler, YAHOO.example.calendar.cal1, true);
YAHOO.example.calendar.cal1.renderEvent.subscribe(syncMonthYear);
YAHOO.example.calendar.cal1.render();
myChangePageHandler();
};


var myChangePageHandler = function(type,args,obj) {
var month = YAHOO.example.calendar.cal1.cfg.getProperty("pagedate").getMonth() + 1;
if (month.toString().length == 1) {
month = "0" + month;
}
var year = YAHOO.example.calendar.cal1.cfg.getProperty("pagedate").getFullYear();

document.getElementById("cal1Titles").innerHTML = "";
_dayTitles = new Array("","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","");

checkPostsForMonth(month, year);
};

function checkPostsForMonth(month,year) {
document.getElementById("cal1loadimg").style.display = "block";

var script = document.createElement("script");
script.setAttribute("type", "text/javascript");
var theUrl = _yourBlogUrl +"/feeds/posts/summary?alt=json-in-script&callback=checkPostsCallback&published-min=" + year + "-" + month + "-01T00%3A00%3A00" + _yourBlogTimeZone + "&published-max=" + year + "-" + month + "-31T23%3A59%3A59" + _yourBlogTimeZone + "&max-results=100";
script.setAttribute("src", theUrl);
document.documentElement.firstChild.appendChild(script);
};

function checkPostsCallback(json) {

if (json.feed.entry) {
for(i = 0; i < json.feed.entry.length; i++) {
var month = json.feed.entry[i].published.$t.substr(5,2);
var year = json.feed.entry[i].published.$t.substr(0,4);
var day = json.feed.entry[i].published.$t.substr(8,2);
var date = month + "/" + day + "/" + year;
var href = json.feed.entry[i].link[0].href;
var title = json.feed.entry[i].title.$t;

if (day.substr(0,1) == "0") {
day = day.substr(1);
}

document.getElementById("cal1Titles").innerHTML += "<li><a href='" + href + "'>" + title + "</a>";
_dayTitles[day] += "<li><a href='" + href + "'>" + title + "</a>";

YAHOO.example.calendar.cal1.addRenderer(date, myCustomRenderer);

}
YAHOO.example.calendar.cal1.render();
}

document.getElementById("cal1loadimg").style.display = "none";

};


function showDayTitles(day) {
document.getElementById("cal1Titles").innerHTML = _dayTitles[day];
}


var myCustomRenderer = function(workingDate, cell) {

var day = workingDate.toString().substr(8,2);
if (day.substr(0,1) == "0") {
day = day.substr(1);
}


cell.innerHTML = '<div onmouseover="showDayTitles(' + day + ');"><a href="javascript:void(null);" >' + YAHOO.example.calendar.cal1.buildDayLabel(workingDate) + "</a></div>";
YAHOO.util.Dom.addClass(cell, YAHOO.example.calendar.cal1.Style.CSS_CELL_SELECTABLE);
YAHOO.util.Dom.addClass(cell, YAHOO.example.calendar.cal1.Style.CSS_CELL_HIGHLIGHT1);
return YAHOO.widget.Calendar.STOP_RENDER;


}

var mySelectHandler = function(type,args,obj) {
var dates = args[0];
var date = dates[0];
var year = date[0];
var month = date[1];
if (month.toString().length == 1) {
month = "0" + month;
}
var day = date[2];

var element = YAHOO.util.Dom.getElementsByClassName("d" + day, "td", "cal1Container")[0];

if (day.toString().length == 1) {
day = "0" + day;
}

if (element.className.indexOf("highlight1") != -1) {
window.location = _yourBlogUrl + "/search?updated-min=" + year + "-" + month + "-" + day + "T00%3A00%3A00" + _yourBlogTimeZone + "&updated-max=" + year + "-" + month + "-" + day + "T23%3A59%3A59" + _yourBlogTimeZone;
}

};

var changeDate = function() {
YAHOO.example.calendar.cal1.setMonth(parseInt(YAHOO.util.Dom.get("cal1monthselect").value));
YAHOO.example.calendar.cal1.setYear(parseInt(YAHOO.util.Dom.get("cal1yearselect").value));
YAHOO.example.calendar.cal1.render();
myChangePageHandler();
}

var syncMonthYear = function(type) {
YAHOO.util.Dom.get("cal1monthselect").value = parseInt(YAHOO.example.calendar.cal1.cfg.getProperty("pagedate").getMonth());

var fullYear = parseInt(YAHOO.example.calendar.cal1.cfg.getProperty("pagedate").getFullYear());

var isYearFound = false;
var i = 0;
while(i < document.getElementById("cal1yearselect").options.length && !isYearFound) {
if (document.getElementById("cal1yearselect").options[i].value == fullYear) {
isYearFound = true;
}
i++;
}
if (!isYearFound) {
var option = document.createElement("option");
option.setAttribute("value", fullYear);
var text = document.createTextNode(fullYear);
option.appendChild(text);
document.getElementById("cal1yearselect").appendChild(option);
}

YAHOO.util.Dom.get("cal1yearselect").value = fullYear;
};

YAHOO.util.Event.addListener(window, "load", cal1Init);
YAHOO.util.Event.addListener("cal1dateselect", "click", changeDate);
//]]>
</script>

Finally, go to Template -> Page Elements and add a new HTML/Javascript element with the following

<div id="cal1wrapper">

<div id="cal1select">

<select name="cal1monthselect" id="cal1monthselect">
<option value="0">January</option>
<option value="1">February</option>
<option value="2">March</option>
<option value="3">April</option>
<option value="4">May</option>
<option value="5">June</option>
<option value="6">July</option>
<option value="7">August</option>
<option value="8">September</option>
<option value="9">October</option>
<option value="10">November</option>
<option value="11">December</option>
</select>
<select name="cal1yearselect" id="cal1yearselect">
<option value="1995">1995</option>
<option value="1996">1996</option>
<option value="1997">1997</option>
<option value="1998">1998</option>
<option value="1999">1999</option>
<option value="2000">2000</option>
<option value="2001">2001</option>
<option value="2002">2002</option>
<option value="2003">2003</option>
<option value="2004">2004</option>
<option value="2005">2005</option>
<option value="2006">2006</option>
<option value="2007">2007</option>
<option value="2008">2008</option>
<option value="2009">2009</option>
<option value="2010">2010</option>
<option value="2011">2011</option>
<option value="2012">2012</option>
<option value="2013">2013</option>
<option value="2014">2014</option>
<option value="2015">2015</option>
<option value="2016">2016</option>
<option value="2017">2017</option>
<option value="2018">2018</option>
<option value="2019">2019</option>
</select>
<input type="button" value="-->" id="cal1dateselect"/>

</div>

<div id="cal1Container"></div>
<div style="clear:both;"></div>

<div id="calbackloadimg">
<pre id="cal1loadimg" style="display:none;"><img src="http://img239.imageshack.us/img239/9057/40lf8.gif" style="vertical-align:middle;"/> Loading...</pre>
<pre id="cal1Titles"></pre>
</div>

</div>

Required Modifications
In the 2nd code-box above, you'll need to edit the following 2 variables

_yourBlogUrl needs to be changed to your blog URL (don't add the trailing slash)
http://purplemoggy.blogspot.com <-- CORRECT
http://purplemoggy.blogspot.com/ <-- WRONG

_yourBlogTimeZone needs to be changed to the timezone offset that your blog is set to
If your timezone is UTC-08:00 then you'd enter -08:00 here
If your timezone is UTC-07:00 then you'd enter -07:00, etc.


You should be able to modify just about everything from the CSS file. You'll have to download it here and upload it somewhere else of your choosing.
http://yui.yahooapis.com/2.2.0/build/calendar/assets/calendar.css

There's 3 images here that you could also replace.
is defined in the CSS
is defined in the CSS
is located towards the bottom of the 3rd code-box above. It's the Arrows image from http://www.ajaxload.info/

Note: I removed Calendar Archive, because it is redundant with 'recent post' and it has bigger overhead.

Peek-A-Boo Installed

Installation instruction after jump.


Step 0:
Back-up your template before modifying it.

Step 1:
Add the following javascript code to the head of your template. You can place it just above the </head>-tag.
<script type='text/javascript' src='http://www.anniyalogam.com/widgets/hackosphere.js' />


Step 2:

Find the includable named 'post' in your template, and change it so that it is exactly as shown below (the code in highlite has to be added):

<b:includable id='post' var='post'>
<div class='post'>
<a expr:name='data:post.id'/>
<b:if cond='data:post.title'>
<h3 class='post-title'>
<b:if cond='data:post.url'>
<a expr:href='data:post.url'><data:post.title/></a>
<b:else/>
<data:post.title/>
</b:if>
</h3>
</b:if>
<div class='post-header-line-1'/>

<div class='post-body' expr:id='"post-" + data:post.id'>
<b:if cond='data:blog.pageType == "item"'>
<p><data:post.body/></p>

<b:else/>
<style>#fullpost {display:none;}</style>
<p><data:post.body/></p>
<span id='showlink'>
<p><a expr:onclick='"javascript:showFull(\"post-" + data:post.id + "\");"' href='javascript:void(0);'>Read More...</a></p>
</span>
<span id='hidelink' style='display:none'>
<p><a expr:onclick='"javascript:hideFull(\"post-" + data:post.id + "\");"' href='javascript:void(0);'>Summary only...</a></p>
</span>
<script type='text/javascript'>checkFull("post-" + "<data:post.id/>")</script>
</b:if>

<div style='clear: both;'/> <!-- clear for photos floats -->
</div>
</div>
.... rest of template code ....

Save your template.

Step 3:
In the Settings - Formatting tab go to the bottom and enter the following post-template:

Type your summary here.
<span id="fullpost">

Type the rest of your post here.
</span>

Modify on side margin (cosmetic)


change

#header {
margin: 0 1%;


into
#header {
margin: 0 0.5%;

change
h1.title {
padding-top: 38px;
margin: 0 1% .1em;

into

h1.title {
padding-top: 38px;
margin: 0 1% .1em;
#header .description {
display: block;
margin: 0 1%;


into

#header .description {
display: block;
margin: 0 0.5%;

change
#content-wrapper {
margin: 0 1%;

into

#content-wrapper {
margin: 0 0.5%;

Second Sidebar Installed.

Thanks to Hans of Beautiful Beta

Installation instruction after jump.

This Layout has 4 sections: Header, Main (with the Blog Posts), Sidebar and Footer.
The HTML-template looks like this (the line-numbers are added for reference only):

010: <body>
020: <div id='outer-wrapper'>l<div id='wrap2'>
030: <!-- skip links for text browsers -->
040: <span id='skiplinks' style='display:none;'>
050: <a href='#main'>skip to main </a>
060: <a href='#sidebar'>skip to sidebar</a>
070: </span>
080: <div id='header-wrapper'>
090: <b:section class='header' id='header' maxwidgets='1' showaddelement='no'>
100: <b:widget id='Header1' locked='true' title='Second Sidebar (Header)' type='Header'/>
110: </b:section>
120: </div>
130: <div id='content-wrapper'>
140: <div id='main-wrapper'>
150: <b:section class='main' id='main' showaddelement='no'>
160: <b:widget id='Blog1' locked='true' title='Blog Posts' type='Blog'/>
170: </b:section>
180: </div>
190: <div id='sidebar-wrapper'>
200: <b:section class='sidebar' id='sidebar' preferred='yes'>
210: <b:widget id='BlogArchive1' locked='false' title='Blog Archive' type='BlogArchive'/>
220: <b:widget id='Profile1' locked='false' title='About Me' type='Profile'/>
230: </b:section>
240: </div>
250: <!-- spacer for skins that want sidebar and main to be the same height-->
260: <div class='clear'> </div>
270: </div> <!-- end content-wrapper -->
280: <div id='footer-wrapper'>
290: <b:section class='footer' id='footer'/>
300: </div>
310: </div></div> <!-- end outer-wrapper -->
320: </body>

Lines 010 and 320 are the body-tags. All your code has to be between these two tags.

Lines 020 and 310 are the div-tags for two wrappers, the wrapper called "outer-wrapper" and the wrapper called "wrap2". In CSS you can define fonts, colors, and other styling for these wrappers. We'll look into CSS later in this tutorial.

Lines 080 to 120 contain the header. As you see, there is a div-wrapper (080 and 120), section-tags (090 and 110) and the widget that contains the header itself (100).

Lines 130 to 270 contain the content. Content means here: blog posts and sidebar. There is a div-wrapper called "content-wrapper" (130 and 270), and inside this wrapper there are 2 more wrappers: the "main-wrapper" (140-180) and the "sidebar-wrapper" (190-240).

Inside the main-wrapper we find the main-section (150 and 170) with the Blog-widget (160). This widget contains your posts.

Inside the sidebar-wrapper we find the sidebar-section (200 and 230) with an Archive-widget (210) and a Profile-widget (220).

And finally we have a Footer (280-300).

Now that we understand the structure, let's take a look at the formatting of this template. In the stylesheet you will fund the following code:

#outer-wrapper {
width: 660px;
padding: 10px;
....... }

#main-wrapper {
width: 410px;
float: left;
....... }

#sidebar-wrapper {
width: 220px;
float: right;
........ }

The outer-wrapper has a width of 660 pixels. The padding is set to 10 pixels, so that everything that is inside the outer-wrapper stays 10 pixels from the border. So that leaves 660 - 20 = 640 pixels for main-wrapper and sidebar-wrapper.
The main-wrapper has a width of 410 pixels, and floats to the left.
The sidebar-wrapper had a width of 220 pixels, and floats to the right. Together, main-wrapper and sidebar-wrapper have a width of 410 + 220 = 630 pixels. In the middle there is a space of 640 - 630 = 10 pixels.
So, if we want to squeeze in a second sidebar, we have to do something to create space. As it is now, it won't fit in.



Adding a second sidebar.

First, we will add the sidebar to the structure of the template, then we will add it to the CSS, and make it fit into the page.

Step 1: Backup the template.

Step 2: Make your right-sidebar unique.
Change lines 190 and 200:
190: <div id='right-sidebar-wrapper'>
200: <b:section class='sidebar' id='right-sidebar' preferred='yes'>

In your CSS style-sheet, change "#sidebar-wrapper" to "#right-sidebar-wrapper".
If you save your template now and view your blog, it should look okay.

Step 3: Add a left sidebar by adding new lines of code:
131: <div id='left-sidebar-wrapper'>
132: <b:section class='sidebar' id='left-sidebar' preferred='yes'/>
133: </div>
Now save your template, and take a look at the Page Elements tab.

You can see there is a new section, just below the header and above the posts. But it is not at the left side of the screen jet. Therefore, we have to add some CSS.

Step 4: Add CSS for the left sidebar.
In your CSS-style sheet, add the following code:
#left-sidebar-wrapper {
width: 220px;
float: left;
word-wrap: break-word;
overflow: hidden;
}
Your Page Layout tab will show something like this:

The sidebar-section is now to the left, but your right-sidebar is suddenly below your posts. That is because the width of 2 sidebars and a main-section counts up to 840 pixels, and that is more than the width of the outer-wrapper (660 pixels).

Step 5. Change outer-wrapper and header-wrapper width.
In your CSS-stylesheet look for the #header-wrapper and #outer-wrapper definitions, and change the width from 660 to 860.

Step 6. Add a page element.
Now finally, add a page element to your left sidebar.