Sunday, December 10, 2006

Recruit One, Recruit Them AllThe US Army recently spent $200 million dollars on a marketing firm to come up with their new slogan: "Army Strong." What marvelous words! The ingenuity! The succinctness! Definitely worth 200 Nobel Prizes in Literature.

Now, as we all know, the Army has been experiencing recruiting woes ever since the Iraq War began going downhill shortly after Bush's cover-girl photo-op aboard the USS Abraham Lincoln. I don't know whether the new slogan will help out or not, but I truly hope that next time the Army will spend these huge sums of money on protecting the soldiers stuck in Bush's Iraqi morass.

To that end I thought, in the spirit of patriotic duty, that I would offer, for free, a supplemental slogan and recruiting poster. They need to know they don't have to pay $200 million for this stuff. Of course, my work may not have quite the suppleness of "Army Strong," but it's a good mix of the classic and the realistic, and has a nice internal rhyme which emphasizes the important parts.

I hereby declare that the United States Army may use the below poster and all words within in any way, shape, or form, without charge:

I want YOU to die for Bush's lie
my advertising suggestion to improve recruiting performance for the United States Army.

Sunday, December 03, 2006

Map Your Travels in Blogger BetaUPDATE: 02-04-2006 - I have redone much of this hack by using the Blogger JSON feeds. You can see the latest version here.

UPDATE: 01-20-2006 - I am working on a new version of this feature that utilizes the Blogger JSON feeds and AJAX (or more properly speaking, I guess, AJAJ). This will reduce the lines of code to a minimum, and hence be simpler to implement. It will also work better and overcome the issue I mention in my 12/22 update below. Check back soon for the new version!

UPDATE: 12-22-2006 - Something screwy is going on with this. I just noticed this week that when initially loading the map page, several all-important links won't display. (The links allowing you to pick a country, then city, region, and/or place associated with that country.) This makes the whole thing non-functional and certainly unimpressive.

YET, oddly enough, if you simply reload the page, it will display correctly. Why would a static webpage display one way on the initial load, and another way when you reload? I don't know if this is caused by a change on Blogger's end, or if this might even be a bug in Firefox 2.0.1 which I recently upgraded to. Any ideas?

Here's how, for some reason, it looks now on initial load:



Here's how it's supposed to look, and how it's been looking all along until recently. Again, if you refresh the page, everything's magically okay:



----------------Original Post----------------


A few weeks ago while surfing around for some Blogger Beta hacks, I came across Hoctro's Place and saw how he had integrated Google Map Search with his blog. Very cool, I thought, and as I was at that time starting a post relating some of my travels in China, the idea soon occurred to me to try to use Google Maps to show various places I've been in the last few years. With satellite maps I can show all sorts of details like where I lived, worked, ate, went to school, got treated for dysentery, went skinny-dipping, etc. Now's the time to mark these places, while my memory is still fresh and I can still wind through various city streets in my mind.

And knowing how the times they are a-changing (especially in China), it will be great 20 years later to be able to revisit these places and say with certainty, "right here, in this parking lot, is where my apartment used to be."

So I pondered this for a while, thinking about how I wanted it to look and function, and trying to get it to look and function that way in Blogger Beta. Right away I must say thanks to Ramani from Hackosphere, from whose hacks I learned how to mix widget loops and JavaScript, and thanks to Mike for his online tutorial on using the Google Maps API. You can see what I finally came up with, after lots of fretting and sweating, by clicking on the "places I've been" link below my profile.

NOTE: this does not work in Internet Explorer (v6.0, sp2). I have used conditional tags to disable the link in IE, since it otherwise results in a DNS error that forces IE to shut down. I have no idea what causes the error, and I'm very tired of trying to figure out how to "trick" IE into displaying what I want, so I have left it as is. The web can't wait for IE. But if anyone can figure out how to resolve this error, I would be much obliged. Here's a link that's not disabled to this section of my blog. Again, if you're using IE, it will force IE to shut down.

The code for this functionality is below. I offer it for anyone who might want to use it, and more importantly, for anyone who can improve it, as I feel it might be a little over-engineered.

In brief, I decided to use a label search result page to display the map, and all the individual posts dealing with various locations. This allows me to use a simple label to tie all of these posts together, and also allows me to display the different locations without having to reload the page. I also use labels, as well as part of the post title, to set up a hierarchy of world, country, region, city, and place posts. Each location, no matter at what level, is a separate post. Thus, with the code in place, I am able to easily manage everything through the Posts dashboard.

In order to work, posts must be composed as follows:

Post Title

At the country level, the title must have the country name, latitude, longitude, zoom level, and H S or M map type (Hybrid, Satellite, or Map), all separated by commas. For instance:
China,35.86166,104.195397,3,H
How does one get the latitude and longitude? The easiest way is to go to Google Maps, find the place you're looking for, and click on "Link to this page." You'll see the page reload, and in the address bar, you'll see part that goes "&ll=" followed by two numbers:


This is the latitude and longitude, and you can copy them directly from there. Incidentally, the zoom level will be just before this, where it says "&z=".

At the region, city, and place level, the title is exactly the same, except that you need to type in the name of a higher level first. For instance:
China,Great Wall,40.355595,116.009375,17,S
China,Wuhan,30.579997,114.269829,12,S
Wuhan,York Bar,30.589035,114.297032,18,S
This associates the post to the higher level. Thus, after I click on China, which is at the country level, I will then see a link for the Great Wall, which is at the place level. Also, I will see a link for Wuhan, which is at the city level. When I click on Wuhan, I will see a link for the York Bar, which is at the place level. As you can see, the different levels can be associated with each other in different ways, so you don't always have to go from country to region to city to place.

Post Body

The post body has no special requirements. However, if you want a marker or markers to appear for a location, you must have the following in your post body:

<span id="markers3317635477131100617" class="markers">39.930011,116.399975,Beijing|31.229999,121.470001,Shanghai</span>

This is what I part of what I have for my country level "China" post. When I click on "China," the map will show China, and there will be markers at the above coordinates. Clicking on a marker will open an info window which says, for instance, "Beijing".

The CSS will make this <span> invisible, but the data inside will be used to display the markers when the location loads. The data consists of the latitude, longitude, and info box description. If there are multiple places to mark, they should be separated by a pipe | . Also, the id for this span must be the word "markers" plus the post ID. I get this by saving the post first as a draft, then opening it again, and copying it from the address bar:


In addition, you can have some optional links in your post body which, when clicked, will move to a nearby location and place a marker there. This is so you don't have to clutter the map with too many markers (e.g., my apartment, the coffee shop next door, the vendor across the street, the restaurant at the corner), but can still point out these places for anyone who wants to see them. Here's a link I had for the post on my school in China:

<a href="javascript:void(0);" onclick="javascript:showaround('30.593126','114.291678','Trust Mart');">Behind</a> the school is the Trust-Mart supermarket where I did most of my shopping my first year in China.

