Thursday, June 28, 2007

sideblog_comments.diff

Here's how you add comments to the Sideblog plugin for Wordpress by Kates Gasis. This diff will only work for Version 3.8.

145c145
<  $sideblog_contents = $wpdb->get_results("SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->posts.post_content, $wpdb->posts.post_date FROM $wpdb->posts, $wpdb->post2cat WHERE $wpdb->posts.ID = $wpdb->post2cat.post_id AND $wpdb->post2cat.category_id = $asidecategory AND $wpdb->posts.post_status ='publish' AND $wpdb->posts.post_type = 'post' AND $wpdb->posts.post_password ='' AND $wpdb->posts.post_date < '" . $now . "' ORDER BY $wpdb->posts.post_date DESC LIMIT " . $limit);
---
>  $sideblog_contents = $wpdb->get_results("SELECT $wpdb->posts.ID, $wpdb->posts.post_title, $wpdb->posts.post_content, $wpdb->posts.post_date, $wpdb->posts.comment_count FROM $wpdb->posts, $wpdb->post2cat WHERE $wpdb->posts.ID = $wpdb->post2cat.post_id AND $wpdb->post2cat.category_id = $asidecategory AND $wpdb->posts.post_status ='publish' AND $wpdb->posts.post_type = 'post' AND $wpdb->posts.post_password ='' AND $wpdb->posts.post_date < '" . $now . "' ORDER BY $wpdb->posts.post_date DESC LIMIT " . $limit);
153a154
>  $patterns[] = "%comments%";
173c174,175
<    $replacements[] = $excerpt2;
---
>    //$replacements[] = $excerpt2;
>    $replacements[] = $sideblog_content->comment_count . " comment" . ($sideblog_content->comment_count == 1 ? null : "s");

Tuesday, June 19, 2007

widont.rb

I don't mean to knock Shaun Inman and his wordpress plugin Widon't. It's a very useful plugin that eliminates typographical widows by replacing the last space with a non-breaking space. He says the regular expression is '|([^s])s+([^s]+)s*$|'. This is of course, completely false; something was lost in translation here.

First, the pipe characters are weird but I think PHP accepts them. I've always used the forward slash to denote a regular expression. Second, the s is meant to be \s the notation for whitespace of any sort.

The actual plugin works fine. I think Shaun's just made a typo on his blog.

Here's a similar piece of code in Ruby:

"Lorem Ipsum Dalor Est".gsub(/([^\s])\s+([^\s]+)$/, '\1&nbsp;\2')
# => "Lorem Ipsum Dalor&nbsp;Est"

I love how Ruby (and Javascript, if I recall correctly) gives regular expressions special status like how most modern languages treat strings. In web development and command line scripting, strings are the only real input/output you work with and regular expressions are akin to the hand of God.

Sunday, June 17, 2007

randomhover.js

I thought, wouldn't it be a great idea to have the background of a link change to a different color every time you over hover it? That'd look sweet.

// NOTE: Load prototype.js first (prototypejs.org)
// NOTE: Load the HTML first, otherwise we don't know what we're dealing with

// function to set random background colors
var sidebarLinks = function(e) {
  var bg = "transparent"; // default background

  if (e.type == "mouseover" || e.type == "focus") {
    var colors = new Array("#ff6", "#6cf", "#f9f"); // list of colors we like
    
    // get random number and use % to make sure i doesn't go out of bounds
    var i = Math.floor(Math.random() * colors.length) % colors.length;
  
    bg = colors[Math.floor(Math.random() * colors.length)];
  }

  // get the link that triggered the event
  var element = Event.element(e);

  // set the background on that link
  element.style["background"] = bg;
}

var sidebars = $$("#sidebar a"); // all the links in the sidebar

for (var i = 0; i < sidebars.length; ++i) {
  // call "sidebarLinks" whenever I mouseover or mouseout a link
  Event.observe(sidebars[i], "mouseover", sidebarLinks);
  Event.observe(sidebars[i], "mouseout", sidebarLinks);

  // these are the keyboard-specific events for accessibility reasons
  Event.observe(sidebars[i], "focus", sidebarLinks);
  Event.observe(sidebars[i], "blur", sidebarLinks);
}

This code can actually be a lot shorter if you inline a few things. But I expanded it out to help the reading process and because my syntax highlighter has a few parsing bugs. Grr.

Wednesday, May 30, 2007

alternator.php

/**
 * Guys, seriously. It is pretty common to want to do something where
 * you do something to every 2nd row, don't use a lengthy if else block.
 *
 * Just have one bool, $foo, and set it to !$foo on every iteration.
 * Simple!
 */
$i = 0;
$alt = true;

echo "<ul>";
while ($i < count($list))
{
    echo "<li";
    echo $alt ? " class=\"alt\"" : null;
    echo ">";

    echo htmlentities($list[$i]);

    echo "</li>";

    ++$i;

    $alt = !$alt; // aha! sorcery!
    /* if ($alt)
    {
        $alt = false;
    }
    else
    {
        $alt = true;
    } */
}
echo "</ul>";

Monday, May 28, 2007

An exercise in reading HTML specifications

Did you know that web pages are chunked? Imagine the page is like a big piece of paper. When you ask for the piece of paper, the server rips it up into little pieces and hands it out to people. The pieces are passed to random people until you collect all the pieces. Then you have to get some glue and stick it all together before you can read it.

Internet, that is just idiotic. You are wasting everyone's time with all this ripping up and sticking together. Time that could be spent communicating thoughtful ideas over some massive global network.

