David Simon on Debate and Journalism

It’s why I used to love a healthy newsroom, which I have described as a magical place where everyone disagrees with everything all of the time.  Arguments make the work better; when people stop arguing, or at least arguing intelligently, absent the usual half-assed, rhetorical cheating, the work invariably suffers.

(Source: davidsimon.com)

Scantily Clad Women are for the Bedroom, not the Showroom Floor.

I love women. I love scantily clad women. I think the majority of men, and of course some women, would agree with me. Sexual attraction is inherently part of the human experience and part of the instinctual core that makes up who we are. The same goes for women with men.

However, this is not okay.

*This* is a glimpse inside Ad:Tech San Francisco. Maybe not all of Ad:Tech. Maybe not even most of Ad:Tech. But it’s certainly a representation of how at least a few people decided to capture it. And this is not directed toward the photographers, at least one of whom I am personally acquainted with. And certainly not directed toward the women who are captured in the photographs or women who have embraced their own sexuality and their own representation of it.

It’s not directed toward sex in art, sex in social commentary, sex in music, sex in film, or choice of sexual exhibitionism. This is entirely about the objectifying of women for comercial gain.

Sex sells, right? It’s been used for decades to touch on an instinctual desire, particularly in men, that ties desire to a commercial action, such as buying. This is why the porn industry is so huge. This is why men will pour hundreds, if not thousands of dollars, into the sex industry and the industry thrives.

I am not naive, nor am I a curmudgeon. As a man, I readily admit to, at least occasionally, “Thinking with my penis”…

But this is an industry that is loosely defined as “tech” and tech is largely dominated by men. We have an image problem. On one hand, the industry as a whole has spoken out vocally about the representation of women in presentations, at conferences, on speaker lineups, etc. We have vilified organizations that put on events not proportionally represented by women and yet… somehow it’s okay, with a wink and a nod, to put women on display on show room floors for the purpose of selling a product. That’s, somehow, okay… even if no one will say that. After all, these “booth babes” are getting paid and this is their job. Sure, gimme a free tee-shirt or a brand-labeled rubber band ball. Cool.

I love scantly clad women as much as the next guy. I’d rather she be in my bedroom or sipping a bourbon and ginger at a bar or show, than pushing some new mobile ad network on a showroom floor so the married ad executive from Burbank can get his nards off. To me, this is a practice that really needs to end.

Note: Despite my desire to use a sexy image for this post, I’ve chosen not to for obvious reasons.

The Anatomy of a Successful April Fools Joke (Or Don’t Any of You do Fact Checking?)

Photo by Sean MacEntee

Photo by Sean MacEntee

With April Fools Day on Sunday, I started thinking about how to successfully prank everyone. There’s only been one successful prank I’ve participated in during my lifetime and it eventually ended up on Mashable – because, you know, Mashable is such a beacon of great fact-checking journalism. Zing! ;)

Realizing that I had two awesome calendar quirks upon me – that AFD was this coming Sunday, a weekend, and that the end of the government Q2 was today… I had plausible cover for a real awesome prank.

So I texted my good friend Amanda at the U.S. Department of Agriculture and floated an idea past her. I needed an alibi and some cover in the event I started to get questioned. My idea is that I was moving back to DC to take a senior level role at a federal agency. Given that she has such a role at USDA, the ruse went from there.

A made up position (but one that sounded totally reasonable to the naked eye) – Deputy Director of Online Operations – was concieved. Since it was the end of Q2, I had to make the decision by close of business today. My cover would include “budget cuts” and “workforce consolidation” as reasons for a new position.

The next step in purpotrating this lie was to ensure all the closest people in my life bought the lie. I could clue them in to a lie, but too many cooks in the kitchen could spoil the whole thing so I wanted the closest people buying it.

So I told my roommate and spun a story she believed. Then I told my friend Mike Neumann who bought in hook, line and sinker. I did let my girlfriend in on the secret since she would be likely to panic.

I reinforced the story again this morning with my roommate, referencing a conference call and a “letter of intent” from USDA. I don’t think the USDA even issues Letters of Intent and it’s the Office of Personel Management who actually does hiring on behalf of agencies and suggesting I had to make this decision today and that “it was a hard one” and “I really don’t want to leave Austin”. I knew when she started consoling my dog that she was thoroughly convinced. Good job, Aaron. Phase 1 complete.

Having suitably hooked my friends, it was time to start rumor dripping. IT started with an innocuos status update on Facebook (since, you know, that’s for family and friends and not the world): “Well, Austin… it’s been a fun 2 years. I’ll see you at SXSW, I guess”. In comments, I (intentionally) float DC as my destination but played coy on details citing “a gag order”. Enough information to be compelling, but also enough to maintain the cover of my story. Everyone buys in. Phase 2, done!