When I click the link, it will pan to the new location, and place a marker there. These locations need to be fairly close by to smoothly pan; otherwise, the map will simply reload. Again, you need the latitude, longitude, and the info window description.

Post Labels

Each post should have two labels. Every post should have the label, atravelmap. Then, each post should have another label depending on what level it's on: countrymap, regionmap, citymap, or placemap. The atravelmap label page is the main page used to display the map and posts. The other labels are there to help with sorting the posts into the right hierarchy.

The CSS will prevent these labels from appearing in the labels widget.

Post Date

Before you publish the post, you need to backdate it. Usually I save the post as a draft first (to get the post ID), then change the date and publish it. With the code I have, the posts should be backdated to 1985 (I just arbitrarily chose this year). The code will prevent this year from appearing in the Blog Archive widget.

Also, the code will prevent any of the posts from appearing via the "Older" link. Note: if you don't have very many posts currently, you may need to modify your Blog Settings (Formatting) to only display a certain number of posts on your home page. This will prevent the travel posts, with their funky titles, from appearing on your homepage.

Blogger will display the post titles from later to earlier, so you will need to play with the months and days a bit to get them to show up alphabetically. For instance, I have my posts on China dated to October 1985, Greece dated to August 1985, and Hungary dated to June 1985. This makes them display in alphabetical order: China, Greece, and Hungary.

I also disable comments for my travel posts, and the code I have does not allow for comments to even be displayed for these posts, but that could be fairly easily changed.

World Post

You might have noticed, there was one level that I haven't talked about yet: the world level. This level consists of a single post, and this post is what is displayed when initially going to the map page. It controls the markers that are initially shown at the world level, and allows anyone to go back up to the world level without having to reload the page.

The world post title is similar to the country-level post. Here's what I use on my blog:
world,35.704857,-6.926808,1,S
The latitude and longitude can be whatever center of the world you choose.

The world post label is worldmap (and, of course, atravelmap).

The date doesn't really matter, as long as it's in 1985.

To show markers at the world level, you'll put a hidden span in your post body, just as I described above for other posts:

<span id="markers1100387009350392250" class="markers">35.86166,104.195397,China|38.278603,23.80708,Greece|47.162494,19.503304,Hungary|23.200961,-102.700195,Mexico</span>


And that's it. It does seem like a lot, as there's a fair amount of data to sift through, but once you do it some it's easy to get used to.

Here's the code:

1. Go here to get a Google Maps API key for your blog. There's no limit on the number of URL's you can register for a key, so I'd highly recommend getting one for a test blog first.

2. Copy the following somewhere between the tags: <b:skin><![CDATA[/* and ]]></b:skin> :

.markers {
display:none;}

a.countrymap:link, a.regionmap:link, a.citymap:link {
text-decoration:none; color:#3a80b4;}

a.regionmap, a.citymap, li.placemap {
text-decoration:none; display:none;}

.travelsection {
font-weight:bold;}

/* This prevents the map posts from
showing up in the label widget */
li#atravelmap, li#worldmap, li#countrymap,
li#regionmap, li#citymap, li#placemap {
display:none;}

#placelist li {
list-style-type: disc; text-align: left;}

/* You will need to modify these margins to
get them to display right in your blog.
This is what I have: */
#placelist {
margin-left:13px;}

#countrydiv, #regiondiv, #citydiv {
margin-left: 5px;}


3. Next there are a series of JavaScript functions you'll need to copy between the tags: ]]></b:skin> and </head> . This is where I might have over-engineered some stuff. If any JavaScript experts see ways to simplify, let me know.

<script src="http://maps.google.com/maps?file=api&v=2&key=YOUR_KEY_HERE" type="text/javascript">
</script>


