August 2003 Archives

Today is the last day to sign up for the national telemarketing Do Not Call list and have telemarketing calls blocked starting October 1st. If you register after today, telemarketing calls won't get blocked until 90 days after you register.

To register, go to http://donotcall.gov/ or call 888-382-1222.

Note: Rhye tried to register our phone numbers and used her Hotmail address to receive the confirmation e-mails. She never received them. I re-registered our phone numbers using my Earthlink e-mail address, and received the confirmations within 60 seconds.

(Hat tip: CalPundit)

Technorati down

The Technorati web site has been down since yesterday. I wonder what's up with that?

Update: Technorati is back up tonight.

Update to Monthly Archive Macro

Thanks to a tip from Lisa (distant, early morning), the Monthly Archives Macro now respects the #renderedFileExtension directive in #prefs.txt. To get the update, download the new version of the macro and follow the directions to install the new version over your old one.

In Radio's discussion forum, Christopher Burton asks how to use a graphic as a link in the Navigator Links. Julie at Sexy Magick offered a Newbie Tip explaining how to add a link to a graphic, which can be used above or below the Navigator Links, but not within them.

As far as I know, Radio's Navigator Links do not support using a graphic as a link within the Navigator Links, but Radio can be tricked into using one anyway.

Open up your favorite text editor, and in a blank page, enter the html that you want to use for a Navigator Link. For this example, I'm going to use the link and image source html from Julie's Newbie Tip:

<a href="http://radio.weblogs.com/0119318/"> <img src="http://radio.weblogs.com/0119318/Screenshots/rose.jpg"> </a>

The problem we have is that the <, >, and " characters in the above html code have special meaning to Radio's XML parser (which is what reads the Navigator Links file). Radio will complain if the above html code is inserted directly into a Navigator Link as-is.

To prevent Radio from treating the <, >, and " characters as special characters, we have to use the html encoded equivalent for these characters, instead of those characters directly. Within the html code, we'll need to perform the following 3 steps:

1. Replace every < with &lt;
2. Replace every > with &gt;
3. Replace every " with &quot;

Either manually, or by using the search/replace function in your text editor, perform each one of the above three steps.

Here's what the html code looks like after the < characters are replaced with &lt; (step 1):

&lt;a href="http://radio.weblogs.com/0119318/"> &lt;img src="http://radio.weblogs.com/0119318/Screenshots/rose.jpg"> &lt;/a>

Now here's what the html code looks like after the > characters are replaced with &gt; (step 2):

&lt;a href="http://radio.weblogs.com/0119318/"&gt; &lt;img src="http://radio.weblogs.com/0119318/Screenshots/rose.jpg"&gt; &lt;/a&gt;

And here's what the html code looks like after the " characters are replaced with &quot; (step 3):

&lt;a href=&quot;http://radio.weblogs.com/0119318/&quot;&gt; &lt;img src=&quot;http://radio.weblogs.com/0119318/Screenshots
/rose.jpg&quot;&gt;
&lt;/a&gt;

Now it is time to insert our new link into the Navigator Links. Open up the Desktop Website, and go to the Navigator Links page.

At the point where you want the new link to appear in the list, insert the following line:

<item name=""/>

Our new link does not need a pagename attribute (and should not have one), because the link is going to be present in the name attribute.

Copy the html text from the text editor and paste it between the quotes of the name attribute. If this is done correctly, our new Navigator Link will look like this:

<item name="&lt;a href=&quot;http://radio.weblogs.com/0119318/&quot;&gt; &lt;img src=&quot;http://radio.weblogs.com/0119318
/Screenshots/rose.jpg&quot;&gt;
&lt;/a&gt;"/>

Click on the Submit button, and check out the new image in the middle of your Navigator Links that should now be there.

Here's a screenshot showing what my page looked like when I inserted Julie's image link into my Navigator Links, following the steps outlined above:

Another Shockwave time waster

Lisa (distant, early morning) says this thing sucks, yet she is still fiddling with it and blames grelf. Heh!

(This is also a sneaky trackback test to see if Lisa's trackback is really fubar or not.)

Comment and trackback monitor for Radio

Check out the Radio Comment Monitor - a comment and trackback monitor which can supply RSS feeds that work in Radio's News Aggregator.

I don't use Radio's comments, but I have been looking for a way to monitor new trackback links. Very nice! (Hat tip: Education Blog - Radio Portal)

Bruce Schneier's new book

Kevin Drum (CalPundit) is reading Beyond Fear, a new book by security expert Bruce Schneier (Crypto-Gram). Kevin hasn't finished the book yet, but he did share this *very* interesting paragraph about cell phone security:

Nokia spends about a hundred times more money per phone on battery security than on communications security. The security system senses when a consumer uses a third-party battery and switches the phone into maximum power-consumption mode; the point is to ensure that consumers buy only Nokia batteries.

I look forward to reading Kevin's review of the book if he decides to write one.

"A Scholarly Critique of the Style, Symbolism and Sociopolitical Relevance of Gilligan's Island." You really have to read the whole thing to appreciate it. Here's a sample:

Gilligan, the Skipper's "little buddy", embodies every extraneous governmental agency, policy and program ever foisted on innocent people anywhere. It is "Gilligan's island." Gilligan is well-intentioned. He sincerely wants to help. Gilligan saves no exertion, refuses no absurdity, respects no boundary in his unceasing efforts to solve, or at least soften, any and all of the everyday problems of the castaways. More often than not Gilligan is the problem. At best he makes a bad situation worse. At worst, he makes a great situation completely unbearable.

In every episode, Gilligan somehow manages to ruin another chance for the castaways to be rescued. Still, in the next episode, everyone will rely on Gilligan for some critical act. Schwartz forces us to ask, "Why do they continue to trust Gilligan when they know he will fail?"

(Hat tip: Daily Pundit; Zogby Blog)

Julie at Sexy Magick starts off a post with a stream of thought on Radio Userland:

Don't know why I find this funny..but everyone is bitching about the lack of response from Userland, calling them names, etc...there are only two guys working on the problems and they both have lives outside of Userland and their jobs. I realize its frustrating as all hell when the response that comes back sounds like a dotcom techno babble that makes no sense to anyone but the person that wrote it or possibly another system admin that totally understands his frustration on why the damn servers keep going down and probably in the middle of the night when he's sleeping..they need to hire another person to help them with the basic day to night system admin stuff..for example the discussion board, the basic newbie troubleshooting and questions, someone that uses Radio frequently and sees the problems happening. The question is should I email Dave and tell him..hire me, I can do the job? I want to be a radio rat (but in a good sense) :)

I've been wanting to comment about this for the last couple of days, but if I posted everything I wanted to say, I'd have 5 full posts' worth of material. So I'll just post some brief comments.

1. "...bitching about the lack of response from Userland" - see this post.

2. "...why the damn servers keep going down and probably in the middle of the night when he's sleeping" - This reminded me of the saying, "A watched pot never boils." Servers almost always go down when they're not being watched. (That probably falls under Murphy's Law too.)

3. "...should I email Dave and tell him..hire me, I can do the job?" - Yes, absolutely!!

4. "I want to be a radio rat (but in a good sense) :)" - Me too, Julie....me too. Though I think I'll have to settle for being just a rogue radio rat.

Shortcuts menu link is finally fixed!

For quite a while, the Shortcuts link on the Radio menu (Desktop Website) didn't work. When I clicked on the link, I got the following error: "[Macro error: This operation is not supported for table values. If you intended to take its address, use the '@' operator.]"

I thought my shortcuts (or something else) in Radio were permanently hosed. Something I didn't know then but I do now is that very little in Radio is permanently broken if you know where to look. I traced the code from the link in the menu back through Radio until I found the code that actually creates the Shortcuts page.

That particular macro reads data from weblogData.shortcuts.personal, so I took a look at the actual data it was trying to read. The first line had a name of "item #1", kind "table". The second line had the title of my first post as its name, and kind "string". The first entry looked wrong when compared to the second one, so I deleted the "item #1" entry. I tried the Shortcuts menu link again and it worked, so one more little Radio annoyance is now taken care of.

Yesterday, I ran across a thread started by a user who complained about lack of response and asked again for an answer to his problem in Radio Userland's discussion forums. This guy obviously just stepped off the clueless boat. I was tempted to tell him so in the discussion forum, but decided I should be nice and say nothing there.

The last time I posted a help request here, I found 48 hours too long to wait for a response to my message--by most standards of end-user support--so I went ahead and re-installed radio and wasted 2 days re-making my sight.

The discussion forums are not "end-user" support - they are "user-to-user" support, or "users helping users". Radio Userland employees occasionally participate there, but they are certainly not obligated to do so. Nobody there is being paid for the time they spend helping others, so if he thinks 48 hours is too long to wait, tough shit.

While reinstalling Radio might have fixed his problem, he took no steps to backup his web *site*. The fact that he had to spend 2 days rebuilding it is his fault, not Radio Userland's. Doing dumb things then whining about how much time it cost does not gain one any sympathy.

Now I'm back to square 1 because the aggregator died again. I went ahead and purchased Radio before my trial ended to guess that this wasn't a factor. I'm frankly tired of guessing because radio doesn't possess sufficient system documentation for me to troubleshoot the problem myself. I hope this time that someone will assist me in a timely manner.

It would seem to me that there is a programming or database issue here. Throwing money at it by buying a license isn't going to solve it. Obviously this guy is incapable of making competent guesses, so why make them at all? Post a message in the forum that describes what is happening and say you don't know what to do.