Awhile later I make my “official announcement“. This part of the prank is meant to provide even more plausible information, laced with real life fact. Every good lie has an element of truth. I describe the role in words that are believable… that it’s mostly technical, that it involves WordPress, that in Austin I’ve taken up more healthy eating habits – something that plays directly into the mission of USDA.

Since this was my “announcement”, I shared it back on Facebook as its own status update, as well as updated the original “float post” so that those who already saw my update would see the new update. I also tweeted it out to my 9500+ Twitter followers.

Everyone bites. No one questions anything. No one even thinks about AFD. Phase 3 complete.

The key to this joke was timing. To be plausible, I had to do it today. The government doesn’t work on the weekend and if I waited until Monday… my opportunity would be squandered because everyone would have their AFD defenses up. But 2 days before… no one saw it coming.

Additionally, it’s a prank. I don’t want this being on the internet forever and a day. I ensured the proper meta tags were added to my post so Google won’t index it and no one will be confused later down the road. Ha! But then, no one looks at source code. ;)

I’m sorry I’m not coming back to DC. Actually, I’m not. But y’all shouldn’t believe everything you read on the internet. :)

There is a Season, Turn, Turn, Turn: Back to DC.

Back when I moved to Austin in 2010, I was thrilled to be leaving the rat race that was DC. I was looking forward to a place when people did not watch presidential speeches to joint sessions of Congress in bars as if they were the Super Bowl and instead sat on patios with their friends eating chips and queso and drinking local craft beers while listening to live music.

I looked forward to a cheaper and easier way of living where summers were hot but not nearly as unpleasant and winters did not bring 50″ of snow in just a few days. It was a new life with new opportunities and new experiences far away from the northeast where I had lived almost all of my life.

I did not expect it would come to an end short of 2 years after I made that bold move. But it’s coming to an end, barring some unforeseen hitch.

I’m moving back to DC in the middle of July. Beginning mid-may, I will become a Fed. You heard that right… a Fed. I’m pleased to have accepted a position within Department of Agriculture to become Deputy Director of Online Operations – a far more senior position than I could have imagined since my only Federal job experience was on the corporate contracting side with Lockheed Martin, Northrop Grumman and CSC. However, I am uniquely qualified for this role.

The role is a new one that lies somewhere between an operations style role surrounding technical execution and communications where I’ll have my hand in some of the online community aspect. Mostly, it’s a technical role though. And WordPress is heavily at play here.

In a way, this is a dream job. To be able to use my WordPress experience to help direct a portion of public policy related to critical infrastructure around some of America’s greatest domestic assets, enabling analysts to develop partnerships with state and local school food programs, among other things… it’s incredibly sobering.

So while I don’t start in DC until July 16, I’ll be beginning my role on May 14 at the USDA office here in Austin.

Regrettably, I have to move, but I do so with a tremendous amount of perspective and new experiences from Austin to live with. One thing I take away from Austin is the importance of locally grown vegetables and grass-fed beef… this perspective will help make this role even more effective.

Thank you to all my friends here in Austin. I’ll be back. I love this place too much not to come back.

TUTORIAL: Using WordPress’ Ajax API

WordPress has tons of APIs to do tons of things. It really does. One of the cool ones that I’ve been using a lot lately, has been around for a bit. It’s the Ajax API. Sure, you could write your own Ajaxy thing but why do that when WordPress lets you do it all very simply.

This tutorial will show you how to replicate the functionality that is presented in the “Like” button at Facebook. It assumes that you have WordPress set to require users to be logged in to take such actions. It wouldn’t make much sense for someone to not be logged in for such functionality. Obviously, you could do something else with Ajax (polls? Loading new content?) that doesn’t have the same assumption, but in this case… we’re assuming a user is logged in and the $current_user global is set.

Getting Started

Let’s start with the basic PHP class (you do write good object-oriented code, right?)

1
2
3
4
5
6
7
8
class My_Like_Button {

    function __construct()
    {
    }
}

$my_like_button = new My_Like_Button;