BUT THERE'S A SOLUTION. You make your webpage so small, that it only needs to take up one piece of paper. It's so small that noone will bother to rip it up, so when it reaches your audience, they don't need to glue everything back together. Imagine all the energy we'd save that way.

So here are some templates for you to build from:

html4-tiny.html:

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

xhtml-tiny.html:

<!DOCTYPE html 
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

html5-tiny.html: (as according to the HTML5 specification on 2007-05-28)

<!doctype html>

The truth is, I don't know if these could be smaller or are even valid. First of all, the HTML validator fails me because it's a pretty generic validator. You see, the W3C provides DTDs for HTML 4.01 and XHTML 1.0 but DTDs alone cannot verify 100% conformance to the spec. This means that things are special-cased and I'm doubtful they've special-cased some idiot wanting to write the smallest possible HTML document.

The HTML5 spec is easier to read because it is designed with audience in mind. But at the end of the day, it's still a spec. Spec aren't meant to be read by humans. They're meant to be read by pedantic assholes (who yell at people trying to interpret the spec) and angelic humanitarians (who interpret specs and translate for the rest of us).

toast.exe


You are in your childhood kitchen but its not your childhood kitchen. You feel
light-headed. There is a piece of toast sitting in the toaster.

> look toast

The toast is burnt just the way you like it.

> get toast

Taken.

> give toast to mr james

You give the toast to Mr. James, your first boss when you took a job over the
holidays in data entry. He greedily eats up the toast and gives you his shirt
that is covered in crumbs.

> look

You are in your childhood kitchen but its not your childhood kitchen. You feel
light-headed. There is toaster. Your old boss, Mr. James is standing topless
in the corner of the room.

> i

You are carrying:
A shirt covered in crumbs.

> save

Ok.

> quit

Your score is 5 (total of 50 points).
This gives you the rank of Beginner.
Do you wish to leave the game? (Y is affirmative):

> y

Saturday, May 26, 2007

StateMachine.cs

State machines are a very very handy design pattern. I am easily one of the top 3 programmers in the world and I didn't learn state machines until my final year of university. Just goes to show that we all need to keep learning. (Ok I'm kidding about being in the top 3, lighten up and go meet a nice girl instead of drinking so much Haterade.)

The first class is the Game class that is the entry point and stores environment variables that are shared between all states (e.g. player name, high score, statistics, etc.). There is very little going in inside Game.

class Game
{
    /**
     * Entry point for the program. Create a new Game object and start running
     */
    public static void Main()
    {
        Game game = new Game();
        game.Activate();
    }
    
    private bool exitGame;
    private State state; // current state of the game
    public Game()
    {
        exitGame = false;
        state = MainMenu.Instance;
        // do other "new game" stuff here
    }
    public void Activate()
    {
        // keeping running the game until someone tells us to exit
        while (!exitGame)
        {
            state.Activate(this);
        }
    }
    public State GameState
    {
        set
        {
            state = value;
        }
    }
    public bool ExitGame
    {
        set
        {
            exitGame = value;
        }
    }
}

The MainMenu class is quite lively.

It's got a private constructor to make sure that there's only one copy of the class that is ever instantiated. You don't need to create these states more than once. As a bonus, you could wait until MainMenu#Instance is called before creating the state. I don't know if the compiler would already optimize for this though, so better run some benchmarks and figure it out before you add more lines to your already unmaintainable codebase.

MainMenu.Activate(...) is where all the action is going on. It basically asks for the user's input and then changes the state of the game accordingly. This is the fun of a State pattern. You avoid wasting your time with really verbose switch and else if statements and instead abstract it away so you deal with state transitions. It maps better to the state diagram that you drew (tell me you drew one).

class MainMenu : State
{
    private static State mainMenu = new MainMenu();
    public static State Instance
    {
        get
        {
            return mainMenu;
        }
    }
    
    private MainMenu() { }
    
    public override void Activate(Game game)
    {
        Console.WriteLine("Welcome to the game!");
        Console.WriteLine("1: Write a novel");
        Console.WriteLine("2: Read a novel");
        Console.WriteLine("3: Plagiarize a novel");
        Console.WriteLine("4: Criticize another novel writer");
        Console.WriteLine("5: Exit to DOS");
        
        // Get keyboard input from the user
        int choice = getChoice(5);
        
        switch (choice)
        {
            case 1:
                ChangeState(game, WriteNovel.Instance);
                break;
            case 2:
                ChangeState(game, ReadNovel.Instance);
                break;
            case 3:
                ChangeState(game, WriteNovel.Instance);
                break;
            case 4:
                ChangeState(game, CriticizeWriter.Instance);
                break;
            case 5:
                ChangeState(game, ExitGame.Instance);
                break;
        }
    }
    
    private int getChoice(int max)
    {
        // Implement this one on your own!
    }
}

Did you notice that MainMenu inherits from something called State? Go back and read the code, dummy.

This is an abstract class that all states inherit from. Every class that inherits from this must have a Activate(Game game) method and that's about it. You could also add more things here that are common to all the states.

Umm... I've forgotten what the virtual keyword does. I think it means the method is late-binding so in the sub-classes, you could re-define this function and it would be polymorphic so you could have a sub-class of State that does some clean-up before transitioning away.

abstract class State
{
    /**
     * Activate() gets the state to do whatever it needs to do.
     * When a state has finished running, it calls ChangeState().
     *
     * The Game object is just where important environment data is stored so the
     * different states have can work on this data.
     */
    public abstract void Activate(Game game);
    
    protected virtual void ChangeState(Game game, State state)
    {
        game.GameState = state;
    }   
}

Well that just about covers it! Please please please think about implementing a State before you starting writing a huge switch statement.