It is true that Radio does not come with much documentation, but there a lot on the internet - if you know where to look. I was able to figure out bugs in Radio's backup routines and the WYSIWYG editor toolbar with the documentation available on the internet. Even if he had "sufficient system documentation", I doubt this guy could troubleshoot his way out of a paper bag.

I read the "frankly tired of guessing" part (along with the tone of his post) to imply this guy thinks someone owes him an answer. In the forums, you are asking for someone to help you as a favor. Other users who are donating their time in the forums for free certainly don't owe any answers to anybody. While everyone wants help with their problems "in a timely manner", you presume on the graciousness of other users at your own risk.

The mystery is complicated by this observation: there exists no hourly scans for news in my events log.

This is not a mystery; this is probably the actual cause of the aggregator not working. If it can be determined why Radio is not performing hourly scans, the aggregator will most likely be fixed.

Can someone shed some light on this problem? Has anyone experienced something similar? Is there any plan to distribute bonafide system docs so that registered users can understand the constraints and limitations of Radio, and plan their sites accordingly?

With only the information that this guy's news aggregator is not working and Radio is not performing any hourly news scans, it is doubtful that this problem can be solved without additional information. As far as whether anyone else has experienced something similar, that's what search engines are for. I would have searched Radio Userland's forums first (and then the internet) before posting a question about a problem that may have been solved months ago.

Is there any plan to distribute "bonafide system docs"? Dream on, buddy. Even if this guy had such docs, he clearly does not understand the "constraints and limitations" of user-to-user support. I certainly wouldn't expect him to understand the constraints and limitations of something more complicated like Radio's software.

Any response would be appreciated...

Well, there's mine, but I doubt it's what you're looking for.