<script type="text/javascript">
// Thanks to Mike at http://www.econym.demon.co.uk/ for his tutorial, which included this bit:
function createMarker(point,html) {
var marker = new GMarker(point);
GEvent.addListener(marker, "click", function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
</script>

<script type='text/javascript'>
// Thanks to Dustin Diaz at http://www.dustindiaz.com/ for this great JavaScript function
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}
</script>

<script type='text/javascript'>
// This function displays the appropriate post body, and makes all others disappear
function showtravelpost(a) {
var e=getElementsByClass('travelpost',document,'div');
for(var i=0;i < e.length;i++){
e[i].style.display="none";
}
document.getElementById(a).style.display="block";
}
</script>


<script type='text/javascript'>
// This function displays the next links in the hierarchy,
// makes links belonging to another hierarchy disappear,
// and permanently highlights and unhighlights the appropriate level(s).
var count = 0;
function shownext (a,b,c) {
var allplace=getElementsByClass('placemap');
for(var i=0;i < allplace.length;i++){
allplace[i].style.display="none";
}
var allcity=getElementsByClass('citymap');
for(var i=0;i < allcity.length;i++){
allcity[i].style.background="#efefef";
allcity[i].style.color="#387fb5";
}
if (b == "regionmap" || b == "countrymap") {
var allcity=getElementsByClass('citymap');
for(var i=0;i < allcity.length;i++){
allcity[i].style.display="none";
}
var allregion=getElementsByClass('regionmap');
for(var i=0;i < allregion.length;i++){
allregion[i].style.background="#efefef";
allregion[i].style.color="#387fb5";
}
}
if (b == "countrymap") {
var allregion=getElementsByClass('regionmap');
for(var i=0;i < allregion.length;i++){
allregion[i].style.display="none";
}
var allcountry=getElementsByClass('countrymap');
for(var i=0;i < allcountry.length;i++){
allcountry[i].style.background="#efefef";
allcountry[i].style.color="#387fb5";
}
}
document.getElementById(c).style.backgroundColor="#c0c0c0";
document.getElementById(c).style.color="#000000";
var e=getElementsByClass(a);
for(var i=0;i < e.length;i++){
e[i].style.display="inline";
}
var f=getElementsByClass('placemap');
for (var i=0;i < f.length;i++){
if (f[i].style.display!="none") {
f[i].style.display="list-item"
}
}
count++;
}
</script>

<script type = "text/javascript">
// This function is for the "world" link to get you back where you started.
// Could have been combined with the above, but I was too lazy at that point.
function showworld() {
var allplace=getElementsByClass('placemap');
for(var i=0;i < allplace.length;i++){
allplace[i].style.display="none";
}
var allcity=getElementsByClass('citymap');
for(var i=0;i < allcity.length;i++){
allcity[i].style.display="none";
}
var allregion=getElementsByClass('regionmap');
for(var i=0;i < allregion.length;i++){
allregion[i].style.display="none";
}
var allcountry=getElementsByClass('countrymap');
for(var i=0;i < allcountry.length;i++){
allcountry[i].style.background="#efefef";
allcountry[i].style.color="#387fb5";
}
}
</script>

<script type="text/javascript">
// This function controls mouseover highlighting. The count
// variable here comes from the shownext() function above.
function highlightmap (a) {
if (document.getElementById(a).style.backgroundColor=="rgb(192, 192, 192)") {
count++;
}
else {
document.getElementById(a).style.backgroundColor="#c0c0c0";
document.getElementById(a).style.color="#000000";
count=0;
}
}

function unhighlightmap (a) {
if (count == 0) {
document.getElementById(a).style.backgroundColor="#efefef";
document.getElementById(a).style.color="#387fb5";
}
}
</script>

<script type="text/javascript">
// This function allows you to enter a single letter in the post title
// to determine what map type you want.
function getType (a) {
var typeparameter ="";
var maptype = a;
if (maptype == "H") {
typeparameter = "G_HYBRID_MAP"
}
else if (maptype == "S") {
typeparameter = "G_SATELLITE_MAP"
}
else if (maptype == "M") {
typeparameter = "G_NORMAL_MAP"
}
return typeparameter;
}
</script>

<script type='text/javascript'>
// This function shows a set of markers for any given level.
function showmarkers (a) {
if (document.getElementById(a)){
var spandata = document.getElementById(a).innerHTML;
var setmarker = spandata.split("|");
var markernum = setmarker.length;
for (i = 0; i < markernum; i++) {
var onemarker = setmarker[i].split(",");
var qdescription = onemarker[2]
var point = new GLatLng(onemarker[0],onemarker[1]);
var marker = createMarker(point,qdescription);
map.addOverlay(marker);
}
}
}
</script>

<script type='text/javascript'>
// This function is for if you want to show a few places in a small area
// (like "the cool coffeeshop next to the hotel that I went to every morning").
// Puts a marker in, and moves smoothly (most of the time) to that marker.
// Needs some improvement.
function delay(a,b) {
map.panTo(new GLatLng(a,b));
}

function showaround (a,b,c) {
var point = new GLatLng (a,b);
var qdescription = c;
var marker = createMarker (point, qdescription);
map.addOverlay(marker);
var currentzoom = map.getZoom();
if (currentzoom < 18) {
map.panTo(new GLatLng(a,b));
}
else {
var currentcenter = map.getCenter();
var midlat = (currentcenter.lat() - ((currentcenter.lat() - a)/2));
var midlng = (currentcenter.lng() - ((currentcenter.lng() - b)/2));
map.panTo(new GLatLng(midlat,midlng));
setTimeout("delay(" +a+ "," +b+ ")",600);
}
}
</script>


4. Copy the following widget just above this widget:

<b:widget id='Blog1' locked='false' title='Blog Posts' type='Blog'>

Be sure to check your template for any other HTML widgets first. If you already have a widget with an id of HTML1, change the id here to HTML2 or 3 or whatever. This is the widget which will contain the map.

<b:widget id='HTML1' locked='false' title='Google Map' type='HTML'>
<b:includable id='main'>
<b:if cond='data:blog.url == "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>
<div class='widget-content'>
<data:content/>
</div>
<b:include name='quickedit'/>
</b:if>
</b:includable>
</b:widget>

Note that here and below you might need to add "?max-results=" to the label page URL, as by default Blogger will only display 20 or so on one page. I set the links here with max-results of 200.

5. Copy the following just after these tags:

<b:includable id='main' var='top'>
<!-- posts -->
<div id='blog-posts'>


<b:if cond='data:blog.url == "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>
<script type="text/javascript">
var worlddata="";
var worldpostbody="";
var worldmarkerset="";
var countrydata="";
var regiondata="";
var citydata="";
var placedata="";
<b:loop values='data:posts' var='post'>
<b:loop values='data:post.labels' var='label'>
<b:if cond='data:label.isLast == "true"'>
<b:if cond='data:label.name == "worldmap"'>
var title = "<data:post.title/>";
splittitle = title.split(",");
var postbody = "\"travelpost<data:post.id/>\"";
worldpostbody = "travelpost<data:post.id/>";
var markerset = "\"markers<data:post.id/>\"";
worldmarkerset = "markers<data:post.id/>";
t = getType(splittitle[4]);
worlddata = worlddata + "<a class='worldmap' href='javascript:void(0);' onclick='javascript:showworld(); showtravelpost(" +postbody+ "); map.clearOverlays(); map.setCenter(new GLatLng(" +splittitle[1]+"," +splittitle[2]+ ")," +splittitle[3]+ "," +t+ "); showmarkers(" +markerset+ ");'>"+splittitle[0]+"</a>";
<b:else />
<b:if cond='data:label.name == "countrymap"'>
var title = "<data:post.title/>";
var splittitle = title.split(",");
var qsplittitle = "\"" + splittitle[0] + "\""
var label = "\"<data:label.name/>\""
var postbody = "\"travelpost<data:post.id/>\"";
var markerset = "\"markers<data:post.id/>\"";
var travellink = "link<data:post.id/>";
var qtravellink = "\"link<data:post.id/>\"";
var t = getType(splittitle[4]);
countrydata = countrydata + " <a class='countrymap' id='" +travellink+ "' href='javascript:void(0);' onMouseOver = 'javascript:highlightmap(" +qtravellink+ ")' onMouseOut='javascript:unhighlightmap(" +qtravellink+ ")' onclick='javascript:shownext(" +qsplittitle+ "," +label+ "," +qtravellink+ "); showtravelpost(" +postbody+ "); map.clearOverlays(); map.setCenter(new GLatLng(" +splittitle[1]+"," +splittitle[2]+ ")," +splittitle[3]+ "," +t+ "); showmarkers(" +markerset+ ");'>"+splittitle[0]+"</a> ";
<b:else />
<b:if cond='data:label.name == "regionmap"'>
var title = "<data:post.title/>";
var splittitle = title.split(",");
var qsplittitle = "\"" + splittitle[1] + "\""
var label = "\"<data:label.name/>\""
var postbody = "\"travelpost<data:post.id/>\"";
var markerset = "\"markers<data:post.id/>\"";
var travellink = "link<data:post.id/>";
var qtravellink = "\"link<data:post.id/>\"";
var t = getType(splittitle[5]);
regiondata = regiondata + " <a class='" +splittitle[0]+ " regionmap' id='" +travellink+ "' href='javascript:void(0);' onMouseOver = 'javascript:highlightmap(" +qtravellink+ ")' onMouseOut='javascript:unhighlightmap(" +qtravellink+ ")' onclick='javascript:shownext(" +qsplittitle+ "," +label+ "," +qtravellink+ "); showtravelpost(" +postbody+ "); map.clearOverlays(); map.setCenter(new GLatLng(" +splittitle[2]+"," +splittitle[3]+ ")," +splittitle[4]+ "," +t+ "); showmarkers(" +markerset+ ");'>"+splittitle[1]+"</a> ";
<b:else />
<b:if cond='data:label.name == "citymap"'>
var title = "<data:post.title/>";
var splittitle = title.split(",");
var qsplittitle = "\"" + splittitle[1] + "\""
var label = "\"<data:label.name/>\""
var postbody = "\"travelpost<data:post.id/>\"";
var markerset = "\"markers<data:post.id/>\"";
var travellink = "link<data:post.id/>";
var qtravellink = "\"link<data:post.id/>\"";
var t = getType(splittitle[5]);
citydata = citydata + " <a class='" +splittitle[0]+ " citymap' id='" +travellink+ "' href='javascript:void(0);' onMouseOver = 'javascript:highlightmap(" +qtravellink+ ")' onMouseOut='javascript:unhighlightmap(" +qtravellink+ ")' onclick='javascript:shownext(" +qsplittitle+ "," +label+ "," +qtravellink+ "); showtravelpost(" +postbody+ "); map.clearOverlays(); map.setCenter(new GLatLng(" +splittitle[2]+"," +splittitle[3]+ ")," +splittitle[4]+ "," +t+ "); showmarkers(" +markerset+ ");'>"+splittitle[1]+"</a> ";
<b:else />
<b:if cond='data:label.name == "placemap"'>
var title = "<data:post.title/>";
var splittitle = title.split(",");
var qsplittitle = "\"" + splittitle[1] + "\""
var postbody = "\"travelpost<data:post.id/>\"";
var markerset = "\"markers<data:post.id/>\"";
var t = getType(splittitle[5]);
placedata = placedata + "<li class='" +splittitle[0]+ " placemap'><a href='javascript:void(0);' onclick='javascript:showtravelpost(" +postbody+ "); map.clearOverlays(); map.setCenter(new GLatLng(" +splittitle[2]+"," +splittitle[3]+ ")," +splittitle[4]+ "," +t+ "); showmarkers(" +markerset+ ");'>"+splittitle[1]+"</a></li>";
</b:if>
</b:if>
</b:if>
</b:if>
</b:if>
</b:if>
</b:loop>
</b:loop>
</script>

<hr />
<b:loop values='data:posts' var='post'>
<div expr:id='"travelpost" + data:post.id' class='travelpost' style='display:none;'>
<data:post.body/>
<hr />
</div>
</b:loop>
<b:else />
<b:loop values='data:posts' var='post'>
<b:if cond='data:post.dateHeader'>
<h2 class='date-header'><data:post.dateHeader/></h2>
</b:if>
<b:include data='post' name='post'/>
<b:if cond='data:blog.pageType == "item"'>
<b:if cond='data:post.allowComments'>
<b:include data='post' name='comments'/>
</b:if>
</b:if>
</b:loop>
</b:if>


5. Look for these two items in your template:

<!-- navigation -->
<b:include name='nextprev'/>
<!-- feed links -->
<b:include name='feedLinks'/>

Before it, enter this:

<b:if cond='data:blog.url != "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>

After it, enter this:

</b:if>

This will prevent the Newer, Older, and Home links from appearing on your map page.

6. Find this includable:

<b:includable id='nextprev'>

Then look for the anchor <a> with the following href:

expr:href='data:olderPageUrl'

Change the href as follows:

expr:href='data:olderPageUrl + "&updated-min=2005-08-31T00%3A00%3A00-00%3A00"'

This prevents your travel posts from appearing when anyone clicks on the Older link in your blog. You may need choose an earlier year. I started my blog just a couple of months ago, so I obviously don't have any posts older than 2005. Note: some months didn't work here. I seem to recall that June or July didn't work, but August did.

7. There were several widgets I didn't want displaying on my map page, so I added the following after the main includable (<b:includable id='main'>) for each widget I didn't want to display:

<b:if cond='data:blog.url != "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>

Just before the end of the includable (</b:includable>), you of course need </b:if> .

8. I use the hierarchy-type archive, and the following prevents my travel map posts from appearing in the archive. (I'm not sure how to prevent them from appearing for the other archive types.)

Just after these lines:

<b:includable id='interval' var='intervalData'>
<b:loop values='data:intervalData' var='i'>

Copy this:

<b:if cond='data:i.name != "1985"'> <!--you'll make this whatever year you backdate your posts to-->

Then just after the </ul> tag, you'll add the closing if tag </b:if> .

9. Add the following to your sidebar, below this:

<b:section class='sidebar' id='sidebar' preferred='yes'>

This widget will contain the post titles, displayed in the proper hierarchy. These post titles are what you click on to display the location on the map, and display the corresponding post body. Again, be sure to check your other HTML widgets to get the appropriate id.

<b:widget id='HTML2' locked='false' title='Places I've Been' type='HTML'>
<b:includable id='main'>
<b:if cond='data:blog.url == "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>
<!-- only display title if it's non-empty -->
<b:if cond='data:title != ""'>
<h2 class='title'><data:title/></h2>
</b:if>
<div class='widget-content'>
<data:content/>
</div>
<b:include name='quickedit'/>
</b:if>
</b:includable>
</b:widget>


10. Add the following widget near the very end of your template, just before the final </b:section> tag.

<b:widget id='HTML3' locked='false' title='Map Script' type='HTML'>
<b:includable id='main'>
<b:if cond='data:blog.url == "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>
<div class='widget-content'>
<data:content/>
</div>
<b:include name='quickedit'/>
</b:if>
</b:includable>
</b:widget>


11. This is the final change to the actual template itself. Add the following to the sidebar to create a link to your travel map page. I put mine just below my profile widget:

<b:widget id='HTML4' locked='false' title='Travel Link' type='HTML'>
<b:includable id='main'>
<b:if cond='data:blog.url != "http://your-blog-name.blogspot.com/search/label/atravelmap?max-results=200"'>
<div class='widget-content'>
<data:content/>
</div>
<b:include name='quickedit'/>
</b:if>
</b:includable>
</b:widget>


12. Now, after you save your new template, go to the Layout view. (Note: you will get a pop-up every time you view the Layout stating that the API is registered to another URL. This is because the template is being loaded to render the Page Layout section, and the URL there is "http://beta.blogger.com.....")

Find the Google Map widget, click Edit, and add the following to it:

<div id="map" style="width: 100%; height: 400px"></div>

<noscript>JavaScript must be enabled for Google Maps. JavaScript is either disabled or not supported by your browser.
</noscript>

<script type="text/javascript">
if (GBrowserIsCompatible()) {
// Display the map, with some controls and set the initial location
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(35.704857,-6.926808),1,G_SATELLITE_MAP);
map.enableContinuousZoom();
}
else {
alert("The Google Maps API is not compatible with this browser");
}
</script>

The coordinates above is what I chose to be the center of the map of the world when the map page first loads. I chose zoom level 1 (the highest), and a satellite map type.

13. Find the Travel Link widget, click Edit, and add the following to it:

<!--[if IE]>
<script type="text/javascript">
function iealert() {
alert("Internet Explorer does not support this function. Get the better browser. Get Firefox at http://www.mozilla.com");
}
</script>
<p>
<a href="javascript:void(0);" onclick="javascript:iealert();">places I've been</a>
</p>
<![endif]-->

<![if !ie]>
<p>
<a href="http://your-blog-here.blogspot.com/search/label/atravelmap?max-results=200">places I've been</a>
</p>
<![endif]></![endif]></![if>

Since this doesn't work in Internet Explorer, this will prevent people using IE from clicking on this link and then having to shut down their browser.

14. Find the Places I've Been widget, and add the following to it. You can obviously customize how you want it to look, but this is what I did:

<table width="100%">
<tr>
<td id="worldtd">
</td>
<td style="text-align:right;">
<a href="http://your-blog-name.blogspot.com/">back home</a>
</td>
</tr>
</table>
<p>
<ul>
<li><span class="travelsection">country:</span>
<div id="countrydiv">
</div>
</li>
<li><span class="travelsection">region:</span>
<div id="regiondiv">
</div>
</li>
<li><span class="travelsection">city:</span>
<div id="citydiv">
</div>
</li>
<li><span class="travelsection">place:</span>
<div id="placediv">
<ul id="placelist">
</ul>
</div>
</li>
</ul>
</p>


15. Finally find the widget named Map Script. Click Edit, and add the following:

<script type="text/javascript">
obj = document.getElementById('worldtd');
obj.innerHTML = worlddata;
obj = document.getElementById('countrydiv');
obj.innerHTML = countrydata;
obj = document.getElementById('regiondiv');
obj.innerHTML = regiondata;
obj = document.getElementById('citydiv');
obj.innerHTML = citydata;
obj = document.getElementById('placelist');
obj.innerHTML = placedata;
showtravelpost(worldpostbody);
showmarkers(worldmarkerset);
</script>
A Blogger Beta hack that integrates Google Maps with your blog, and allows you to show the locations of your travels.

Thursday, November 23, 2006

Cars and BarsMADD announced a few days ago their new campaign to install alcohol-detection devices in cars of drunk drivers. While this will likely reduce repeat incidences of drunk driving somewhat, I can't help but think this is a band-aid solution. The true problem is cars themselves, or rather, the car culture that has developed in America (and is developing elsewhere).

With the urban sprawl spawned by the Interstate Highway System, no one stays local to do anything. We can't, really. After all, we live far from where we work far from where we shop far from where we eat far from where we drink. If at least our favorite watering hole were within walking distance or a short drive away, incidences of drunk driving would plummet. (And think how much happier in general we would all be if everything else were closer as well. I can't tell you how nice it is to live a 5-minute walk away from the supermarket.)

But the growth of interesting, self-containing, walkable communities—oases in our urban deserts—is obviously a pipe dream (except for Prince Charles' urban village of Poundbury). However, another feature of our car culture can be changed: public transport.

There is simply no easy way to get to and from bars, restaurants, and other weekend places without driving a car. Public transport, if it even goes to the desired destination, shuts down at 10pm. You might be able to get a ride with a friend, but what if he's drunk, too? And what if you went to a bar by yourself, to drink in solitude? Of course, you could always call a cab, but those are a bit of a rip-off because everything is so far away.

Let's get our scattered places well connected, so it's easy to get around without a car. This will not only decrease drunk driving, but improve the quality of life for everyone: the less we have to stress over traffic, fight over parking spots, and fret over gas prices, the better our lives will be. Many of us may then have less need to get drunk in the first place.
A couple of thoughts on what will really reduce drunk driving in America.

Sunday, November 19, 2006

Wo Er MaThis month-old article about Wal-Mart bidding for the Chinese chain Trust-Mart brought back memories of my time in Wuhan. (I actually started this post a month ago, then partly because of this post, I got side-tracked with integrating Google Maps with my blog to show various places from my travels—took me quite a while. You can see the result in the "places I've been" link on the right. ) Right behind my school there was a Trust-Mart, and it's where I did nearly all of my shopping for a year. Its Chinese name is 好又多, which means something like "good (things) and many (things)." (Wal-Mart's name in Chinese is 沃尔玛 — it has no meaning really, but rather is phonetic. You can see the literal meaning of each character here.) But I didn't find it that great, and once I discovered some of the other, better supermarkets—Carrefour (家乐福), Fu-Mart (大福源), and even, I'm ashamed to admit, the Wal-Mart which opened up in 2004—I rarely went back. (There was also the much smaller but more spread-out Zhongbai (中百), a branch of which opened directly below my school in 2002.)

Though they might vary in cleanliness and selection, the layout of all the large supermarkets was the same, and I suspect it's so throughout China: They are all housed in a large 2- or 3-story building that looks more like a department store from the outside. When you walk through the entrance, you see several stalls and small shops where people sell clocks, shoes, jewelry, tea, and trinkets. Most likely, there is a canteen nearby. You cannot enter the store itself from the first level. You have to take an escalator to the second or third level, where you may encounter some other stalls before you can actually enter the store proper. Upstairs they sell about every non-edible item you might want in your home in China: TVs, radios, dumpling steamers, office supplies, water heaters, mosquito nets, washing machines, rice cookers, clothes, shoes, dishes, woks, bicycles, weights, toys, mahjong (麻将), toiletries, electric fly-swatters, calligraphy paper, Hello Kitty crap, karaoke machines, dictionaries, pirated CDs and DVDs...

You have to wind your way through all of this stuff—this is China's version of putting the milk and bread in the back—which can be incredibly difficult if you're pushing a cart through weekend crowds. Then finally you get to the escalator going down, and you descend into the smells of food.

At Fu-Mart, you gently sank into the wonderful smell of baking bread, but most other places brought you down right in the fish and meat section, where the smells of preserved salty fish, flattened dehydrated chickens, frogs and eels in aquariums, and all sorts of animal parts, rushed into your nostrils like Henry V's army unto the breach.

As you might have guessed from the brief list of 2nd-floor items I recounted above, there are all sorts of odd things you can find in Chinese supermarkets, and this becomes even more apparent as you wander amongst the food.

Dried shredded fish. Black herbal jello. Geriatric nut powders. Dried string mushrooms. Frozen fish balls. Tree ear fungus (木耳). Tofu that looks like dried corn husks. Spicy pickled vegetables. Curdled pig blood. Lotus seeds. Blackened preserved eggs (皮蛋). Sesame paste. Plum sauce. Red bean paste (红豆沙). All the wonderful Chinese vegetables, such as caitai (菜苔), uncommon outside of Hubei Province, and lihao (蓠蒿). Chinese fruit, like longyan (龙眼) and lizhi (荔枝). Noodles for local dishes such as hot-dry noodles (热干面) and cold noodles (凉面), as well as all sorts of other noodles. Endless varieties of tea. (And that's just what I can remember from a single sitting.)

Then after you check out (without the benefit of conveyor belts like in the US), you had to get your receipt stamped before going out the narrow exit (like the pass of Thermopylae) and back amongst the vendors. Then you did like everyone else does, and which I still do here, living as I do close to a supermarket—you park your cart, heft up your bags, and walk home. If it was raining, you might have caught a taxi or, before they were banned in 2003, a mamu (麻木 - a local Wuhan name for tricycle pedicabs).

All of these wonderful items—sometimes more, sometimes less—were available in the traditional outdoor street markets, which are great places to walk around in, and look at people and things. I didn't shop too often in the markets because, especially as a foreigner, I could never be sure I was getting a fair price. You have to haggle and bargain in the markets, and my general aversion to bargaining coupled with my inability to do so in Chinese guaranteed I would never get the price I could get in the supermarkets.

Yet it would be a shame if the outdoor markets disappeared. I wonder if the emergence of these supermarkets in recent years signals the beginning of the end, and the eventual lessening of variety, especially now that Wal-Mart is on the scene.

Admittedly, the Wal-Mart in Wuhan was much nicer, not to mention bigger, than any Wal-Mart I've seen in the U.S. The building it's in is actually rather stylish, and sells some things you'll never see at a Wal-Mart here. (Actually, those aren't porn videos, but sex education videos with very titillating covers and very boring content.)

So I didn't really feel it that bad or tasteless to shop there, like I do in America, though I went as little as necessary, preferring Fu-Mart above all others.

But I think it's only a matter of time—perhaps a long time given the size of the country and it's population, but witness the rapidity with which McDonald's and KFC have spread their tentacles throughout China (770 and 1,700 locations by November 2006, respectively - source). Once the outdoor markets go, then the variety in supermarkets themselves will begin to shrink. And when it's all over I wonder how much of the weird and wonderful and local variety will be lost, and replaced by a generic cuisine you can find any old place. Just like in the U.S.
now that Mal-Wart has opened its doors in China, and is acquiring a Chinese chain as well, is the diversity of the country's food and other products endangered?

Thursday, October 26, 2006

Robert Frost & Ogden NashThese two poets are about as opposite as you can get. One the master of dark understatement from rural New England, the other the light-verse virtuoso oft associated with the New Yorker. Though a good deal of their lives overlapped (Frost 1874 - 1963, Nash 1902 - 1971), they don't seem to have had anything to do with each other. I can find no reference to Nash in Frost's selected letters, or in a biography I have of Frost. I don't know enough about Nash's life or letters to say "vice versa," but I'm certain I could, although Frost does make an appearance in one of Nash's poems ("O, Snow-Bound was written by Robert Frost / And Scott Fitzgerald wrote Paradise Lost" — from Who Did Which? or Who Indeed?).

A quick stroll through the table of contents of a volume by both poets easily shows how worlds apart they are, but here are a few contrasting stanzas, exempli gratia:

The City
by Odgen Nash

This beautiful ditty
Is, for a change, about the city,
Although ditties aren't very popular
Unless they're rural and not metropular.

Sentimentalists object to towns initially
Because they are made artificially,
But so is vaccination,
While smallpox is an original creation.

Artists speak of everything urban
As the W.C.T.U. speaks of rye and bourbon,
And they say cities are only commercial marts,
But they fail to realize that no marts, no arts.

The country was made first,
Yes, but people lived in it and rehearsed,
And when they finally got civilization down,
Why, they moved to town.

Take country people, they suffer stoically,
But city people prefer to live unheroically;
Therefore city dentistry is less painful,
Because city dentists find it more gainful.

City people are querulous and queasy,
And they'd rather die than not live easy
And if they did die, they'd find fault
If they weren't put in an air-conditioned vault.

Yes, indeed, they are certainly sissies,
Not at all like Hercules or Ulysses,
But because they are so soft,
City life is comfortable, if not perpetually, at least oft.

The Need of Being Versed in Country Things
by Robert Frost

The house had gone to bring again
To the midnight sky a sunset glow.
Now the chimney was all of the house that stood,
Like a pistil after the petals go.

The barn opposed across the way,
That would have joined the house in flame
Had it been the will of the wind, was left
To bear forsaken the place's name.

No more it opened with all one end
For teams that came by the stony road
To drum on the floor with scurrying hoofs
And brush the mow with the summer load.

The birds that came to it through the air
At broken windows flew out and in,
Their murmur more like the sigh we sigh
From too much dwelling on what has been.

Yet for them the lilac renewed its leaf,
And the aged elm, though touched with fire;
And the dry pump flung up an awkward arm;
And the fence post carried a strand of wire.

For them there was really nothing sad.
But though they rejoiced in the nest they kept,
One had to be versed in country things
Not to believe the phoebes wept.

But they were not always so antipodal. Frost occasionally penned a whimsical verse:
Sym-ball-ism

The symbol of the number ten—
The naught for girls, the one for men—
Defines how many times does one
In mathematics or in fun
Go as you might say into zero.
You ask the heroine and hero.


And Nash sometimes weighted his lines:
Old Men

People expect old men to die,
They do not really mourn old men.
Old men are different. People look
At them with eyes that wonder when...
People watch with unshocked eyes;
But the old men know when an old man dies.


But both poets came together in a very real way for me in the last few days. Last Wednesday, I stopped at Half-Price Books while my wife was getting her lovely locks scissored. I checked all the sections I normally do, to see if anything new was in. In the poetry section, I spied an old edition of Frost's complete poems. It was actually entitled "Collected Poems," and it was published by Halcyon House, which I found odd because Holt had published most of his poetry.



I pulled it from the shelf and thumbed through it. It was published in 1942, and definitely looked that old.



The first page was inscribed, "To Mother, With Love, Helen. Mother's Day 1944." Inside the book were several newspaper clippings about Frost which had stained the pages they were wedged between.



Frost is one of my favorite poets, and I have three different volumes of his complete poems (one published in 1964 just after his death, one edited by Edward Connery Lathem who "regularized" a lot of Frost's punctuation and spelling, and the Library of America edition which is the best you can get of the poet). This would make an interesting fourth volume, and would be the oldest of the lot. But I wasn't quite sure, as books are a vice of mine, and I've been trying to buy fewer and read more of the ones I already have. Did I really want it, I asked myself. Especially with the newspaper stains. As I was mulling it over, I looked back at the front of the book, and separated a couple of pages that had static cling, and suddenly saw this:



I'm sure my jaw dropped open at the sight of that. I just remember a rush of thought like, "Is that really Frost's signature?! Can't be. How could it have ended up here, like any old book? Frost's signature? Really?" I looked and looked at it. Even though I had a wee bit of doubt—I had to doubt, I mean, what are the chances?—but also, I knew. I had seen Frost's writing before, and this volume even had a facsimile of his signature on the frontispiece. I wandered the aisles a little more, walking off my excitement some, and bought it.

I have no idea how much it's worth. I did manage to find this very edition, also signed, on eBay, for $249. Needless to say, considerably more than I payed for it, but no matter the monetary value, it is the jewel of my little Frost collection.

Since the signature was dated March 13, 1949, I wanted to see if I could find out where he was that day. I checked his selected letters and biography, but couldn't find anything near that date. So I went online and typed in "Robert Frost March 13, 1949." Lo and behold, I found this site detailing the Frost collection at Bluffton University, and from one of the items listed, I can say it's likely that Frost signed this book in Georgia at Agnes Scott College:

Folder 30 - Photographic Material -- Photographs
1. (1945?) - Frost at University of Georgia (lighter exposure)
2. (1945?) - Frost at University of Georgia (darker exposure)
3. January 1947 - Frost at Agnes Scott, signing books (signed)
4. January 1947 - Frost at Agnes Scott, signing books (signed)
5. March 13, 1949 - Frost with Doris Sullivan, Agnes Scott student


Incidentally, while looking around on eBay and other websites, I happened upon a photo of Frost's Complete Poems 1949. I had never seen what it looked like, and I was intrigued how it looked exactly the same as my 1964 edition, except for the year 1949 on the cover. Then I remembered that not long ago, perhaps just this last time, I had seen at Half-Price a volume of Frost that looked like that. At the time, I had passed it by, thinking I already owned that edition. It suddenly struck me that it could have been the 1949 edition, and what's more, it could be signed. (Crazy and covetous, I know.)

So a few days later, I went back to Half-Price Books. The volume was gone, alas, and though I felt a little disappointed, I realized I was being rather silly. To find one like this, not probable but quite possible. To find two, not possible, at least statistically. But while I'm here, I thought, I might as well check some of the other old poetry tomes on the shelf. You never know... I pulled an old, cigarette-smelling edition of Carl Sandburg of the shelf. No signature. Read a few pages, placed it back on the shelf. Looked at an old, thick volume of Kipling. Then saw on the bottom shelf a collection by Ogden Nash.



I'd actually seen it before, but didn't bother looking at it. I have a good edition of his already (Verses from 1929 On), and though I like his light verse, you have to be in the mood for it.

I slid it from between its companions on the shelf, opened it and saw right away this:



No way! I had no idea what Nash's signature looked like, and wondered if it might be fake. But does that really happen? And who would fake Nash's signature? It was written with a heavy black pen, and at the bottom of the page was a lighter inscription, "To my Love, Dorothy Ann. Love, Bill. 3/23/42". The book itself was published in 1941. The fact that the inscription was at the bottom of the page, obviously leaving room for the signature, pretty much cinched it for me.

So again, I made a happy purchase, and after getting home checked online to see if I could verify the signature. Sure enough, it was his, and I found one site that was selling a signature of his for $399.00. I think I've probably used up all my luck for the rest of my life.

Which is why I haven't even attempted removing the price stickers. Modern stickery is designed to survive a direct nuclear hit, and will rip and tear anything it is removed from, or at least leave a nasty residue. Does anyone have an idea how to safely remove them?

Speaking of things modern, I end with a poem by each. These are by no means the best, but I find them relevant to our time.
Not to Keep
by Robert Frost

They sent him back to her. The letter came
Saying... And she could have him. And before
She could be sure there was no hidden ill
Under the formal writing, he was there,
Living. They gave him back to her alive—
How else? they are not known to send the dead—
And not disfigured visibly. His face?
His hands? She had to look, to look and ask,
'What is it, dear?' And she had given all
And still she had all—they had—they the lucky!
Wasn't she glad now? Everything seemed won,
And all the rest for the permissable ease.
She had to ask, 'What was it, dear?'

'Enough
Yet not enough. A bullet through and through,
High in the breast. Nothing but what good care
And medicine and rest, and you a week,
Can cure me of to go again.' The same
Grim giving to do over for them both.
She dared no more than ask him with her eyes
How was it with him for a second trial.
And with his eyes he asked her not to ask.
They had given him back to her, but not to keep.

Everybody Tells Me Everything
by Ogden Nash

I find it very difficult to enthuse
Over the current news.
Just when you think that at least the outlook is so black that it can grow no blacker, it worsens,
And that is why I do not like the news, because there has never been an era when so many things were going so right for so many of the wrong persons.
A little bit of Frost, a little bit of Nash, and a whole lot of luck.

Wednesday, October 18, 2006

Bless Who?There's a new guy at work who sits in the cube next to mine. The few times he's sneezed, I've said the customary "bless you," but he has always responded with silence.

I imagine his silence arises from feelings similar to those some people have when they hear "under God" in the pledge, or see "in God we trust" on all of our money (so much for rendering unto Caesar what is Caesar's), or are forced to participate in school prayer, or have to view in a courthouse a hulking monument engraved with the ten commandments, only three or four of which can be related to our legal system.

And I can definitely sympathize with this feeling, as "bless you" is a religious phrase, once you think about who's doing the blessing—the full subjunctive form is, after all, "may God bless you."

But when I say it, and I think most other non-religious people would feel the same, I don't say it with religion, I don't feel anything religious. It's simply the one after-sneeze expression we have in English. The German "gesundheit" is available, but it always has a facetious ring to it, and what if you want to be truly earnest, say, after a particularly furniture-rattling sneeze?

If only we could say, "health!" like they do in nearly every other European language, for that is truly what any post-sternutation wishes or concerns should be directed towards. Why associate religion with the high-force expulsion of spit and snot?

Of course, "bless you" supposedly arose from a belief that the soul might leave the body, or that the devil might enter, during a sneeze. Other accounts say it started with Pope Gregory the Great during one of the many historical outbreaks of the bubonic plague, one symptom of which, unsurprisingly, was sneezing.

And before modern medicine, a sneeze could have been considered an omen of greater illness, bubonic plague or no—but still, why not say "health"? "Bless you" seems more morbid, as if you know the person's going to die. It's like you've given up hope, and you think the other person's going to give up the ghost, so you resign yourself to saying, "I hope God blesses you," and perhaps that person won't tumble down to God's eternal torture chamber. (Maybe it really was from those bubonic times, when death was pretty much inevitable.)

"Health!" I'd rather say. "Screw the afterlife, I want you well in this life." But we don't have that phrase available.

So now I've taken to not saying anything at all when someone sneezes. But it feels very odd greeting a sneeze with silence—it feels rude. And I'm sure that my other coworkers, to whom I've always extended a "bless you," have noticed that now I say nothing. Do they wonder why I've suddenly become impolite?

Yet if I continue saying it when it's not desired, that makes me seem somewhat like those obnoxious Christians who disobey their master's command not to "pray standing in the synagogues and in the corners of the streets, that they may be seen of men" (Matthew 6:5), who blatantly advertise their religion and impose it on others. Far be it from me, non-Christian that I am, to make another non-Christian feel that way about me.

Short of finding a new phrase, only one other solution suggests itself to me. But would it be okay to say it to some, and not to others?

At any rate, "health!"
should the English after-sneeze expression change to something less religious?

Sunday, October 08, 2006

Better Coffee

I had rarely for many years used animal food, or tea, or coffee, &c.; not so much because of any ill effects which I had traced to them, as because they were not agreeable to my imagination. ... think of dashing the hopes of a morning with a cup of warm coffee, or of an evening with a dish of tea!
Henry David Thoreau: Walden.

When I came across those lines in Walden, my reverence for Thoreau slipped, not quite a notch, but a few hairs at least. I love coffee. I look forward to the brew almost every afternoon. (I've never really been one to cry for a cup in the morning.)

I enjoy the ritual of making it, the anticipation while it cools just a little, and the hot dark taste as it goes down—not to mention the caffeine fix. That's what got me through the all-nighters I pulled in high school (and one double all-nighter) and college, though the boost I get is milder now.

The passage in which the above quote occurs discusses our animal life vis a vis our spiritual. Thoreau doesn't elaborate much here on his aversion to coffee, instead deliberating on the virtues of abstaining from meat, but it seems to stem from a concern with being enslaved to exotic appetites and addictions at the expense of higher pursuits. Later on he gets more economic:
I did not use tea, nor coffee, nor butter, nor milk, nor fresh meat, and so did not have to work to get them; again, as I did not work hard, I did not have to eat hard, and it cost me but a trifle for my food.
This is not an issue with coffee anymore (except for those who drop $4+ at Starbucks everyday), though there are plenty of contemporary addictions this could be applied to—cars and oil spring to mind, as do disposable AA batteries for all of our portable electronic gadgets.

But I think Thoreau would have plenty more to say about coffee were he around today. I think he would criticize the mass production of inferior coffee products, the exploitation of the environment and people of coffee-producing countries, and our reduction of coffee to the merest utilitarian purpose of giving us a little more energy to work.

I was made aware of all of this and much more when I read Uncommon Grounds by Mark Pendergrast. I left the book at my school in China for the enlightenment of any coffee drinkers who might come that way, otherwise I'd quote from it.

But Pendergrast traces the history of coffee from the legend of Kaldi's dancing goats to the Starbuck's phenomenon of our time, and I highly recommend his book. He particularly focuses on the late 19th and 20th centuries, explaining the increasing intertwining of coffee with international relations, economics, and our domestic lives, as well as discussing how coffee was produced, packaged and sold over the years, and how that influenced the quality and taste of the coffee we drink.

Two things become apparent when reading this book:
  1. Coffee was one of the first products that fell victim to the mantra of corporate America: "how much can we lower the quality and up the quantity, and get people to still buy it?"
  2. Coffee as it is mostly grown is bad for the environment, the economy, and the people of coffee-producing countries.
Because of this, most of the coffee out there is no good, and most people don't really know what a good cup of coffee tastes like—and yet the big coffee companies rake in money every year.

Consider your canned coffee. Generally made from the cheaper, poorer-tasting Robusto beans, grown with pesticides and paid pennies for. Pre-ground long before it's brewed, so it rapidly loses flavor. And old after sitting on the shelf at the store and at home for weeks and weeks, possibly months or even longer. Coffee is a perishable commodity and needs to be brewed as soon after roasting and grinding as possible.

When I read this book, I had been regularly drinking Nescafe Gold instant coffee, as that was the easiest type of coffee to buy in China. After I finished, though, I vowed never to drink instant coffee again, or crappy regular coffee, even if nothing else were available (that's the only way to fight the "increase quantity, decrease quality" corporations). Generally I have succeeded—I can count on one hand the number of times since then I've had crappy coffee with a couple of fingers left over.

I also decided to seek out a better way to make coffee. The book mentioned the French press method as the best, but I never liked the grit that always gets through the filter mesh. I'd used drip coffee makers all my coffee-drinking life, but I knew I'd never had a truly excellent cup from one of those. But aside from a drip, the options available to me in China were nil (although I always saw these cool vacuum pots and other contraptions in the numerous cafés there).

I ended up rigging up something with clothes pins, a large glass jar, and some coffee filters I managed to find. It worked, and not too badly, but though the coffee I used was better than Nescafe Gold, it was not quite the taste I was looking for. (I bought it pre-ground at the French supermarket chain, Carrefour—whole beans, and grinders for them, were impossible to come by—but at least it was real.)

After I came back to America, my quest for a better coffee-brewing method was superseded by the job search and everything else needed to get on my own two feet here. I did get some good beans, though. I tried some organic, shade-grown Green Mountain coffee, as well as Whole Foods' organic store-brand coffee. Now I get Whole Foods' Allegro coffee since they get a newly-roasted batch of beans every week, and you can buy whatever amount you like—I like to get about a week's worth at a time.

But until recently I was still using a drip coffee maker, though the particular model I had was a step up from what I had used in the past. I was still not getting the brew I wanted, and I attribute this to two things: the inside pot of this particular model being difficult to access and hence difficult to clean, and the plastic filter basket.

Coffee always leaves a residue, and just rinsing with water, soap and water, or even coffee pot cleaners does not remove the residue. It has to be physically wiped off. (This is why work coffee is so bad—those huge thermal servers have years of crud inside them, and cannot be cleaned.) Filter baskets are hard to clean effectively what with all the ridges. Furthermore, plastic seems to absorb coffee odors very easily, and it's nearly impossible to remove them. If you use a drip, smell the filter basket and you'll see what I mean (or let me know what soap you use). These old odors get into your coffee every time you brew.

After things settled down in the other areas of my life, I renewed my quest, and decided to give the French press another try, but with a paper basket filter to keep all the grit out. I read somewhere online that this could not be done without the filter shredding, but lo and behold it works, and works very well.

my coffee utensils

The French press I have was a mere $14 at IKEA, and has no plastic parts (except the handle and plunger knob). It also meets my other requirement of it being easy to clean all surfaces that coffee comes into contact with. And 8-10 cup filters fit perfectly in the glass beaker.

a filter in the mouth of the beaker

After the water (just below boiling) is poured over the grinds, I place the filter in the beaker mouth, press it down a little with the plunger, and fold the rest of the filter out over the edge so I can push the lid down.

filter folded over the edge

After 2-3 minutes (that's all the time you need) I lift the lid, fold the filter in, and slowly push down, pausing every 20 seconds or so to shake the press a little to scatter the grinds and allow for the easier flow of liquid through the filter. Pushing down too hard or quickly will cause the filter to tear.

the plunging is done and the coffee is ready

I finish with a beaker full of excellent coffee, and pour it out so it doesn't brew further, and enjoy.

The only other thing I would like to get is a manual burr grinder to replace my electric blade whacker. The best burr grinders are made by Zassenhaus in Germany, but they've not exported any grinders to the US for about two years or so, hence they're hard to come by. I've been watching eBay, but every time a decent one is offered, the price ratchets up to $100+. Don't want one that badly. I've heard that blade whackers cause some flavor loss due to heat, but I just want to switch so I can get one less electronic gadget in my life.

Once I get there, I think I could brew some cups that even Thoreau might try, and hopefully he wouldn't exclaim afterwards, as he did in Walden, "Ah, how low I fall when I am tempted by them!"Bad coffee and how it got that way, and how to make it better.