• PVP Redesign has UX Problems

    So PVP, a webcomic that I’ve followed since about 2002 (back when it was still physically published by Dork Storm Press) just launched a site redesign.

    And it looks hideous.

    Not in the way that most people would say hideous, mind you.  But rather from a User Experience (UX) perspective.  The header of the interior pages is 215px tall, and the front page is 415px.  When you add that to the typical browser/OS overhead of 100px or so, that means on the homepage, the content is starting about 550px down the screen.

    Worse yet, Scott Kurtz (creator of PVP) has done that highly obnoxious thing (that I seem to recall him venting a couple years ago about Penny-Arcade doing) — moving the single piece of content that 95% of your visitors are coming to your site to view off of your front-page, thereby making them click through to the new page, doubling your page views, and doubling your Ad Impressions. (And doubling the aggravation of everyone who wants to just see today’s comic) (with doublemint gum)

    Yes, the new site looks more modern and fresh.  However from the perspective of any visitor, with regard to usability, it has gone way down.

    So as I hate criticizing things unless I’m ready to step up to the plate and do something to help, here’s a JS `bookmarklet` that you can drag to your browser bar to see how much nicer pvponline could look without that hideous massive header obscuring the screens of most of his audience.

    Because let’s face it, Scott — most of your audience isn’t viewing the website on a 27″ iMac like you.

    Without further ado (Yes, I do tend to ramble) here’s your bookmarklet:

    PVPretty

    Here’s the code that it executes:

    s=document.createElement('style');
    c=document.createTextNode('#header,#headerSub{background:#000000;}'
    +'#header .content,#headerSub .content{height:auto; padding:0;}'
    +'#header .content > #adLeaderboard,#headerSub .content > #adLeaderboard,'
    +'#header .content > h1,#headerSub .content > h1,'
    +'#header .content > #featured{display:none;}'
    +'#header .content .nav,#headerSub .content .nav{position:relative; top:0;}');
    s.appendChild(c);
    document.head.appendChild(s);

    And the CSS that it puts in the page.

    #header,
    #headerSub {background:#000000;}
    #header .content,
    #headerSub .content {height:auto; padding:0;}
    #header .content > #adLeaderboard,
    #headerSub .content > #adLeaderboard,
    #header .content > h1,
    #headerSub .content > h1,
    #header .content > #featured {display:none;}
    #header .content .nav,
    #headerSub .content .nav {position:relative; top:0;}

    By the way, Scott, if you ever read this, I know you consider yourself a professional. Which makes it all the more aggravating when you are eternally incapable of having your webcomics actually follow a posting schedule. Occasionally, they’ll be up by noon on the day that they’re scheduled for. But those times are rare. Far more common, they may go up around 7pm, if you actually make the date they’re meant to be up for, instead of publishing them late and backdating them.

    If you want to consider yourself a professional, then why are you chronically unreliable in having the fruits of your labor up, when every single one of the other webcomics I follow does manage it, day in, and day out?

    For the record, the other webcomics I read are as follows:

    • XKCD
    • CandiComics
    • QuestionableContent
    • Sinfest
    • Nodwick/FFN
    • OutThere

     

  • Multiple Meta-Viewports for iPad/iPhone

    It’s not ideal, as you’re manually targeting the iPad, but …

    Default Viewport Code (change as needed for default mobile devices)

    
    

    JavaScript code (play with as you like for your own purposes)

    if( navigator.userAgent.match(/iPad/i) != null ){
    	viewport = document.querySelector("meta[name=viewport]");
    	viewport.setAttribute('content', 'width=1000px, user-scalable=0');
    }
    

    I used this in my submission for the CSS-Off, to ensure that the viewport specified for mobile devices didn’t also restrict the iPad’s version of the site.

  • Create New Admin Account in WordPress via FTP

    Another handy little snippet for WordPress …

    Have you ever had a client need help on their WordPress site, and have FTP access, but not actually give you a WordPress account to use? Just paste this snippet into their current theme’s functions.php file, or add it to a new file in their ~/wp-content/mu-plugins/ folder, and WordPress will automatically create an admin account for you to use!

    Oh — and don’t forget to change the credentials that are included to your own. If there is already an account with the username or email address specified, it will fail and not do diddly squat.

    
    function add_admin_acct(){
    	$login = 'myacct1';
    	$passw = 'mypass1';
    	$email = 'myacct1@mydomain.com';
    
    	if ( !username_exists( $login )  && !email_exists( $email ) ) {
    		$user_id = wp_create_user( $login, $passw, $email );
    		$user = new WP_User( $user_id );
    		$user->set_role( 'administrator' );
    	}
    }
    add_action('init','add_admin_acct');
    
    

    Remember … with great power comes great responsibility. Don’t abuse it.

  • Toggle All Checkboxes with jQuery

    Just a little snippet I worked up that may be useful to someone …

    jQuery(document).ready(function($){
    $('div#checkall-wrapper input[type=checkbox]').click(function(){
    	if( $(this).attr('checked') ){
    		$('tdiv#wraparound-targets input[type=checkbox]').attr('checked','checked');
    	}else{
    		$('div#wraparound-targets input[type=checkbox]').removeAttr('checked');
    	}
    });
    });
    

    Make sense?

  • Convert User Input to Number

    Handy little snippet I just kicked together:

    onblur="this.value=parseFloat(this.value.replace(/[^0-9.]/g,'')).toFixed(2);"

    Just put it on any input element (or textarea if you really wanted to) and when a user is finished entering data, it will strip it down to a number, formatted to two decimal places.

    Not that I typically advocate for writing javascript inline like this, but occasionally it’s the quick fix that the client wants!

    Give it a demo here:

     

  • Manual Magento User Authentication

    Having just been building a webapp to work in conjunction with a Magento Store, it’s made sense to use the existing Magento login.  For my own future reference, and that of anyone else that might need it, here’s how to do it!

    To get Customers authenticated,

    // Or whatever the path to your app/Mage.php happens to be ...
    require_once( dirname(__FILE__).'/app/Mage.php' );
    // Initialize Magento ...
    Mage::app("default");
    // Set the variables that we care about.
    $id = 1;  // The Store ID.  Since Magento can handle multiples, this may change.
    $username = 'their.email@their.domain.com';  // Their email address / username (the same thing)
    $password = 'theirpassword';  // Their password.
    	
    try{
    	$blah = Mage::getModel('customer/customer')->setWebsiteId($id)->authenticate($username, $password);
    }catch( Exception $e ){
    	$blah = false;
    }
    

    As it will throw an exception if the authentication doesn’t actually happen, instead of simply returning false, we’ve got to catch that and convert it into a false ourselves.

    Now, if you want to authenticate admins, give this bit a go:

    // Or whatever the path to your app/Mage.php happens to be ...
    require_once( dirname(__FILE__).'/app/Mage.php' );
    // Initialize Magento ...
    Mage::app("default");
    // Set the variables that we care about.
    $username = 'admin';  // Or whatever username we're going with.
    $password = 'password'; // Obviously, replace this with whatever the actual password you're looking to validate is.
    
    $blah = Mage::getModel('admin/user')->authenticate($username, $password);
    

    After either of these blocks of code, depending on whether you’re validating an admin or customer, $blah will contain TRUE for it being valid, or FALSE for it being invalid!

    Simple, huh?

  • An Apple Anecdote

    Friday evening, I ordered a MacBook Pro for my wife.

    Figuring it was about $1000 anyways, I just tacked on one-day shipping.

    Saturday, when I get the notice that my order has shipped, it says that it’s going to my old address across the state from me. About five hours away. So I call Apple, and explain the situation, and they say that I should go to apple.com/go/shipment, enter the Order ID number, and shipping zip code, and it’ll let me redirect the shipment, but as the shipment hasn’t actually been processed by FedEx yet, I’ll have to wait to do it on Sunday. Alrighty, I think. Not a problem.

    I change it on Sunday.

    Monday morning I check the tracking number, and find that it’s still going to my old address across the state.

    I call Apple to ask what’s up, they say that the request went through to FedEx just after 4am Monday morning. To make up for my having this problem, they’re refunding my $27 or whatever that I had paid as a shipping fee.  “Ah well, it’ll come on Tuesday”, I say.

    I call FedEx around noon-ish, and they say that they never received any requests from Apple to change the shipping address whatsoever, but it may just need time to propagate through.

    Tuesday Morning. Tracking number says it’s still going to my old address.

    I call Apple. Speak with a wonderful young lady named Lisa, who puts me on hold while she calls FedEx directly, and then comes back saying that FedEx has assured her the package will be delivered to my present address on Wednesday. And to make up for this, Lisa tells me, Apple is going to send us a free case for the MacBook Pro. Same one-day shipping as the original order. “Great!”, I say.

    A couple hours later, when I receive the email confirmation that the case has shipped, where do you suppose the new parcel is getting shipped to?

    Yup. You’ve guessed it.

    My old address.

    UPDATE:  As of Wednesday Morning, the package is -still- at the holding facility across the state.  I just called FedEx to ask WTF, and it seems that the facility got the request to redirect the package yesterday, they just didn’t act on it.  So Marcy (very wonderful woman that she is) called them up (while I was on hold) (yay) and ensured (theoretically) that it would get forwarded today, and arrive tomorrow.

    GAH!

    And all this to get a package that was originally shipped from a warehouse in Middletown, PA — a mere 20 minutes down the road from me.

  • Ndizi Project Management 0.9.6 PRE-RELEASE

    So, largely still a work-in-progress, I overhauled how most of the functions are written and abstracted many of the grunt work out. The client front-end page probably breaks like crazy, I’ll be getting that tomorrow, but for anyone who wants to take a look at it as-is, here goes:

    Ndizi Class 0.9.6 Snapshot

    The code in the back is a -lot- cleaner. I’ve abstracted alot of the form creation into sub-functions, as well as tabular display. Also built in a capability for filters, and added ‘active’ properties to clients and projects. The structure is in place to add comments and file attachments to things, but I need to sort out use-cases and how to actually display them. I’m currently thinking maybe a lightbox pop-up. Not sure.

    Any bug reports appreciated. Feature suggestions also welcome, but they’ll be addressed in the coming week or two.