My last post is what I posted in Radio Userland's forums. I tried to copy it here to my blog so I would have a record of it, but Radio's WYSIWYG editor kept insisting on mangling my post (and especially my script) every time I gave it a chance to look at it. What is below is about as good as I can make it. There is one "error" - the next to last line (just above the </script> should have no semi-colons at the end of it.

Update 28-Aug-2003: I was able to finally get the last post formatted a lot better by using Front Page 2000 and notepad against Radio's WYSIWYG html editor. There's no mangling of the script and no extraneous characters.

Using javascript to fix CSS in Radio's WYSIWYG editor. I was a little hasty in my assessment that users have no options to fix the WYSIWYG editor toolbar when IE6 is in "standards-compliant" mode. I still think it is true that this cannot be fixed with CSS alone, but it can be fixed with javascript.

I've written a javascript that, when added to the Desktop Website template, fixes the non-compliant CSS attributes I described in my last post. This script can be easily enabled or disabled as a demonstration of this problem and its solution.

First, the Desktop Website template's DOCTYPE statement must be set to trigger IE6's "standards-compliant" mode.

In the #desktopWebsiteTemplate.txt file, check for the presence of a DOCTYPE statement at the top of the file. If one is present, it should look something like this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

Change the DOCTYPE statement to the following to force IE6 to use "standards-compliant" mode when rendering the Desktop Website, or add it to the top of the file (above the <html> tag) if it not present:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
                "http://www.w3.org/TR/html4/strict.dtd">

The first line in this DOCTYPE statement is the same as the previous one except that the trailing ">" is removed, and the second line of text (the dtd file with trailing ">") is added right below it.

Insert the following script right below where the <%radio.macros.weblogEditBox ()%> appears in the Desktop Website template:

<script type="text/javascript">
<!--

  var fixToolbar=true
  var buttons=new Array(24,23,23,4,23,23,23,
      4,23,23,23,23,4,23);
  var left=0;
  var spanTags= document.getElementById('idBox')
    .getElementsByTagName('span');
  var imgTags= document.getElementById('idBox')
    .getElementsByTagName('img');
  if (fixToolbar) {

    document.getElementById('idBox').style.height="25px";

    for (var i=0;i<buttons.length;i++) {

      spanTags[2*i].style.display="inline-block";
      spanTags[2*i].style.height="26px";
      spanTags[2*i].style.width=buttons[i] + "px";

      spanTags[2*i+1].style.display="inline-block";
      spanTags[2*i+1].style.height="26px";
      spanTags[2*i+1].style.width=buttons[i] + "px";

      imgTags[i].style.left=-left + "px";

      left+=buttons[i];

    }
  }
//-->
</script>

Save the Desktop Website template. Open the Desktop Website in IE6. The WYSIWYG editor toolbar should be displayed now, even with IE6 rendering the Desktop Website in "standards-compliant" mode. (Try refreshing the page if it the toolbar does not display when the Desktop Website is first displayed.)

To demonstrate that this script is what is fixing the toolbar, disable the script to make to toolbar disappear again:

In the script just added to the #desktopWebsiteTemplate.txt file, change the value of "fixToolbar" from true to false (third line). Save the Desktop Website template and open the Desktop Website again. Now the WYSIWYG editor toolbar should be gone. (Try refreshing the page if it the toolbar is still displayed.)

To re-enable the script and display the WYSIWYG editor toolbar, change the value of "fixToolbar" back to true.

To restore the Desktop Website template back to its prior condition, delete the script and restore the DOCTYPE statement to the first DOCTYPE example above.

This script has only been tested in IE6.

I offer this script as a "workaround", an alternate solution in addition to Lawrence's suggestion of using a DOCTYPE that does not trigger IE6's "standards-compliant" mode.

Jake Savin at Radio Userland realized what the problem was, and issued a permanent fix:

It appears as though you (and others?) didn't have the latest version of radio.backup.backupTemplates. I've re-released the latest version of this part, which should fix the errors.

You may want to re-add the @statusMsg parameter to the call to the radio.backup.backupTemplates call in radio.backup.backupAll, to make sure that you see any error messages that may occur when backing up your templates.

I received Jake's radio.root update early this morning and posted my results back to the discussion thread:

Talk about some lucky timing - my nightly backup completed at 12:21 AM and then I got Jake's root update at 12:25 AM.

I re-added the @statusMsg parameter to the radio.backup.backupTemplates call in radio.backup.backupAll, re-compiled the macro, then did a manual backup. No errors.

I won't know until tomorrow if the nightly backup works too, but I'm not expecting any problems.

Not a big deal, but I wonder how I ended up with a non-current version of the radio.backup.backupTemplates macro.

Thanks for fixing this, Jake!

Case closed!

Heh!

Donald Sensing says "Heh!" at this, but I couldn't stop at just one. (Hat tip: One Hand Clapping)

Julie at SexyMagick asks for someone to explain trackback and how it works. I've left a short explanation in her comments, and hopefully this post will show up in her trackback for that post.

Update 26-Aug-2003: The Cartoonist wants in on this game too, so I'll link him and see if he gets a trackback link. It doesn't look like he's been having much luck in sending trackback pings.

Update 26-Aug-2003 #2: The Cartoonist did not receive my trackback ping. I re-edited this post and put his trackback url into the "URLs to Ping" box. He didn't get that trackback ping either.

I did some digging around and figured out where Radio stores the results of trackback pings - they're stored with the blog posts in weblogData.root (weblogData.posts.[postNumber].trackback.outbound.urls.[urlPinged].errorString).

In the trackback data for this post, the trackback ping to The Cartoonist has this error message:

"Can't open stream because TCP/IP error code 10060 - Connection timed out."

It would seem that Radio's trackback is down for the time being. As I write this, trackback went totally offline.

Update 26-Aug-2003 #3: Okay it's 5 minutes later and trackback seems to be working again. Let's see what happens....

.....okay, trackback itself seemed to be working, but it would not re-ping The Cartoonist's blog. I deleted his trackback url from this post in weblogData.root, re-published this post, and he got my trackback ping.

Putting my new macro tricks to good use

Since I worked out the programming for my monthly archive links macro, I keep seeing little things everywhere that I used to think would never be fixed but now are "not too difficult" or even "easy".

In my news aggregator, I am subscribed to my own XML feed so I can see what is going out on it as I make new posts. The formatting for my posts has never looked like everyone else's, mainly because html tags were being included in the output. This was one of those things that I never thought I'd be able to fix.

Today I fixed it, and it was easy once I knew what to do. I already had a callback script in place to trim the length of each post in the XML feed to 300 characters. What I found out today was that Radio has a built-in function (searchEngine.stripMarkup). All it took was to add that one function to my callback script. The html tags are gone and I am a happy camper.

Tracking down Radio problems

For those who may be interested, I've put up a couple of long posts in the Radio Userland category.

The first one is a debugging of the radio.macros.weblogEditBox macro to show (primarily Radio Userland's programmers) why Radio's WYSIWYG editor toolbar buttons disappear when IE6 is in "standards-compliant" mode. (Bottom line: bad CSS.)

My second post addresses this Radio error:

Radio UserLand's nightly backup failed because there was an error verifying the backup:

Verification of backup failed because the weblog backup for 4/2003 does not exist.

If you use Radio and have been receiving this error, you'll want to read my post to see why this error occurs and how to correct it.

Debugging Radio's nightly backups

Even though I have backups enabled on my copy of Radio, they have never worked since day 1. I was always a bit irritated that it did not, but didn't know enough about Radio to know what to look at and try to fix it.

In this Radio discussion thread, Fernando Alves asked about the same backup error that I've been getting every day. Armed with the knowledge of Radio's internals that I gained from writing my "Monthly Archives Links" macro (plus a few others), I decided to take a crack at figuring out what was wrong. I found the problem and posted my findings on the discussion forum, which is repeated below:

I attempted to trace what the backup process is actually doing. It fails *very* early in the process, because one of the first things the backup process should do after initialization is create the subdirectories to store the backup files in (and this is not happening).

I noticed that the backup process uses a temp table to record various things. What I found interesting is that there was a message in system.temp.radio.backup.lastError:

"Can't complete the backup because an error occurred: Can't call "backupTemplates" because there are too many parameters."

Backing up the templates is the first thing the backup process does, which would explain why the failure is total. I looked into the template backup routines, and I think I found the error.

In system.verbs.builtins.radio.backup.backupAll, look for the line that says � bundle //templates. Open that bundle if it is not already, and look at the second line within that bundle:

radio.backup.backupTemplates (@statusMsg)

Notice that this macro call is passing one parameter.

Now look at the macro that is being called - system.verbs.builtins.radio.backup.backupTemplates. The problem shows up on the very first line:

on backupTemplates ()

This macro takes no parameters, so passing it one *will* cause an error.

Looking at the code, if I had to take a stab at fixing the problem, I would recommend removing the parameter from the macro call in radio.backup.backupAll, so that it looked like this:

radio.backup.backupTemplates ()

Just to be safe, I'd rather let the pros at Radio Userland make the call on how this should be fixed.

The next day, I decided to test my findings, and I reported them in the discussion forum as well:

I decided to test the findings in my previous post and see if I could do a manual backup.

Within the Radio app, in the script at system.verbs.builtins.radio.backup.backupAll, I opened the bundle at the line � bundle //templates. The second line within that bundle contained the following line: radio.backup.backupTemplates (@statusMsg)

I changed that line to read:

radio.backup.backupTemplates ()

and clicked on the Compile button.

I then performed a manual backup using the Backup/Restore page at http://127.0.0.1:5335/system/pages/backup. I could not locate a link to the Backup/Restore page on the Desktop Website. Is there one? Should there be one? I'd vote for a link on the Nightly Backups preferences page (http://127.0.0.1:5335/system/pages/prefs?page=2.16).

The manual backup completed successfully. In the \www\backups directory, I now have subdirectories (\posts, \prefs, \stories, and \templates), and there are files present in each of these subdirectories.

One gripe - the Backup/Restore page said that my files were backed up, and that the backup was verified, but nothing was written to the Events Log to indicate that this really happened.

I did check the status at system.temp.radio.backup.lastError - this field is now blank (indicating that the last backup was successful).

My request to Radio Userland's programmers:

1. Please fix the error in the backup code.

2. Add a link to the Backup/Restore page on the Nightly Backups prefs page.

3. Log manual backups and backup verification on the Events log.

I have not tested any restore operations, so I don't know if they function correctly or not.

Debugging CSS in Radio's WYSIWYG editor

In a prior post, I talked about how certain DOCTYPE statements in a web page can cause Radio's WYSIWYG editor toolbar to disappear in IE6. Yesterday, I decided to see if I could pinpoint exactly what Radio does that causes this effect. I did find the cause, and I posted my findings on Radio Userland's discussion forum. Here is the text of that posting:

I figured out why the WYSIWYG editor toolbar does not display when IE6 is rendering in "standards-compliant" mode.

Some of the CSS generated by the <%radio.macros.weblogEditBox ()%> macro is not within CSS1 standards, and IE6 ignores these "invalid" CSS attributes when it is rendering in "standards-compliant" mode. Depending on the particular CSS attribute involved, this can cause significant differences in rendering between "standards-compliant" mode and "buggy" mode.

Microsoft has an MSDN article which talks about this:

Stricter Style Sheet Parsing

When you use the !DOCTYPE declaration to switch on standards-compliant mode, Internet Explorer 6 or later ignores style sheet declarations that do not comply with CSS1. Earlier versions of Internet Explorer permit you to use certain invalid declarations, such as leaving out the leading '#' sign at the beginning of a hexadecimal RGB value.

One line in particular prevents the WYSIWYG editor toolbar buttons from appearing. Here is the line of code, which is buried in system.verbs.builtins.html.editor.wysiwygEditor (it is within the "div id=idBox" / "script" bundle of code):

s+="<span style='position:relative; height:26;width: " + buttons[i] + "'><span style='position:absolute; margin:0px;padding:0;height:26; top:0;left:0;width:" + (buttons[i]) + ";clip:rect(0 "+buttons[i]+" 25 "+0+");overflow:hidden'><img border='0' src='[[toolbarImgUrl]]' style='position:absolute;top:0;left:-" + left + "' width=290 height=50";

This is a snippet of javascript code which builds the html for the toolbar, one button at a time. The html output by this javascript for the second button would look something like this:

<span style="position:relative; height:26;width: 23"><span style="position:absolute;margin:0px; padding:0;height:26;top:0;left:0; width:23;clip:rect(0 23 25 0);overflow:hidden"><img border="0" src='[[toolbarImgUrl]]' style="position:absolute;top:0;left:-24" width=290 height=50></span></span>

In this one line of code, there are two errors, each committed multiple times -

1. Lengths (such as height and width) have no units (such as px). From the above linked MSDN article:

Missing Unit Type Identifiers Treated as Pixel Values

According to CSS1, length values must specify a unit type identifier, such as cm, mm, in, pt, pc, or px. Values without unit type identifiers and values with white space between the number and the unit type identifier are ignored. Earlier versions of Internet Explorer treat numbers without any unit type identifier as pixel units -- as if "px" were appended to the string.

Within the first span's style:
height:26; should be height:26px;
width: 23 should be width: 23px

Within the second (nested) span's style:
height:26 should be height:26px;
width:23; should be width:23px;

Within the img tag's style:
left:-24 should be left:-24px

When IE6 is in "standards-compliant" mode, none of these CSS attributes are recognized or applied.

2. Span elements are assigned invalid style attributes (height and width). Again from the MSDN article:

Width and Height of Inline Elements

Inline elements such as SPAN, B, and I do not support width or height properties. If you want to set the width or height property of an inline element with standards-compliant mode switched on, you must set the display property of the element to inline-block.

The above line of code assigns both a height and width to each span. As in the error above, IE6 will not recognize or apply a height or width to a span when it is rendering in "standards-compliant" mode (unless the display:inline-block attribute is set).

By correcting these two errors in that one line of code, IE6 will display the WYSIWYG editor toolbar even in "standards-compliant" mode:

s+="<span style='display:inline-block; position:relative;height:26px;width: " + buttons[i] + "px'><span style='display:inline-block;position:absolute; margin:0px;padding:0; height:26px;top:0;left:0;width:" + (buttons[i]) + "px;clip:rect(0 "+buttons[i]+" 25 "+0+");overflow:hidden'><img border='0' src='[[toolbarImgUrl]]' style='position:absolute;top:0;left:-" + left + "px' width=290 height=50";

These are by no means the only CSS errors in the code. The following div, which is the container div for the 4 drop-down formatting boxes just above the toolbar, also has a height with no units (px):

<div id="tb2" style="width: 100%;height:25;overflow:hidden; background:gainsboro;" onselectstart="return false" ondragstart="return false">

This div, which happens to be the container div for the WYSIWYG editor toolbar, has three errors:

<div id=idBox style="width: 100%;text-align: left; ;visibility: hidden, height:25;overflow:hidden; background:gainsboro" ID=htmlOnly>

1. Like the div above, this div has a height with no units (px).

2. The visibilty attribute ends with a comma instead of a semi-colon.

3. There are *two* id attributes in this div. At the beginning is "id=idBox", and at the end is "ID=htmlOnly".

I had hoped that these problems could be overcome with some appropriate declarations in the style sheet. Unfortunately, this is not possible.

The width for each toolbar button's span element needs to be set in the style sheet in order for this to work, but the width varies from button to button. The left attribute in the img tag needs to be set as well, and it varies from button to button too.

Until Radio Userland's programmers fix up the code for the <%radio.macros.weblogEditBox ()%> so that it outputs valid CSS, the only option available to users is to not use DOCTYPE statements in their templates that cause IE6 go into "standards-compliant" rendering mode.

Powers of 10

Kevin Drum over at Calpundit reports on some milestones he has reached this week: he's now averaging 10,000 visits per day and he got his one millionth visitor yesterday. Congratulations, Kevin!

On this side of the fence, my powers of 10 are not nearly so spectacular. Two days ago, I posted a new tool that Radio Userland's users had been wanting for several months. After Radio Userland posted this on the Product News page, and it went out on their RSS feed, I've gotten about 100 visitors from it so far. The only other power of 10 worth mentioning is that I have about 10 links at Technorati. I'm glad for the traffic that I'm getting now, but compared to Kevin, I have a lot of room to grow.

Getting noticed at Radio Userland

| 2 Comments

Radio Userland posted an announcement of my new monthly archive link macro on their Product News page. Thanks, Radio Userland!!

Update 21-Aug-2003: Radio Userland has listed my monthly archive macro on their "Documentation > Tips from other Radio Users > Scripts and utilities" page.

I've put up the first release of my macro along with documentation on it. The post is really long, so I've posted it only to my "Blogging" category blog page. If you're interested in seeing what the final version can do, you can read all about it here. Link to Radio Userland discussion forum post is here.

I've searched high and low for a macro that would create a list of links to the monthly archive pages without success, so I decided to try and write one myself. This is a macro is a Cadillac - there's many features in it that many people may never use, but hopefully it will be of use to the largest possible number of Radio Userland users.

In deciding what the macro should be able to do, I included macro programming to do what I wanted it to do, what some posters on Radio Userland's forums have requested, and some things I thought would be cool or handy features for the macro.

How to install this script into your Radio.root

  1. Download the file to your local hard drive.

  2. You will then need to install it into Radio. Bring your Radio application to the front. From the 'File' menu choose 'Open...' and then select the newly downloaded script. A box will open, asking "Name for imported object?" and "workspace.monthlyArchiveLinks" will be displayed in the text box. Click OK to install the script. You will then see the script in a window.

    If you installed a previous version of this macro, you can install a newer version over an older version. Follow the steps #1 and #2. After clicking "OK" to install the script, another box will display which asks, "Replace existing object named workspace.monthlyArchiveLinks?". Click Yes to install the new version.

  3. Click Compile, then close the window. (Or take a look at the code if you want to see what is under the hood, then close the window.) The macro is now ready to use.

Feedback, comments, and suggestions to improve this macro are welcome.

Update 21-Aug-2003: hideInactive parameter added and documentation updated in response to a comment left by Jim Biancolo on Radio Userland's discussion forum.

Update 30-Aug-2003: Macro now respects #renderedFileExtension directive in #prefs.txt. Thanks to Lisa at distant, early morning for the tip.

Update 01-Sep-2003: Fixed Home Page archive links bug that caused macro to not correctly determine if a month has posts. (Incorrectly used nameOf instead of indexOf to get index number for post.)

Update 26-Oct-2004: Fixed bug where date format with month and year having no separating characters (such as "mmmyy") would give incorrect output for month names ending in a "y".

Documentation is included in the macro as comments, and reprinted below:

Features

  • Automatically determines range of dates to create monthly archive links for.

  • For dynamic pages (pages served locally on the Desktop Website), relative links starting at / are provided for the monthly archive links.

  • For static pages (pages upstreamed to a web server), full URLs for the monthly archive links are provided.

  • If the page being rendered is a category web page, monthly archive links to the category archive pages are provided.

  • If no posts were made in a particular month, the macro can optionally render that month as plain text instead of a link (so as to not link to a page which doesn't exist), or not render that month at all (omit that month from the list).

  • A start date, end date, or both can be specified to restrict the date range monthly archive links are created for.

  • Monthly archive links can be displayed in ascending or descending chronological order.

  • Separator text can be customized to create a vertical or horizontal list of links as well as include any special characters desired between monthly archive links.

  • Date format strings can be used to customize the appearance of the date text displayed for each monthly archive link.

  • Uses CSS classes for archive links, inactive archive "link" text, and separator text.

Usage

<%workspace.monthlyArchiveLinks (start:"date1", end:"date2", order:"o", separator:"sep", dateFormat:"format_string", hideInactive:true)%>

All parameters are optional and will use default values if omitted. (Using the macro can be as simple as including <%workspace.monthlyArchiveLinks ()%> in your template.)

Parameters:

start:"date1"

Type: string
Default: nil ("")

Valid values: Any string which can be interpreted as a date

  • Numbers separated by slashes or dashes, in the order in use by the system (e.g., "4/20/91" or "20/4/91" or "4-20-91" or "20-4-91")

  • Standard abbreviations for the month, with or without punctuation (e.g., "April 20, 1991" or "Apr 20, 1991" or "Apr 20 1991").

  • The full month, day and year (e.g., "April 20, 1991").

This parameter determines the beginning of the time period monthly archive links are created for.

If omitted, or has a value of nil (""), this parameter is set to the date of the earliest post (1st post) in the weblog.

Date for start parameter ("date1") must be less than or equal to date for end parameter ("date2"); otherwise the macro will exit with no error and no links will be created. Use the "order" parameter to reverse the order of links.

If an invalid date string is used, the macro uses the default value (date of 1st post in weblog) and outputs an error message along with the list of monthly archive links.

end:"date2"

Type: string
Default: nil ("")

Valid values: Any string which can be interpreted as a date

  • Numbers separated by slashes or dashes, in the order in use by the system (e.g., "4/20/91" or "20/4/91" or "4-20-91" or "20-4-91")

  • Standard abbreviations for the month, with or without punctuation (e.g., "April 20, 1991" or "Apr 20, 1991" or "Apr 20 1991").

  • The full month, day and year (e.g., "April 20, 1991").

This parameter determines the ending of the time period monthly archive links are created for.

If omitted, or has a value of nil (""), this parameter is set to the current system date (today).

Date for end parameter ("date2") must be greater than or equal to date for start parameter ("date1"); otherwise the macro will exit with no error and no links will be created. Use the "order" parameter to reverse the order of links.

If an invalid date string is used, the macro uses the default value (current system date) and outputs an error message along with the list of monthly archive links.

order:"o"

Type: string
Default: nil ("")

Valid values (case insensitive): "" (nil), "ascending", "ascend", "a", "descending", "descend", "d"

This parameter determines the chronological order of the monthly archive links.

For values of "" (nil), "ascending", "ascend", or "a" (or if this parameter is omitted), monthly archive links are listed in ascending chronological order (earliest to latest).

For values of "descending", "descend", or "d", monthly archive links are listed in descending chronological order (latest to earliest).

If an invalid value for this parameter is used, the macro uses the default value ("ascending") and outputs an error message along with the list of monthly archive links.

separator:"sep"

Type: string
Default: "<br/>"

Valid values: Any string

This parameter determines the separator text which is output between each monthly archive link.

If omitted, this parameter is set to a value of "<br/>". If set to a value of nil (""), monthly archive links will be created with no separator between them.

For vertical links, "<br>" or "<p>" can be used as a separator to put a line-break between each link.

For horizontal links, "&nbsp;" (non-breaking space) or a "|" character can be used as a separator.

No checking or processing is performed on separator string text. Invalid html included in separator string will have unintended effects.

dateFormat:"format_string"

Type: string
Default: nil ("")

Valid values:

Nil ("")

Literal value of "monthRange" (case sensitive)

Format string:

  • String must contain at least one of the following: "m", "mm", "mmm", "mmmm"

  • String may optionally contain at least one of the following: "yy", "yyyy"

  • String may contain other spacing and/or separator characters as desired

This parameter determines the date format for the text of the monthly archive links.

Value of "monthRange" produces links in the format of "08/01/2003 - 08/31/2003".

If a fomat string is used, the string must contain a "month" format code. A "year" format code is optional but recommended.

To display the month and year, include the following format codes in the format string:

  • "m" - displays months as 1 - 12
  • "mm" - displays months as 01 - 12
  • "mmm" - displays months as Jan - Dec
  • "mmmm" - displays months as January - December
  • "yy" - displays years as 00 - 99
  • "yyyy" - displays years as 1900 - 9999

If omitted, or has a value of nil (""), this parameter is set to a default value of "mmmm yyyy" (produces links in the format of "August 2003")

If this parameter does not contain a month format code ("m", "mm", "mmm", or "mmmm"), an error message is output and the macro exits (no links are created).

Leading and trailing spaces are trimmed from format string before creating monthly archive links.

Other characters present in format string are included as a part of the monthly archive link text as-is.

Examples of format strings used to format an August, 2003 monthly archive link:

  • "yyyy-mm" = "2003-08"
  • "mmmm, yyyy" = "August, 2003"
  • "mmm yyyy" = "Aug 2003"
  • "mmmyy" = "Aug03"
  • "mm.yyyy" = "08.2003"
  • "mm-yy" = "08-03"
  • "mmmm" = "August"
  • "< mmm >" = "< Aug >"

hideInactive:true

Type: boolean
Default: false

Valid values: true, false ("true", "false", 1, 0 also allowed)

This parameter determines whether months that have no posts are included in the list of monthly archive links.

If omitted, or has a value of false, months that have no posts are rendered as an "inactive" link (month is displayed as plain text only).

If parameter has a value of true, months that have no posts are not rendered and not included in the list of monthly archive links.

Values other than those listed above may cause unexpected behavior:

  • A non-zero numeric value will evaluate as true (inactive months not be rendered)

  • A value of nil ("") will evaluate as false (inactive months will be rendered)

  • Any non-empty string value other than "false" (case insensitive) will evaluate as true (inactive months will not be rendered)

adrBlog

Type: address
Default: radio.weblog.init ()

Valid values: ?? Use of this parameter, and use of values other than default not recommended

CSS classes

monthlyArchiveInactiveLink

Class used for monthly archive "link" when there are no posts for that month (and no link is created). This class should have same CSS as "a" tags (links) but use different color to indicate that the "link" is disabled. (I use "color: #999;" to indicate this.)

monthlyArchiveLink

Class used for "a href" tags of monthly archive links. Any characters included in the format string besides month and year format codes will also take on this formatting.

monthlyArchiveText

Class which encloses all text output by macro. Most notably, this class can be used to format separator text (for example, if "|" characters are used in a horizontal list of links, this class can be used to change their color, etc.).

Possible issues

If a category is being upstreamed to a different server than the main blog, it is not known if this macro will function correctly. (This case is untested.)

Changes

10/26/2004 - Fixed bug where date format with month and year having no separating characters (such as "mmmyy") would give incorrect output for month names ending in a "y".

09/01/2003 - Fixed Home Page archive links bug that caused macro to not correctly determine if a month has posts. (Incorrectly used nameOf instead of indexOf to get index number for post.)

08/30/2003 - Respect #renderedFileExtension directive in #prefs.txt

08/21/2003 - hideInactive parameter added and documentation updated

08/20/2003 - Macro created by David Phillips (TweezerMan)

I changed the way the monthly archive links are generated again. I scrapped using links in an opml file and decided to try to write a macro to automatically generate the proper links. I searched high and low on Radio Userland's forums for a macro to do what I wanted, but didn't find any. All I found were other people's requests for such a macro that went unanswered.

Designing and writing the macro was hard. Figuring out the proper approach, how to hook into existing Radio Userland routines, whether the address or value of a variable is needed, the actual commands needed and their syntax, trying to cover all of the "what if the macro runs into something bad or unexpected" scenarios - all of this and more took a lot of time. I think it is safe to say that it is not perfect, but it works and does everything I want it to do right now.

Here's a summary of what my new macro does:

  1. Calculates the proper starting month/year (uses posted date of 1st post in blog) and ending month (uses current month/year) for the archive links automatically. Calculates the possibility of an archive link for each and every month in between.

  2. If the web page is a category page, the macro calculates monthly archive links to the category archives and not the main blog's.

  3. For each month in the archive list, the blog is checked to see if a post was actually made in that month. If a post is present, a link is created to the archive. If there are no posts for that month, the plain text of the month/year appears with no link (which should make it display in a different color as well). For category pages, this check is made by determining if a post in that category was made for that month.

  4. If the web page is being upstreamed (being FTP'd to a web server), full URLs for the archive links are provided so the links will work on any page of the blog, whether it's the home page, a category page, an archive page, or any other page.

  5. If the web page is dynamic (served locally on Radio Userland's Desktop Website), relative links starting at / are provided for the archive links. Category pages on the Desktop Website are given relative links to the local category archive pages.

I was tempted to post the code of the macro here, but I think I may tweak it a little more first. These are some of the things I feel need to be looked at:

  • If I correctly understand one of the Radio Userland macro calls I used, it assumes that every post created is posted to the main blog. This is probably a safe assumption for most users, but I can think of at least 1 case where this assumption is not valid and I'm not sure how the macro would handle that case.

  • I am not confident that if a category is being upstreamed to a different server than the main blog that the code would still work correctly.

  • The checking I do to ensure I'm working with a valid category seems excessive, which makes me wonder if I'm checking it correctly.

  • I need to apply a CSS class to the "a href" tags the macro generates.

  • I think it would be a good idea if the macro could accept starting and ending dates to calculate the month/year list of archive links for. This would be useful to generate archive links only for the current year, for example.

Regardless of whether I post the code here, I probably should post it over at Radio Userland when I'm a little more comfortable with it. More Radio Userland users are likely to see it that way.

A little background: Both Rhye's PC and my PC have a Hauppauge WinTV card installed on our computers. The cards are connected to infrared receivers attached to the front of each monitor. An infrared controller application runs in the system tray to read key presses from the remote control and sends them as keyboard characters (keystrokes) to the Hauppauge WinTV application.

The infrared controller has some flaws in it. If it is running, and the WinTV application is in the foreground, everything works like it is supposed to. When the infrared controller is running and WinTV is not in the foreground, the controller appears to send its keystrokes to every application running on the task bar. Unfortunately, the infrared controller does not check to see what application it is talking to, and whatever application happens to be in the foreground will accept the infrared controller's keystrokes just like they were typed at the keyboard. (Background applications appear to ignore the keystrokes.)

Most of the time, this is not a problem. I normally run the infrared controller application 24/7, and when I'm using the WinTV remote control, I always have the WinTV application in the foreground. The problem is when Rhye uses her remote control to command her WinTV card while I'm working in another program on my PC.

Both of our computers are on the same side of the room, and it is difficult for Rhye to point her remote control in such a way that her computer sees the infrared signal but mine does not. So more often than not, both WinTV cards execute commands from Rhye's remote control.

A month or two ago, I was working on a MS Word document. Rhye started entering channel numbers with her remote control, and MS Word happily picked up the key presses and entered them into my document. I told Rhye what was happening and we both laughed about it - it was easy to see what was happening, and easy to fix.

Last night, I was looking at some of the programming scripts in Radio Userland's radio.root (main) database. While I had a script open, Rhye pressed a couple of the number keys on her remote control to change channels. Unfortunately for me, a whole line of text was selected in a core Radio Userland script, and the keystroke replaced the entire line of text with the number Rhye pressed on the remote control.

Without knowing what the original text was, the only option I thought I had was to reinstall Radio Userland. Then I remembered I had made a backup of the entire Radio Userland directory, including the radio.root database. I extracted a copy of the old radio.root, renamed it radio2.root, and opened it in Radio Userland. It complained a lot, but I was able to see the affected script in both databases and copy the correct code from the old database to the current database. Disaster averted!

My lesson for the evening: Don't run the infrared controller app when I'm working on other things on the computer - especially if it's programming.

Back in this post, I mentioned a problem I ran into while I was trying to make the html code on my blog "standards-compliant":

One thing I learned while I while trying to validate the html was how to break Radio Userland's WYSIWYG html editor. According to the W3C standards, the DOCTYPE in an html file is supposed to specify the full path to a DTD (document type definition) file. If such a path is specified, Radio Userland's WYSIWYG html editor no longer displays the formatting and linking toolbar at the top of the editor. (I have no idea why, but I suspect that it has something to do with the fact that the WYSIWYG editor code has an IFRAME tag in it.) It took me quite a while to figure out that this is what caused my toolbar to disappear.

While I was learning about how to use CSS (styles), I read about how CSS implementation was broken in Internet Explorer (IE's "broken box model", among other things), and that IE6 has a "standards-compliant" mode and a "buggy" mode of rendering CSS. I had no idea that rendering differences between "standards-compliant" mode and "buggy" mode were what caused the toolbar to disappear - until today.

While I was trying to find the answer to another problem, I ran across an MSDN (Microsoft Developers Network) article that talks about this very subject.

Versions of IE prior to IE6 do not render CSS in accordance with W3C standards. IE6 defaults to using the "buggy" mode (Microsoft calls it "compatibility" mode) in order to display pages similar to the way a prior version of IE would.

The "standards-compliant" mode is supposed to render CSS in accordance with the W3C standards. This mode is turned on if certain conditions are met by an html page's DOCTYPE. The following table shows which values of the DOCTYPE declaration turn on standards-compliant mode with IE6 or later.

Label Definition URL present URL not present
No !DOCTYPE present   Off (buggy) Off (buggy)
HTML (No Version Present)   Off (buggy) Off (buggy)
HTML 2.0   Off (buggy) Off (buggy)
HTML 3.0   Off (buggy) Off (buggy)
HTML 3.2   Off (buggy) Off (buggy)
HTML 4.0 No Definition Present On (compliant) On (compliant)
HTML 4.0 Frameset On (compliant) Off (buggy)
HTML 4.0 Transitional On (compliant) Off (buggy)
HTML 4.0 Strict On (compliant) On (compliant)
XHTML   On (compliant) On (compliant)
XML   On (compliant) On (compliant)
Unrecognized !DOCTYPE   On (compliant) On (compliant)

All of the themes that come with Radio Userland except one ship with the DOCTYPE highlighted in green above - HTML 4.01, Transitional, no URL. (The one exception has no DOCTYPE declaration at all.) Web pages rendered by Radio Userland therefore all use IE6's "buggy" mode of rendering CSS.

By adding the DTD URL to the DOCTYPE, I unknowingly switched IE6 from "buggy" mode to "standards-compliant" mode. Something in the code used to build the WYSIWYG html editor doesn't work right when IE6 is in compliance mode. The WYSIWYG html editor only shows up as a macro call in my template (radio.macros.weblogEditBox ()), so I would have to look at the rendered html to see what the macro is putting in there.

I don't know if this is something I can fix - it depends a lot on the actual html code used to build the editor. But at least now I know why the WYSIWYG html editor toolbar seemed to disappear at an odd time.

Update 22-Aug-2003: Sometime in the past, I thought I had seen something on this issue somewhere on Radio Userland's web site. While I was trying to solve this problem, I was unable to find that page. I was looking for something else today on Radio Userland's web site and found it again. Radio Userland has known (or at least suspected) this was an issue for several months now (since 01/31/2003). I guess it's nice that Radio Userland at least confirmed this problem's existence and the solution that I ended up figuring out on my own.

Update 24-Aug-2003: More details on this issue are available in this post.

New issue of Crypto-Gram is online

Bruce Schneier has published another edition of his monthly Crypto-Gram newsletter ("...providing summaries, analyses, insights, and commentaries on computer security and cryptography"). Bruce's newsletter is always informative, whether the articles are serious or humorous - and this month is no exception.

In addition to writing excellent articles on his own, Bruce also links to a number of interesting stories elsewhere on the internet. Here's a sample of linked stories in this month's newsletter:

If you have an interest in security - computer security, information security, or physical security - Crypto-Gram is definitely worth reading. I personally enjoy stories about "stupid security".

Microsoft seems to be more than a little concerned about the new Blaster worm that is making the rounds. The worm's mission is to use compromised machines to launch denial of service attacks against Microsoft's Windows Update servers.

I say this because Microsoft e-mailed me 6 basically identical bulletins in one day about the worm and what steps I needed to take to protect my computer from it. Evidently I subscribe to 6 Microsoft e-mail newsletters (I've never counted how many nor cared). Each bulletin had the title of a different newsletter in the e-mail's subject.

With all of the *smart* people that work at Microsoft, I'd have thought someone would think to combine the distribution lists for all of their newsletters and weed out the duplicates before mailing, so that only one e-mail is sent to each address. The fact they did not makes me wonder if Microsoft decided it was more important to blast every e-mail address on file as soon as possible rather than taking some time to eliminate duplicate mailings. Sending me 6 e-mails actually decreases the chance I'll read any of them though (let alone all 6).

The ironic part of all this is that all 6 e-mails were wasted on me. Rhye's computer and a third computer we have in the living room are running Win98SE and are not vulnerable to the worm. My machine is running XP Home and I've had the patch that protects against the Blaster worm installed for a month. All 3 machines are behind a hardware firewall and run Zone Alarm as well. My machine has Norton Antivirus running on it. The other two are not running antivirus software - that's probably the only weak area in our home network.

I know a lot of people don't patch their machines as often as they should, so there's going to be a large number of infected machines out there. It will be interesting to see what happens over the weekend (that's when the worm is supposed to start its first denial of service attacks against Microsoft), and how Microsoft deals with it - especially since Microsoft does not have a stellar reputation in the computer security field.

I changed the method used to create the list of links on the right. Radio Userland has a built-in "Navigator Links" xml format file for this purpose, but it is somewhat limited in what it can do. I'm now using a Radio "outline" to create a opml format file (like xml, but different), which is then used to output the list of links. The outline makes setting up and managing the links quite a bit easier (editing, customizing, adding html code, etc.). It is also possible to use macros in the outline.

One problem I had that it took me a while to figure out was how to add "attributes" to links in the outline. If a person can figure out how, a "title" attribute (to display a tooltip when the mouse hovers over the link) and a "target" attribute (to specify which window the link should open in when clicked) can be added to each link.

I discovered two ways to add a title or target attribute. One is to edit the opml file directly in a text editor. Find the line with the link you want to modify, and add the string title="LinkTooltip" or target="_blank" before the "/>" characters at the end of the line.

The other way is to select the link you want to add an attribute to. Open the "Quick Script" window (Tools, Developers, Quick Script on the Radio menu, or Ctrl+; in Windows / Cmd-; on the Mac?). Enter the following in the Quick Script window:

op.attributes.setOne ("attName", "attValue")

where attName is the name of the attribute you want to add ("title" or "target") and attValue is the value you want to set for that attribute. Run the script by clicking the "Run" button or pressing the Enter key. After setting an attribute, they can be examined by right clicking on the link and selecting "Debug". If the attribute was set correctly, it will appear as a table row in the Debug window.

Relative links are still a big problem. I'm hoping that I will find a macro or figure out how to write one that handles relative links correctly (especially the monthly archive links), no matter if the links are on the home page, a category home page, or an archive page for either one.

More blog changes

I've got one item pretty much done on my "to do" list - categories are now live on my blog. There's a new section in the links column to the right (below "Monthly Archives" and "Navigation") with the categories I decided to start off with.

Each category page is almost like a stand-alone blog (and they could be if I wanted them to be). Instead of showing "The Tweezer's Edge 2" at the top of the page, each page displays the category name and category description. Initially, I hated this, but I think I'm getting used to it now.

I found a neat little piece of code that takes a post, lists all the category names it has been routed to, and formats the list as links to the appropriate category blog pages. I tweaked it to use css instead of font tags, display at the bottom of the post instead of above it, and learned enough of Radio Userland's scripting language to fix a few bugs in it.

One thing I like about having categories is that instead of having to search through my entire blog to find a series of posts scattered over weeks, I can click on the appropriate category link and see them all in one place. Hopefully this will help my blog readers too. A number of blogs have linked to one of my posts about Movable Type's licensing. Sometimes I wonder if the people who read that post know of what I wrote later on the same subject and would be interested in reading those too. Now there is a link at the bottom of the post they can click on if they want to see them all.

One minor bug is that the "Monthly Archive" links on the category pages are links to the main blog archives, not the category archives. That is going to take some work to fix. I'm probably going to have to learn more scripting and write my own code to create the correct links. It's not a big deal right now, but it is something I would like to fix.

While I was at it, I decided to change the "description" of my blog. It used to be "Random thoughts from an inmate at the asylum" and now reads "Blogging the thoughts and adventures of TweezerMan!".

A friend of Rhye's who lives in Lexington, Texas was kidnapped at gun-point a week and a half ago while in her car. The kidnapper forced her to drive to Oklahoma City over the next several hours, where she was finally able to get away. She called Rhye a few days ago to tell her what happened and to let Rhye know about her story appearing in the the local newspaper.

The newspaper's links (if you can call them that) are kind of hard to follow. Here are the links to the three parts of her story:

Part 1 - Front Page - "Lexington Woman Abducted at Gun-Point in Broad Daylight"

Part 2 - Lifestyles Page - Scroll down to "Abduction (Cont'd from Front Page)"

Part 3 - Church Page - Scroll down to "Abduction (Cont'd from Lifestyles)"

Rhye told me her friend is still pretty shaken up from the incident. It wouldn't surprise me if it took her weeks or even months to recover from her ordeal.

Rhye asked me what I might have done. A situation as dangerous as that one has to be constantly evaluated to decide whether a particular action is too dangerous or not, and I wasn't there.

Given that, a number of options are possible at a convenience store / gas station while you're filling up the car with gas. I would have considered any or all of the following:

  • Tell the clerk to call 911 immediately and report a kidnapping.

  • Write a quick note to the clerk with "Call 911 - Kidnap" and my license plate number on it.

  • Give the clerk my drivers license and tell them to call the police and report a kidnapping.

  • Ask the clerk to lock the front doors, go hide in the back of the store, and call the police.

  • Tell the clerk to activate their silent robbery alarm (if they have one).

Most of these require a lot of confidence in the clerk: the clerk needs to be intelligent enough to understand the situation quickly, to believe you are telling the truth, and to act quickly and discreetly. Police response time needs to be rapid as well - if the police can't get on the scene within 5 minutes, the situation would get a lot worse before it got better by involving the clerk and the store.

If I thought it was likely that the kidnapper would kill me in some secluded area, I told Rhye that one drastic option that I would consider is to crash the car into a bridge pylon. Just before I did, I'd check my seat belt to make sure it was snug, and hopefully, the kidnapper won't be wearing his.

Rhye's friend was able to escape her kidnapper because he was stupid and she took advantage of the opportunity that presented itself. The kidnapper 1) got out of the car, 2) turned his back on his victim, 3) put his gun by into his back pocket (took his hands off of the gun), and 4) then put both hands down his pants. For Rhye's friend's sake, I'm glad he was a dumbass.

Update 16-Aug-2003: The above links to the story in The Lexington Leader are now broken. The story has rotated into the newspaper's archives, with only Part 1 available there. Part 2 and Part 3 are nowhere to be found. I have sent an e-mail to the newspaper, requesting permission to reprint the entire story here on my blog. It will be interesting to see what their response is.

Blog theme redesign finally complete

I finally bit the bullet and rebuilt my blog templates last night and this morning. It is not a pure css design, but the browser interface to my blog (the Desktop Website) is no longer screwed up.

To get around the problems I discussed in my last post, I enclosed the entire blog in one table - one row for the header, one row with a cell for the blog posts and a cell for the links column, and one row for the footer. Within the blog templates, I replaced as many tables as possible with css. On the external blog, the only table that should be present inside of the blog is the daily archive calendar. The browser interface to my blog (the Desktop Website) has quite a few more as a number of the pages create tables via macro calls, but I can live with that.

I pulled out the style sections from all of my blog templates and combined them into an external style sheet. Now when I want to tweak a style, I only have to do it in one place instead of 3.

Another advantage to my layout and design is that it presents the blog content first (as opposed to the Navigator Links column first). Supposedly this is good design. I used the Lynx Viewer (a text-based web browser) to verify how my blog was presenting its content. It was interesting to see how my site looked on a text browser.

I tried to validate the html code I had come up with. W3C's HTML Validator found one problem with my comment links that I fixed. Beyond that, it chokes on all the code that Radio Userland inserts into the html to make TrackBack work.

One thing I learned while I while trying to validate the html was how to break Radio Userland's WYSIWYG html editor. According to the W3C standards, the DOCTYPE in an html file is supposed to specify the full path to a DTD (document type definition) file. If such a path is specified, Radio Userland's WYSIWYG html editor no longer displays the formatting and linking toolbar at the top of the editor. (I have no idea why, but I suspect that it has something to do with the fact that the WYSIWYG editor code has an IFRAME tag in it.) It took me quite a while to figure out that this is what caused my toolbar to disappear.

I moved on to W3C's CSS Validator to see if my new css code would pass muster. Again, the validator found one mistake, which I corrected. The blog passed on the second try, so I now have the "Valid CSS" logo at the bottom of the page.

I think I'm done with the basic design for a while. I know I'm tired of messing with it (not to mention tired of reading up on html and css and trying a dozen different ways to solve various problems).

Next on my "to do" list is 1) looking at getting categories up and running, and 2) using some of Beth's factfile tips to create a robots.txt file so search engine bots will index my blog smarter.

I've still been trying to figure out over the last couple of days how I could change my blog theme templates to make better use of CSS. The theme I'm currently using is a "CSS-based" theme, but it's basically just a CSS wrapper around an ordinary web page built using tables. I thought I could make the blog itself almost totally free of tables (the one exception probably would have been the calendar in the upper right-hand corner). Unfortunately, the local web page interface (otherwise known as the "Desktop Website") doesn't play very well with CSS, due to 1) how Radio Userland creates those pages, and 2) CSS rendering issues in IE6.

The core of the problem is that a number of the web pages on the Desktop Website have html INPUT and TEXTAREA form fields. These fields, rendered within table cells, are hard-coded to be too wide within Radio Userland's programming (macros in the radio.root database).

No matter how the CSS is set up, the left and right columns never appear side by side, because IE6 expands the width of table cells (and its CSS container box) to accommodate the excessive width of the form fields (usually expanding it to the full width of the browser window). From what I've read, this is a long-standing rendering flaw in IE6.

It is possible to modify the macros directly to create the INPUT and TEXTAREA fields at shorter widths, to remove the tables from around them, or to embed a CSS class attribute within the form fields so that they may be more easily manipulated with CSS. This solution is a temporary one at best, as any changes made to the radio.root database macros will be overwritten by the next Radio Userland radio.root update.

It is also possible to use CSS in a broad manner to override to the hard-coded form field widths. With no class attributes on the form fields, it is impossible to target specific fields - it's an all-or-nothing affair. Also, text fields are rendered at the desired width, but submit buttons are widened to the same width as the text fields they are under.

IE6's lack of full support for CSS2 also precludes some other solutions that occurred to me. IE6 does not support the max-width property. IE6 also does not support the use of attribute selectors, so I cannot define styles for input[type="text"] and input[type="select"] to apply different styles to input text boxes and submit buttons.

The bottom line is that I don't think there is any "perfect" solution. Any such solution is dependent on action from Microsoft and/or Radio Userland, and I know better than to hold my breath waiting for any solutions from them in the near future. I'd still like to try to drastically reduce the number of tables used in my blog templates. Hopefully I can come up with something that works both on the blog as well as the Desktop Website.

Eugene Volokh (The Volokh Conspiracy) answers the following question from Mitch Reifel:

Just sort of a legal curiosity. The Starbucks I frequent now has a sign: We can no longer accept bills larger than $20. They are following many gas stations in the area that don't accept bills larger than $20 "after dark".

Is this legal? While I am generally agreed to the view that businesses should be able to set their own practices (and customers can go elsewhere if they don't like them), currency issued by the U.S. is another matter and I thought, legally, Starbucks has to accept a $50 for "all debts public and private". There is also the issue of keeping confidence in a fiat currency, which is in the best interest of the U.S. government.

Kevin Drum (CalPundit) had the following comments:

In any case, Eugene's answer is that if you buy something first and *then* pay for it (as in a "pump then pay" gas station) they have to accept your $50 bill. However, if you have to pay up front, they can simply refuse to do business with you.

That's clever, but I'd like to suggest two other answers that are completely unrelated to any knowledge of the law:

  • Stores have been doing this for a long time, and it's a dead certainty that some loon somewhere has litigated this. So, since many stores continue to have this policy, apparently that person lost.

  • Perhaps the gas station has to *accept* your $50 bill, but they don't have to give you change. It's up to you if you want to do business with a merchant who has this policy.

Any other ideas?

Around 20 years ago, I worked in a number "pump then pay" gas stations (which had convenience stores as well). Every one of these stores/stations had a policy of not accepting bills over $20 to reduce the risk of robbery.

If a person wanted to buy a packaged good from inside the store (e.g. a bag of chips, a candy bar, a bottle of soda) and tried to pay for it with a $50 bill, we would just refuse the sale. Since a person is not the owner of the goods until they pay for them, and the goods are not damaged or consumed, there is no debt. The fact that currency is "legal tender for all debts, public and private" is not relevant, and any business transaction of this nature can be refused by the business owner. The key here is that the good can be put back on the shelf, and the store and customer are in the same condition as before the customer entered the store.

In the case of the customer who pumps gas into their car, then tries to pay for it with a $50 bill, I'm going to have to disagree with Eugene and Kevin. Assuming that the store has a sign, visible from the pumps, stating the policy of not accepting bills larger than $20, the customer has a big problem.

The store does not *have* to accept the $50 bill. The store could accept it, but if the store personnel are following proper cash handling procedures, they would not have enough money in the register to give change. The law can't force a business to provide something it does not have (change), nor does the law force a store to give a customer free gas because the store doesn't want to accept $50 bills.

Paying for the gas but not receiving the full amount of change due (or any), resulting in the customer paying $30-$40 for $5-$15 worth of gas, is usually not acceptable to the customer (they tend to view this as being "ripped off"). This could also open the store up to theft or fraud complaints from customers, because the store is forcing them to pay more than the posted price for a product.

If the store does not accept the $50 bill, and the customer drives off of the premises, this is theft by the customer. Occasionally, customers would threaten to leave without paying if we did not accept the $50 bill, hoping to pressure us into accepting it. We simply warned them that we would call the police, give the police the license plate number of their car, and file a theft complaint.

Sometimes customers would call the police themselves, hoping that by doing so, the police would take their side. The police always told them they better figure out a way to pay for the gas or expect to be arrested for theft.

Typically, what would happen is that the customer would call a friend or family member and have them bring money to pay for the gas, or take them somewhere to get change for their $50 bill. If the customer had to leave to get change, their car was left on the premises to ensure we would not file a theft complaint.

If we were willing to violate store cash control policy, we had a couple of more options available to us:

  1. If the store did a brisk amount of business (at least $100 / hour in sales), we would ask the customer if they were willing to wait 10 to 30 minutes until we had enough cash in the register to give them change. Most customers we made the offer to accepted it; other customers made such assholes of themselves that we wanted them out of the store as soon as possible and we did not offer this option to them.

  2. If it was the middle of the night and business was dead, sometimes we offered the customer the option to pay with the $50 bill, leave their name, address, and drivers license number, then return in the morning when the store manager was present and could provide change from the store safe.

In either case, customers had no right to demand or expect this treatment. We were putting our jobs on the line by violating store policies.

Unofficially, rather than strictly adhering to the "No bills accepted over $20" policy, I accepted any bill as long as I did not have to give the customer more than $20 change. A customer could use a $50 if they were going to spend at least $30 in my store, and they could pay with a $100 bill if they spent at least $80. It didn't make sense to me to turn down large sales like that when there wasn't any additional risk to me or the store (the risk is the same whether a customer pays with five $20 bills or a single $100 bill).

In the case of small items like microwavable foods which have been already opened and heated, fountain drinks sold in cups, etc., if the customer only had a $50 or $100 bill to pay for them, we would just take away their food or drink and write off the cost as a loss. If the customer had consumed a significant portion of the food or drink, we would bar them from returning to the store ("86" them).

Business policies of not taking bills larger than $20 have been around for a long time. I don't understand how people today think they can use $50 or $100 bills anywhere, especially when purchases are for small amounts.

For the definitive legal answer, a link to the U.S. Treasury's web site was posted in CalPundit's comments:

The pertinent portion of law that applies to your question is the Coinage Act of 1965, specifically Section 102. This is now found in section 392 of Title 31 of the United States Code. The law says that: "All coins and currencies of the United States, regardless of when coined or issued, shall be legal-tender for all debts, public and private, public charges, taxes, duties and dues."

This statute means that all United States money as identified above are a valid and legal offer of payment for debts when tendered to a creditor. There is, however, no Federal statute mandating that a private business, a person or an organization must accept currency or coins as for payment for goods and/or services. Private businesses are free to develop their own policies on whether or not to accept cash unless there is a State law which says otherwise. For example, a bus line may prohibit payment of fares in pennies or dollar bills. In addition, movie theaters, convenience stores and gas stations may refuse to accept large denomination currency (usually notes above $20) as a matter of policy.

Bottom line: Even though currency is labeled as "legal tender for all debts, public and private", it is not mandatory that any particular denomination of currency be accepted as payment of a good or service.

Update: Eugene Volokh has posted an update to his earlier post, which includes comments from a lawyer with the Federal Reserve Bank. I agree with the updated post much more than his first post - it tracks more closely with what my personal experience has been.

I'd been thinking about writing a detailed comparison between the features of TypePad and Radio Userland, now that TypePad is available to the public. Two things have kept me from finishing that post: 1) the full comparison keeps ending up as long as a book, and 2) I have not actually used TypePad and do not intend to do so in the near future, which probably isn't fair to either one.

Radio Userland isn't perfect, but there's a few reasons why I'm using it now and will continue to use for the time being:

  1. You can host a Radio Userland blog anywhere you can FTP to.

  2. Radio Userland stores the database of posts on your local machine.

  3. Creating and editing posts occurs locally and does not require an online connection.

Comparing the feature lists of each one can be misleading. For example, both TypePad and Radio Userland both have comments. But Radio Userland's are sub-standard (unacceptably so, in my opinion), as Radio Userland offers no ability to manage them whatsoever. You cannot edit comments, delete comments, ban posters by IP address, etc. All anyone can do is post comments, period. That is why I disabled Radio Userland's comments on my blog and use HaloScan instead.

If anyone has a question about Radio Userland's features, ask it in the comments. I'm going to stay out of the way for now and watch how well people like or don't like TypePad.

I got TrackBack when I wasn't looking

I noticed in my event log (which I don't check as often as I should) that I received a "root update" from Radio Userland. Evidently one of the things I got in the update is TrackBack (with both the ability to send and receive TrackBack pings), because I now have a "TrackBack" option on my Radio Userland Preferences page. I've turned TrackBack on and added it to my blog template - now let's see how well it works over the next couple of weeks.

Blogroll changes

I have made the following changes to my "Favorite Blogs" list of links -

New additions:

MovableBLOG
Mutated Monkeys

Removed:

Tim Blair
Clayton Cramer
Daniel Drezner
LawMeme
Porphyrogenitus
Samizdata
Andrew Sullivan

There's nothing wrong with the blogs I've removed - I just don't have the time and interest in them to faithfully read them every day now. I hope to find and add new blogs in the future to replace those that have been removed.

Josh Chafetz (OxBlog) links to Eve Tushnet's post on some of the strange Google search terms that led people to her site. Josh also lists a couple of search items that are generating hits for OxBlog.

Lately, most of my search engine hits have been in one of two categories: 1) my posts on Movable Type licensing issues and software copyrights, and 2) my posts on the violations and ignorance of California labor law by Rhye's ex-employer. Here's some of the latest search queries that generated hits on my posts about Rhye's ex-employer and California labor law:

california 30 days wages penalty texas
how to write letter to ex-employer requesting copy of my personal records
getting around overtime law
rhye job
laws on paying accrued vacation after termination of employee
can an employer force an employee to work overtime in california?
my ex-employer owes me salary
california labor law lunch six hours
california employment law timecards
terminated employee pay through end of the week california
"labor law" +employee +lunch +california +five
california labor laws employee timesheet change
penalty for not paying overtime california

Interesting to me, but not nearly as funny as Eve's.

Tweaking the blog html code some more

I don't really want to, but I'm going to have to rebuild my new blog theme with tables. The blog site itself looks like it's supposed to, but the web browser interface to editing my blog and configuring Radio Userland (which also uses the blog theme) is screwed up.

The biggest problem is that the editing screens for the blog and various files have a huge text editor box that doesn't resize much (or at all) with the browser window. The browser won't put it side by side with the navigation links column - it ends up down near the bottom of the page (below the bottom of the navigation links column). I was hoping that I could live with it, but after just a few days it's already aggravating me.

Is this bullshit or what?

Here's a case of people in the government who obviously do not have enough to do. From the Toledo Blade (July 31):

Area employers urged to forbid foul language Policies prohibiting foul language and swearing were recommended by leaders of the U.S. Equal Employment Opportunity Commission's district office in Cleveland who spoke to 150 human resources managers, union representatives, and legal aid workers at a seminar in downtown Toledo yesterday.

This is my favorite quote:

"If you can't find words more expressive, you might not have the intellect to work here" is the phrase district director Michael Fetzer said he has used with violators.

Having served in the military, "more expressive" generally means I use multiple cuss words (the longer and more creative the string of them, the better).

Most people consider me to be a smart guy. (One ex-boss of mine even called me "scary-smart".) If I don't have the intellect to work there, my boss most certainly would not. If I'm cussing about something, I've picked the words I'm using deliberately. They say exactly what I mean and no one around me misunderstands what I'm saying.

My opinion of the Cleveland EEOC can be summed up with two words: Fucking morons!

(Hat tip: Dean's World and Overlawyered.com)

Update: David Bernstein at the Volokh Conspiracy also has a post on the Toledo Blade article. Regarding the EEOC's actions, he says: "An employer may certainly choose to ban such language on its own initiative. But for the government to tell them to do so, or to pursue harassment claims based on protected speech, violates the First Amendment."

Did I mention that I *love* the Volokh Conspiracy?

Aggravation by the painters

This morning, Rhye asked me to open up 3 windows in the living room that had been painted shut. The windows are about 10 feet above ground level, so I had to climb up on the first level of scaffolding and use a putty knife to break the paint between the sides of the window sash (the sliding part of the window) and the window frame.

I came back into our room and found out that the painters had painted shut our bedroom window too (for the third time this week). The last couple of times, I was able to pry it open from the inside, but I couldn't get it to budge this time. I went back outside with the putty knife and climbed on the first level of scaffolding in the back of the house to get to our bedroom window and get it unstuck.

While I was there, I noticed that the basement window under our bedroom window was cracked. As I looked at it closer, I saw it had a whole bunch of cracks, and they radiated from an apparent point of impact that lined up real nice with the corner of the wooden plank I was standing on. I had Rhye pass me the digital camera through the now open bedroom window and I snapped a few pictures of the damage. I climbed down off of the scaffolding and took a few more from the other side of the window in the basement walkway. The painters have said nothing about this broken window (as far as I know), so they're in for a little ass chewing on Monday.

We had two clotheslines strung up in the back of the house. The painters had taken them down sometime during their work on the house and Rhye asked me if I could put them back up today so she could wash and hang out some clothes. I got one line up, then couldn't find the hook for the second line. The painters had removed the hook on the side of the house that was holding up the second clothesline and who knows where it is now. (My guess it that it ended up in the trash.) Rhye wasn't too happy about that.

I will be really glad when this mess is over and done with and the painters are gone.

Update 05-Aug-2003: I showed the broken window to the painters yesterday morning. They did bring up a valid point that it was actually the scaffolding guys who broke the window, but since the scaffolding company is a subcontractor of the painters, the painters agreed to take care of it.

What was kind of funny about the whole thing is that Rhye's mother has been trying to get 3 other windows on the upper floors fixed. One was broken by the painters; the other 2 were not. Rhye's mother can't seem to make up her mind who she wants to fix them, so they are still not repaired. The painters had the broken window in the basement repaired by 4 PM.

A couple of days ago, Rhye read my post about the painting contractor ("How not to pick a contractor") and told me what I said about the license wasn't right - that the license wasn't good at all. According to Rhye, the painters had already started working on the house when we checked their license and the decision was made to let them continue.

I couldn't believe I had remembered so badly and blogged it for everyone to see. I really, really hate to be so wrong about something like that. I knew it would soon drive me crazy if I didn't verify what Rhye said was really true.

Unfortunately, Rhye told me this really late at night. I wanted to check the contractor's license again at the state of California's web site but I didn't have the license number handy. The contracts and paperwork were in Rhye's mother's room (and she was asleep). I tried doing searches on the company name of the painting contractor but got nowhere.

Then I remembered I had taken pictures of the front of the house with our digital camera. The painters put up scaffolding and a huge net around the house, and hung a sign on the front of the net. Pulling up the picture up on my computer, I could tell the license number was on it but the number itself was too small and blurry to read. I ventured out to the front of the house and got the number off the sign.

I immediately checked the painting contractor's license. It would seem that Rhye and I were both correct (to a point, anyway). The contractor's license is valid, active, and current. The license is registered to a "sole ownership" business entity and the license claims they are exempt from needing workers compensation insurance because this business entity has no employees.

The painting contractor is not doing business under the owner's name - they are using a company name. This is what the state has to say about contractors using a DBA ("doing business as"):

You can use a DBA (doing business as) name in addition to or in place of your personal name. You must register your DBA within 90 days of making a change. You cannot use more than one fictitious name. Also, contractors must use the business name shown on their license. The name on the license can be either the license holder's personal name or a fictitious business name as defined in Business and Professions Code Section 17900. You are encouraged to provide the business name used on your license and your license number to customers. That way, your customers can easily verify the business name as listed with CSLB (Contractor's State License Board).

I did find out that the painting company has a "fictitious business name" on file with the San Francisco county clerk's office (which I found by searching for it here), but the company name shows up nowhere on their state contractor's license.

As far as the workers compensation insurance goes, the license is just wrong. The guys painting our house are obviously employees. The painting contract states that the company has workers compensation insurance for its employees, but I don't know if anyone bothered to verify that claim.

It looks to me like the painting contractor's license just needs to be updated, but it should have been scrutinized closely and questions asked about it *before* signing a contract with them.

Update 05-Aug-2003: I printed a copy of the painting company's state contractor's license info, their fictitious business name filing with the city of San Francisco, and a copy of an FAQ from the state showing that DBA business names are supposed to be registered with the state within 90 days. I showed these to the owner of the painting company yesterday. He didn't think there was a problem with the company name not being on the license - he believes that the city fictitious business name filing is sufficient. I do not agree, but it was not something I was going to argue about with him.

I also asked him about the worker's compensation exemption listed on their license. He told me, "Yeah, we hire some new guys last year." I told him that he should notify the state so that the workers compensation policy is listed on their contractor's license, and while he was at it, he could also update the license with the business name as well.

I don't think he's going to do anything about it. I told him that basically he just needs to update the information on his state contractor's license, and I thought he'd like to know so he could avoid problems down the road with future customers. I got the impression he thought I was being a nuisance. Whatever.

New theme for my blog

I liked the old theme I was using before today (SoundWaves: blue), but there was one thing that really bugged me. The old theme's layout had the links down the left, the main blog in the middle, and the calendar sat in a column all by itself to the right. All of the space under the calendar was wasted. I didn't think that moving the calendar to the left would look very good, so I decided to change to the two column theme I'm using now.

This theme (Moveable Radio: blue) heavily uses CSS (styles) to create its look. I had to do some fairly extensive customizing of the theme (especially the CSS) to make it work the way I wanted it to. I think there's a few things I may have not done correctly in the CSS, but it was the only way I could get it to render correctly in IE6.

If you don't think my blog is rendering correctly for you, leave a comment and I'll see what I can do to fix it. I'm still learning CSS, so if you have some sample code to fix the problem you are seeing, that would help a lot. I do not have any other browsers installed, so I cannot test any fixes myself other than in IE6. If the CSS ends up being unworkable, I'll convert the blog to a table-based layout with the same look. Hopefully it won't come to that.

Beyond that, I'd welcome any suggestions and comments on the new theme. No guarantees that I'll use any of them, but I want my blog to present well and be easy to read.