Blog
Welcome to my blog!
Submitted by dmuth on Sat, 2007-12-15 15:04. BlogWelcome to my blog!
To tell you the truth, I do most of my blogging over on LiveJournal, because most of my friends hang out there.
But I still make occasional blog posts to my website, especially when it's something which I feel is important, or was particular well received by folks over on LJ.
Anthrocon days off
Submitted by dmuth on Wed, 2008-04-23 13:37. Blog | FurryGot my days off for Anthrocon. All 5 of them. From the Wednesday before the con until the Tuesday afterward. The Tuesday is my day of recovery. 
In other news, my mom "found" a $50 savings bond from when I was born. That should be worth quite a bit by now. However, she is holding it hostage until I buy her and my father Anthrocon memberships. Wait, what?!
Pictures from Pittsburgh
Submitted by dmuth on Sat, 2008-03-22 21:27. BlogI spent last weekend in Pittsburgh for some Anthrocon Business. The first thing I wanted to mention is that we have some pictures of The Doubletree in Pittsburgh. The full album is at http://www.flickr.com/photos/dmuth/sets/72157604208248727/
But this is probably the most important picture, taken directly in front of the entrance to the Doubletree:
After our business in Pittsburgh was concluded, some of us took a sidetrip to Randyland. For those of you who dined in the Orchid Restaurant at the Westin last year and interacted with the rather lively and animated waiter named Randy Gilson, you all know who I'm talking about. For those of you who didn't... well, Randy is a bit of a community hero in Pittsburgh. This is a picture from Page 2 of the phonebook:
Happy fellow, isn't he? 
Randy is known for creating what is dubbed "Randyland", a section of homes in a rundown part of Pittsburgh that have been painted all sorts bright interesting colors and designs:
The full album of Randyland pictures can be found at http://www.flickr.com/photos/dmuth/sets/72157604203902962/
Share and enjoy!
Dorsai Thing 33 Report
Submitted by dmuth on Thu, 2008-03-20 11:53. BlogFor the impatient, my entire dump of images from Dorsai Thing 33 can be found over on Flickr.
This year's Dorsai Thing was held in Marina Del Rey, just outside of Los Angeles. The temperature was a lovely 70-75 degrees most of the time, so I didn't spend as much of this Thing in the consuite, but rather on Venice Beach, which was a short walk away. Here's what I got to see in the morning:
I got some pics of town itself, too:
And finally, we had a few really loud Hawaiian shirts:
I believe that Dave and Diana Stein actually won prizes for those shirts. Scary.
Also, this year's Thing had not 1, not 2, but 3 new members inducted to the Dorsai Irregulars. The funny thing about Dorsai Membership is that prospective members are not told that they are under consideration. This means that their induction usually comes as a complete surprise to them. It also makes for some interesting pics of the weekend's inductions:
Induction #1, at the barbecue
Induction #2, at dinner
Induction #3, at the end of dinner
Overall, I had an awesome weekend and can't wait until I see some of the other DI and folk at the next con. And according to my calendar, that would be... Furry Connection North from April 11 to 13 in Ann Arbor, Michigan.
I'll see you there.
Mmm... tea
Submitted by dmuth on Fri, 2008-03-14 10:13. BlogSo, the other day at a meeting, I saw a co-worker make tea with one of these:
The way it works is that the tea steeps in the cup, and then you place it on top of a mug, triggering the value in the bottom that empties the tea. What was fun about this was watching a female co-worker freak out. She said she thought the steeper was "pissing" and that it was "so gross".
So, of course I had to get one for myself! I got a referral from that co-worker to Adagio Teas and ordered their starter set, which includes a steeper, 4 sample teas, and a full color guide to tea that talks about the history of tea, brewing styles, and more. That only cost $19. I set shipping to "ground" (the cheapest), and it arrived the very next day. Badass!
I also like the Adagio site. It has a very strong "social network" aspect to it. The co-worker who referred me is now listed as a "tea friend", and you can write reviews on products that you have ordered, as well as read others' reviews. Bonus: for each review you write, you get 50 cents off of your next order. Adagio also has a tea of the month club. Very well.
Also, now that I'm a customer, I can send out coupons for $5 off of your first order. If you're interested in getting a coupon, let me know.
Did I mention I hope to kick the coffee habit? We'll see how well this works out. 
How to make Drupal 5.x work properly on Nearly Free Speech
Submitted by dmuth on Wed, 2008-02-20 22:29. Blog | DrupalWhen it comes to webhosting, you can't beat NearlyFreeSpeech. They're cheap, fast, and reliable. I've been a very happy customer for years, and run a number of Drupal installations under them.
However, NFSN does do things a little differently, and this can cause some interesting interactions with Drupal. The main thing that they do differently is that they use Squid and run reverse proxies at the edge of their network, which cache requests made to member websites. For most sites, this is not a problem. Drupal, however, tries to be "cache friendly" with regards to the headers it emits, and sometimes this doesn't work so well. I've seen the following symptoms happen under a virgin Drupal installation:
- Going to the site, and instead of getting the page you wanted to see, having the file download dialog come up.
- Seeing stale copies of pages.
- Logging out, and seeing pages indicating that you are still "logged in".
- Logging in, and seeing pages indicating that you are still logged out.
Here's how to fix that:
- Open the includes/bootstrap.inc file, taking care to make a backup copy first.
- Go to the function drupal_page_header() and replace the calls to header() with the following calls:
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate");
header("Cache-Control: post-check=0, pre-check=0", FALSE); - Continue down until you get to the drupal_page_cache_header() function. Comment out the header() call that emits a "304 Not Modified" header" and the following exit() call there. The rest of the header() calls in that funciton should be left alone.
- Finally, to assist with troubleshooting, edit the page.tpl.php file for whatever theme you are using, and add the following line in the footer:
Page last generated: <?php print date("r"); ?>By examining that line, you can tell whether you are retrieving the most recent copy of the page or not, and this can be a valuable tool in troubleshooting cached pages.
Once all of those things are done, any cache issues that your users are experiencing should slowly go away.
Finally, I must admit that I am not any sort of HTTP guru. I merely followed what I read in these specifications:
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.2
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.4
If you know of a better way to fix this problem, feel free to let me know...
How to completely break jqModal in MSIE 6
Submitted by dmuth on Sat, 2008-02-09 15:21. BlogI spent about 2 hours tonight trying to figure out why my modal dialog box refused to work under Internet Explorer 6.0. The symptom was that in addition to the rest of the webpage being grayed out, the modal box was also being grayed out. Not good.
The culprit turned out to be this bit of CSS:
position: fixed;
}
Having the position set to "fixed" will screw you every single time. (Plus, the box displaces your page content, instead of appearing over top of it, like you would expect with a high z-index value.)
The fix is to change the position attribute from fixed to absolute. Once you do that, it behaves as expected in both MSIE 6 and FireFox.
Other than that little problem, the jqModal library is a nice little library which can create pop-up boxes within a webpage that are part of the same window. It can also "gray out" the current contents of the page and force the user to click in the box before continue. Very handy to have, if you want to make the user agree to the T&Cs of a particular website.
Why I love relational databases (oh, and Drupal too)
Submitted by dmuth on Sun, 2008-01-20 13:17. Blog | DrupalThe problem
After I brought Anthrocon's room share and ride share forums online, I noticed that last year's posts were still present. This was a problem because people needing rides or rooms for this year's conventions did not notice the date and were replying to those posts, thus wasting everyone's time.
Now, I dislike removing content from any website I manage, since that can potentially hurt Google's PageRank on the site. If only there were some way of removing the old posts from those forums without actually deleting the posts...
Then I remembered that Drupal's database is in third-normal form and came up with this query after about 15 minutes of fiddling:
INSERT INTO temp_nids (
SELECT nid FROM term_node WHERE nid IN (
SELECT n.nid FROM node AS n
LEFT JOIN term_node AS tn ON n.nid=tn.nid
LEFT JOIN term_data AS td ON tn.tid=td.tid
WHERE td.name IN ('Room Share', 'Ride Share')
AND FROM_UNIXTIME(n.created) < '2007-08%'
)
)
DELETE FROM term_node WHERE nid IN (SELECT nid FROM temp_nids);
The innermost query (SELECT n.nid FROM node...) selects node IDs that belong to the Room Share or Ride Share forums with a creation date before August, 2007. The query around that (SELECT nid FROM term_node...) I originally had in to make sure that we got valid node IDs from term_node. Given how the query evolved, that's probably no longer necessary. The outermost query (INSERT INTO temp_nids) stored the matching node IDs in our temporary table for later use.
The final query (DELETE FROM term_node...) deletes the offending node IDs from the term_node table, which is responsible for linking nodes to taxonomy terms.
In other Drupal news, I stumbled across a nice little article the other day called 10 Reasons to Use Drupal CMS. While I knew some of the things mentioned in that article, I had no idea that entities such as The United Nations, Forbes, The Discovery Channel, AOL, and most surprisingly of all--The Grateful Dead.. all use Drupal. Fascinating stuff.
Also, I found the website Drupal Dojo which contains lots of tutorials on how to perform different tasks in Drupal. It looked just like another how-to type site (not that there's anything wrong with that!) until I came to the article on patch rolling and saw this:
Um, yeah... I sure wasn't expecting to see that particular graphic. 
My 2007 New Year's Experience
Submitted by dmuth on Wed, 2008-01-02 10:23. BlogI flew out to Chicago on Friday night to visit some folks for the New Year's .
The flight out was fun, as Chicago got quite a bit of snow that day and was all backed up. So we sat in Philly for about an hour, then after we landed we got to sit around some more until a terminal and a ramp were freed up for us. The entire story is chonicled in my Twitter. I have vague memories of meeting Duncan and Takaza at the airport sometime after midnight and not getting to bed until WAY too late that night. 
I then spent the rest of the weekend at Wuffmeet, having 3 solid days of fun, and returned home last night. At some point during the trip, we headed over to The Westin in Chicago. It is a really sweet hotel and I think it will make a fine venue for Midwest Furfest in 2008.
I don't have much to say about 2007 other than that it was a very positive year. Many aspects of my life just got better and better, and I saw some good things just continue to build on themselves. I guess you could say it is a kind of compound interest, if you will. A few high points that stick out:
- Paid off the last of my student loans
- Sold my car. This helped my cash flow quite a bit, and was a great way to say "screw you" to both the auto and oil industries.
- Got a Pro Account on Flickr and uploaded over a thousand photos. Photography has always been a hobby of mine, and Flickr made it very easy for me to share this with others.
- Attended a number of furry conventions and got to do a fair amount of traveling.
- Saw that I was starting to gain weight and was able to reverse that trend after paying more attention to what I ate.
- Went to the beach for the first time in several years.
- Opened an account with Vanguard and took more control over my retirement funds. (Ameriprise's website is just awful)
I haven't yet had a chance to upload my pics from either The Westin or Wuffmeet. I'll try to do that tonight.
MSIE Javascript Annoyances: Using parameters in setTimeout()
Submitted by dmuth on Tue, 2007-12-18 12:31. BlogToday's programmatic venting is brought to you by Internet Explorer's implementation of the setTimeout() function under Javascript.
What is setTimeout()?
setTimeout() schedules an arbitrary function call for some point in future. This is useful when you have functions that do repetitive tasks some milliseconds apartment, but not constantly.
The reason why this is used instead of a simply while (true) { ... } loop is because Javascript is a single-threaded language. So if you tie up the interpreter by executing one piece of code over and over, nothing else in the browser gets a chance to run. setTimeout() allows other pieces of Javascript (or browser events, such as clicking on a button) to run, while guaranteeing that your code will be executed at some point.
Sounds cool. How do I use setTimeout()?
Simple, like this:
This will cause a function called function_name to execute a certain number of milliseconds in the future.
For functions that don't need data passed into them, that works great. But what if you want to pass in parameters? In FireFox, you would do this:
And this works great. It will call the function called function_name again in the specified number of milliseconds. Except, MSIE doesn't like this. And rather than throw an error, it just ignores the additional arguments. So when function_name gets called again, its argument is now undefined, and choas ensues.
[Edit: It has since been pointed out to me that the most recent draft of the spec does not allow for additional parameters to setTimeout(). Okay then, but why isn't MSIE at least throwing an error? Silently accepting additional arguments and then just throwing them away is just plain stupid.]
So how do I work around this annoyance?
Closures. Up until now, I thought that closures were very geeky, and used only by CS people who were working on their PhDs. Then I saw this:
Wait, what? What's going on there? Well, it might be a little easier to understand if I write it like this:
setTimeout(f, msec);
What's happening there is a variable called "f" is created, which is actually an anonymous function. That function in turn contains a single line of code:
-- a call to the function we really want to call, with our specified argument. Note that all we have done so far is define a function that calls our target function. We have not executed either that function or the target function -- the target function is essentially "frozen in time". This is a very important concept, and if you've never done this before, you will have difficulty wrapping your brain around it. 
To get a better idea of what's going on, in this case, you could also execute the variable f as a function, since it now *is* a function for all intents and purposes:
Bringing this all together, in the above example, the end result is that the function function_name will be executed after the specified interval, with the desired argument. And this will work in both MSIE and FireFox.
Just out of curiosity, what is a practical application of this function?
I'm glad you asked! As I mentioned above, Javascript is single-threaded. This means that a loop that takes a long time to run can cause the browser to appear to "freeze up" or become unresponsive, which detracts from the overall user experience. A perfect example of this would be populating a div with rows of data retrieved via AJAX. Writing 1,000 rows into that div takes about 3.2 seconds on my machine, during which the browser will not respond to commands.
What I did in my little test was instead of printing each row as it was retrieved, I instead stored them in an array. I then wrote a function which shift()ed and printed only 50 elements from that array. After 50 elements were printed, it then checked to see if there were any elements left in the array. If there were, it would call setTimeout() with itself and the array inside a closure, to be run again in 10 millseconds. The end result took a little longer, 3.5 seconds, but resulted in a much more responsive browser, and happier users.
Share and enjoy!
Source: Passing parameters to a function called with setTimeout, by Bryan Gullen











