Categories
Technology

Comments

Recovered from the Wayback Machine.

As you can see, I’ve added in functionality to display the most recent comments regardless of post. I’ve found that I do get comments on older posts, and they’re ‘lost’ because no one knows they occur. Now, every comment has its moment in the sun, so to speak.

Speaking of comments, there have been several attached to the Dripping with Irony post. Some agreement, more disagreement, including a comment from Tim O’Reilly, and I appreciate Tim taking the time to stop by and write a spell.

Discussion related to the post is well and good, and my appreciations are also extended to those others who have commented. However, I have a feeling that some of the people are using me and my posting as a way to hit and jab at each other, indirectly, rather than because they were interested in anything I have to say. Just a feeling, a hunch I have. Silly, eh?

However, if per chance this Is true, then all I can say is that these same individuals must not have learned the lesson that when you play with fire, you get burned. Same could be said of playing with firey birds.

Continuing this post’s topic, I want to talk about anonymous comments. Lately I’ve been getting some nasty anonymous comments, including some of a personal nature unrelated to the postings. There is a difference between posting a comment anonymously because you’re uncomfortable using your name — because of work or other valid considerations — and not using your name because you want to say vicious things without reprecussion.

I don’t want to sound too much like Warf in Star Trek, but people who hide behind the cloak of anonymity in order to take petty, mean shots at others have no honor. Hint: the worst thing I will ever say to another is that they have no honor*.

Starting today, you post a nasty, petty, vicious, and personal comment — about me or anyone else — without attaching your name or some other known psuedonym or your weblog or true email address, I’m deleting it. As simple as that. Don’t like my new rules? Take it up with management. I tire of wasting my time, and my readers time, with Anonymous Coward.

* I actually did this myself, once, by accident. With Happy Tutor from Wealth Bondage, no less. I wrote what I thought was a funny comment, under a joke psuedonym. However, when I checked later, I realized the comment was incredibly mean. I must have been exhausted when I wrote it. I do know that I felt horrid about it afterwards. Personally, I wish that Happy had deleted it.

This is late, but sorry Happy.

Categories
Technology

Comment How-To

Recovered from the Wayback Machine.

In comments to my last posting Jonathon, asked the following about my new comment modification:

Is that standard in (later versions of) MT? Or a custom-coded Burningbird special?

Answer: a bit of both.

The code is based on templates and an example that Ben and Mena provided, but I customized. So I thought I would provide a how-to if others are interested in incorporating at their weblogs.

First, I added permalinks for my comments, so that clicking on the specific comment takes the person directly to the comment. I changed the MT template code for comments within the individual entry archive template to the following (modifications are in bold text):

<a name=”comment<$MTCommentID>”></a>
<$MTCommentBody$>
<span class=”comments-post”>Posted by:
<$MTCommentAuthorLink spam_protect=”1″$> on
<a href=”<$MTEntryLink$>#comment<$MTCommentID$>”>
<$MTCommentDate$></a>
</span>

Once permalinks have been added, I then added the comment code to the main template page. This is a modification of example code the Trotts have provided:

Update: Code has been altered to remove hard coded URL per note from Sam Kington — thanks Sam!

<MTComments lastn=”10″ sort_order=”descend”>
<a href=”<$MTBlogArchiveURL$>/<$MTCommentEntryID pad=”1″$>.htm#comment<$MTCommentID$>”>
<$MTCommentAuthor$></a> on <MTCommentEntry>
<$MTEntryTitle$>
</MTCommentEntry><br />
</MTComments>

From top to bottom: The outer comment block is necessary for using the comment tags. In addition, it also provides instruction to list the last ten comments. The next line then forms the link, which is based on the static archive location appended with the entry id and the comment entry id, both based on MT tags. The next lines add the comment author and title, again both from MT tags.

I’m using MT 2.51, but this should work with any version of MT that supports all of the tags I’ve outlined.

Holler if you have any questions.

Update (12/29/02)

Jonathon Delacour, Mr. Markup to us angle-bracket challenged, pointed out that the name anchor reference is deprecated for XHTML. Instead, the preference is to use id. When I update the weblog to XHTML, I’ll be using the id attribute instead, which is gonna bust heck out of any remaining old browser here abouts.