This code is just a basic skeleton that provides a constructor (the __construct() method, which I’ll use later. It also instantiates a new My_Like_Button object and assigns it to the $my_like_button variable for use in the global scope. Obviously, you can use whatever strikes your fancy for the class name or the global variable.

Building the HTML for the Like Button

Next, we need the basic HTML structure that will be used in our theme for the Like button. For the sake of simplicity, I’m not providing any CSS, but feel free to do as you wish. We need to add this as a new method in our class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function like_button()
{
    if( !is_user_logged_in() )
        return false;
       
    global $current_user;
       
    $html = '<form action="" method="post">
        <input type="hidden" name="like_post_id" id="like_post_id" value="'
. get_the_ID() .'">
        <input type="hidden" name="like_user_id" id="like_user_id" value="'
. $current_user->ID . '">
        <input type="button" name="like_this_post" id="like_this_post" value="Like" />
    </form>'
;
    return $html;
}

This form provides two hidden form fields using get_the_ID() and the $current_user object. Having done this (and after ensuring there is a logged in user), we can now drop this into our theme in the Loop as a template tag:

1
<?php echo $my_like_button->like_button(); ?>

Sending the Ajax Request with jQuery

This is useless by itself. We need something to handle the Ajax. But before we get there, we need to understand how Ajax works within the WordPress context.

All requests must go to wp-admin/admin-ajax.php. Forget the confusion about why you would send a front-end Ajax request to the back-end. You just do.

On the back-end, you’ll have to define functions that will hook into the Ajax API to let WordPress know how to handle the request. More on that in a minute. Let’s build some jQuery to send this to admin-ajax.php.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
function js()
{
    wp_enqueue_script( 'jquery' );
    wp_print_scripts();
    ?>
    <script>
    jQuery(document).ready(function(){
           
        jQuery('#like_this_post').click(function(){
            var like_post_id = jQuery('#like_post_id').val();
            var like_user_id = jQuery('#like_user_id').val();
           
            jQuery.post(
                '<?php echo get_option('siteurl') . '/wp-admin/admin-ajax.php' ?>',
                {
                    action      : 'register_like',
                    user_id     : like_user_id,
                    post_id     : like_post_id,
                    _wpnonce    : '<?php echo wp_create_nonce('nonce-register_like'); ?>',
                },
                function(response) {   
                    alert(response);
                }
            );
               
        });
    });
    </script>
    <?php
}

This is just a PHP function that we can use to throw some jQuery (using the .post() method for our Ajax call) into the head. Note the nonce. You must include this for security. Additionally, you must have an action set. The action is used by WordPress to route the Ajax request.

Finally, we’re passing two extra pieces of data – user_id which is the WordPress user ID and the post_id which is the WordPress post ID of the current $post object inside the Loop. Both of these are supplied in the hidden form fields we created earlier.

Let’s add a new method for hooks and call it in our constructor, so that hooks are executed when the object is instantiated:

1
2
3
4
5
6
7
8
9
function __construct()
{
    $this->hooks();
}
   
function hooks()
{
    add_action( 'wp_head', array( $this, 'js' ) );
}

Supplying the Ajax Handler

Having hooked the jQuery into WordPress, we now need something on the other end to handle the request and return something back to our page. For this, let’s create a method called handle_like().

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function handle_like()
{
    global $wpdb;
    $user_id = (int) $_POST['user_id'];
    $post_id = (int) $_POST['post_id'];
       
    if( !is_user_logged_in() )
        return false;
       
    if( !wp_verify_nonce( $_POST['_wpnonce'], 'nonce-register_like' ) )
        die( 'Go away, asshole!' );
       
    /*
        Here is where we do some sort of database operation to associate
        the Like of the given post with the user who performed the action
       
        Make sure you check for errors. In order to return data, you must
        echo something that the originating page can see. True or false
        only makes sense on this page and not back there.
           
        Typically, you'd output some sort of JSON, XML or plain text.
    */

    $meta_id = add_post_meta( $post_id, 'user_liked', $user_id );
    if( !$meta_id )
        echo "Like not recorded";
    else
        echo "Like recorded";
    exit;
}

In this method, it’s important that all data be sanitized to avoid security problems. I’m performing the most basic of data security here by casting the $_POST variables for the users ID and the post ID to integers.

We’re also checking to make sure the user is logged in. This is why using the built in WordPress Ajax API is actually kind of important. If you build your own Ajax handler, there’s no way to reliable tie in to WordPress to use other APIs like the User API.

Finally, make sure you verify the nonce so you know the request is coming from a legitimate source.

The three security procedures I just listed will largely prevent SQL Injection, ensure authenticated users and eliminate the possibility of Cross Site Request Forgery (CSRF) and generally should be used in all WordPress plugin development.

Simply though, the above method takes the post ID, the user ID and creates a new record in the postmeta table. On success, it will print a success method readable by the original sending page and vica versa on failure.

Note: You must use die() or exit() at the end of the method to make sure the Ajax response exits properly.

Tying the Handler into WordPress

Now that we have a handler method to do our bidding, we need to make sure WordPress knows about it so it routes Ajax requests to the proper place. To do this, we leverage the wp_ajax_{$action} hook.

Remember earlier, while building the jQuery Ajax request, I mentioned that an action POST variable had to be set? WordPress looks to this variable to create a dynamic hook that we can use our new Ajax callback to hook into.

1
add_action( 'wp_ajax_register_like', array( $this, 'handle_like' ) );

Because our action in the js() method was set to register_like, the hook WordPress creates dynamically is wp_ajax_register_like and we can use that to hook our Ajax handler onto.

Wrapping it all Together

Easy right? Use jQuery to send data, wp-admin/admin-ajax.php to receive the Ajax request and pass it on to an appropriate handler function, and send data back to the original page. On the receiving end, you can use normal means to handle the returned data as you wish.

You can download the full code used here at Github.