Anyway the change would be to pull the anchor tag (the <a name=…>) and replace with:

 

<div class=”comments-body” id=”comment<$MTCommentID>”>

 

Thanks to Jonathon for heads up and correction.

Categories
Diversity Technology

We are out there

Recovered from the Wayback Machine.

Clay Shirky left a gracious comment attached to the Dripping with Irony post. I’m glad because this helped the thread reach a positive note, rather than continue into a downward spiral based on the old “she said/he said” pattern (of which I, unfortunately, contributed my share).

When I replied to Clay, I repeated something I told Tim O’Reilly in response to a statement that Tim made in his comment:

Not to mention the dripping irony that, with three women out of twenty-odd participants, this group was more sexually diverse than the typical computer geek gathering…

I told Tim and Clay: We are out there.

The diversification they want, we all want, we all need is out there. There are women, and Blacks, and Latinos, and accessibility challenged folks and other non-represented people out there. But we can’t continue following the same old patterns of connectivity and communication and expect to see something other than the same old faces, time and again.

If we are discussing social software, then we have to first understand the society we’re trying to enable with this software. And to do this, we have to understand the limitations and challenges each of us, as individuals and as a members of one or more “categories”, is facing.

Clay mentioned that he did try to ensure more even representation of gender at the meeting, and I’m sure he did. As he commented, some of the women invited were academics and most likely couldn’t attend because of school commitments. And two women cancelled at the last minute.

However, rather than not have this representation, couldn’t Clay have used technology to enable these women’s participation without their physical attendance? Most people now have access to conference call capability, and most have access to video cameras for their computers. In fact, the software application Groove enables this type of participation, and the creator of Groove, Ray Ozzie, was there — could this not have been used? What a wonderful opportunity this would have been.

With this type of already available technology, these women could have participated and every one would have been richer.

And let’s take a moment to consider the reasons why the women couldn’t participate. Was it just school commitments? Or was it other constraints, such as family responsibilities or finances?

Speaking only of the United States, over 31% of families are now single parent, and only 5% of these families are headed up by men. When you’re a single-parent, especially if you don’t have extended family around you, it becomes virtually impossible at times to physically attend conferences. Or to even attend meetings of user groups at night.

Additionally, money could be more of an issue to both women and minorities. Statistically, women do make less than men, and are not as prevalent in the positions of technology leadership. I believe the same could also be said of many minorities. Both of these circumstances can make it more difficult for a person to buy a ticket to come to a meeting or conference; or to pay for the priviledge of attending the conference. Or even be in a position whereby the company pays the costs.

If we’re discussing social software, isn’t the first place the discussion should start is the constraints preventing potential audience members from becoming full participants? By doing so, we might begin to understand that what we don’t necessarily need is ways of getting the under-represented to meetings and conferences and training; but ways of getting meetings and conferences and training to the under-represented. This outreach, to me, is what social software is all about. It isn’t about sharing music files in such a way that one isn’t busted by Hollywood.

I don’t want to keep picking on Clay and his social software gathering, because I happen to know that he is a decent person who is trying very hard to open closed doors, and give voice to those who are quiet.

However, I will continue speaking out when I see these opportunities.

Categories
Technology

Save Dr. Dotty from the Quicksand

Copy from the Wayback Machine Archive.

Dr. Dotty is exploring in the jungle and accidently walks into quicksand. The object of the game is, of course, to save Dr. Dotty.

The Save Dr. Dotty from the Quicksand games are a variation of the old paper game “Hangmans’s Bluff”. The object of the game is to fill in all the missing letters from one or more words within a phrase and save Dr. Dotty from DOOM.

Playing the Game

-The playing board for each of the Quicksand games is 800 x 600 pixels.
-Each game has an opening animation, and an ending animation if you correctly find all the missing letters.
-Pressing the “ENTER” key after the opening animation stops will start the game.
-Type a letter into your keyboard and every place that the letter exists gets filled in.
-If you type in an incorrect letter, poor Dr. Dotty sinks a little further into the quicksand.
-Close the playing window at any time by clicking the space bar.

The Dr. Dotty games work with Navigator 4.x, Netscape 6.x, IE 4.x, IE 5.x, and IE 6.x, and Mozilla.

 

  • Game 1 If you know about hurricanes, you know the answer to the question in this game. However, you can find the answer in the How the Game Works section, below.
  • Game 2 If you know about minerals and mineral identifications, you know the answer to this game. However, you can find the answer in the How the Game Works section, below.

 

How the Game Works

The Dr. Dotty games use DHTML for all interactive effects. This includes the use of CSS to position elements as well as alter their presentation; and JavaScript to perform all actions, interactive or otherwise.

The elements of the game page are positioned using CSS2 absolute positioning. Doing this I can control the layout of the page at any time. Using absolute positioning also exposes all of the elements to script access once the page is loaded for a browser such as Navigator 4.x. All elements are exposed as part of a Document Object Model (DOM), and hence exposed to interactive scripting access for the IE 4.x and IE 5.x, Mozilla, and the upcoming Navigator 5.x browsers, but to ensure cross-browser and cross- version compatibility, I code to Navigator 4.x, which requires that the elements be positioned absolutely:

   <DIV id="dotty1" style="position:absolute; left: 20px; top: 20px">
   ...
   </DIV>

To ensure that the games work with both IE, Mozilla, and Netscape I used the Burning Bird X-Objects to hide most DHTML implementation techniques. Because of this, when I want to move an object to an absolute position of 100 pixels from the left, I can use the method exposed on the cross-browser objects:

   theobjs["dotty1"].objSetLeft(100);

I’ve also created a set of higher-level animation objects that use the cross-browser scripting objects and JavaScript timers to manage all animation effects. These Animation objects, are basically arrays of animations, with each step in the animation synchronized with matching steps in the other associated animations.

So, to show an element that both moves and clips, I create a new animation sequence (co-ordinated animations that are all performed sequentially in the order they are added to the sequence), and then attach one animation object to the sequence. The animation object is defined with a set number of animation steps, each played out after a specified number of microseconds. After the animation object is created, I then crate new Animator objects, one for the clipping animation and one for the move animation:

   var seq = new animatorSequence();
	
   anim = seq.newAnimator(10,100);
   anim.addAnimator(theobjs["dotty4"],"M",180,160);
   anim.addAnimator(theobjs["dotty4"],"C",0,0,330,200);

When the animation sequence is played, each successive steps of the animations contained in the sequence is synchronized and played:

    seq.play();

So, when Dr. Dotty moves across the screen in the opening sequence, one Animation Sequence is created for the entire opening animation; several Animations are created to handle such things as moving Dr. Dotty, showing the different word bubbles and words that he says, and even changing Dr. Dotty’s expression. Different types of Animators objects are created for each animation effect, and the Animators are added to Animation objects to provide for the synchronization for multiple-animator effects.

Want to see the code creating the animation sequence, animations, and animators for the opening animation? Well, it’s a bit long, but here you go:

function setup_start(){
   seq = new animatorSequence();

   // add animation objects to sequence
   // this animation plays for 200 microsecond, with each
   // step in the animation sequence timed at 20 microseconds --
   // 10 animation steps in all
   var anim = seq.newAnimator(20,200);

   // add animators
   anim.addAnimator(theobjs["dotty1"],"M",180,160);
   anim.addAnimator(theobjs["bubble1"],"M",180,400);
   anim.addAnimator(theobjs["bubble1"],"Z",4);
   anim.addAnimator(theobjs["words1"],"M",230,460);
   anim.addAnimator(theobjs["words1"],"Z",5);

   // second animation, this time one step at 100 microseconds 
   anim = seq.newAnimator(1, 100);
   anim.addAnimator(theobjs["words1"],"H");

   // third animation, 1 step, 1500 ms
   anim = seq.newAnimator(1, 1500);
   anim.addAnimator(theobjs["dotty2"],"S");
   anim.addAnimator(theobjs["words2"],"S");
   anim.addAnimator(theobjs["words2"],"Z",5);

   // fourth animation, 1 step 200 ms
   anim = seq.newAnimator(1, 300);
   anim.addAnimator(theobjs["dotty3"],"S");
   anim.addAnimator(theobjs["dotty2"],"H");
   anim.addAnimator(theobjs["words2"],"H");
   anim.addAnimator(theobjs["words3"],"S");

   // fifth animation, 1 step 2000 ms
   anim = seq.newAnimator(1, 2000);
   anim.addAnimator(theobjs["dotty1"],"H");
   anim.addAnimator(theobjs["words3"],"S");
   anim.addAnimator(theobjs["words3"],"Z",5);

   // sixth animation, 1 step, 100 ms
   anim = seq.newAnimator(1, 100);
   anim.addAnimator(theobjs["words3"],"H");
   anim.addAnimator(theobjs["dotty3"],"H");
   anim.addAnimator(theobjs["dotty4"],"S");
   anim.addAnimator(theobjs["words4"],"Z",5);

   // seventh animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words4"],"S");

   // eighth animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words4"],"H");
   anim.addAnimator(theobjs["words4"],"Z",5);

   // ninth animation, 1 step, 3000 ms
   anim = seq.newAnimator(1, 3000);
   anim.addAnimator(theobjs["words4"],"H");
   anim.addAnimator(theobjs["words5"],"S");
   anim.addAnimator(theobjs["words5"],"Z",5);

   // tenth animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words5"],"H");

   // eleventh animation, 1 step, 3000 ms
   anim = seq.newAnimator(1, 3000);
   anim.addAnimator(theobjs["bubble1"],"H");
   anim.addAnimator(theobjs["dotty5"],"S");
   anim.addAnimator(theobjs["bubble2"],"S");
   anim.addAnimator(theobjs["bubble2"],"Z",4);
   anim.addAnimator(theobjs["words6"],"S");
   anim.addAnimator(theobjs["words6"],"Z",5);

   // twelth animation, 1 step, 1000 ms
   anim = seq.newAnimator(1, 1000);
   anim.addAnimator(theobjs["words6"],"H");

   // thirteenth animation, 10 steps, 100ms (10 ms each) 
   anim = seq.newAnimator(10, 100);
   anim.addAnimator(theobjs["words7"],"S");
   anim.addAnimator(theobjs["title"], "M",200,500);

    // fourteenth animation, 10 steps, 100 ms
    anim = seq.newAnimator(10, 100);
    anim.addAnimator(theobjs["dotty5"],"H");
    anim.addAnimator(theobjs["words7"],"H");
    anim.addAnimator(theobjs["words8"],"S");
    anim.addAnimator(theobjs["words8"],"Z",5);
    anim.addAnimator(theobjs["title"], "M",300,500);
	

     // play all 14 animations, in order 
     // as they are defined in sequence array
     seq.play();
}

At the very end of the function that creates the opening animation sequence, the sequence is played.

One last aspect of the Dr. Dotty games is the interactive portion. This is handled by capturing the keypress event for the Web page, and passing the event to a function:

// handle keyboard events
if (navigator.appName != "Microsoft Internet Explorer") 
   document.captureEvents(Event.KEYDOWN);

document.onkeydown=keypress;

In the function, the keycode for the keypress event is accessed and compared to the letters for the answer: if a match is found, the letter is “filled in” in the answer (using DHTML to replace the existing underscore character with the letter); if a match is not found, Dr. Dotty is lowered into the quicksand further (using clipping to lower the good doctor, and DHTML “hide and show” to change Dr. Dotty’s message and expression).

Download the game source code from the link to the right and make your own version of the game. Have fun!

 

Categories
Technology

All you need is PHP

Recovered from the Wayback Machine.

Sam Ruby says life changed for him, for the better, when he discovered PHP:

Later this month I turn 41. For me, the last three felt like ten. In a good way.

What changed it all for me? PHP

I’m writing the first release of Post Content in PHP, so I’m hoping that the magic works for me, too. However, I’m also using Perl — will this block the good stuff?