(un)Scheduled Maintenance

I just recovered from an issue with my WordPress automatic upgrade where the site only displayed the message:

Briefly unavailable for scheduled maintenance. Check back in a minute.

Fixing it the hard way

After completely freaking out for about a minute, I followed the instructions on Updating Manually. Instead of using FTP I used the OSX Terminal and ssh to do most of the work directly on the server. I simply renamed the previous install folder, scp‘d the new version of WordPress and unzipped it. Once the site was up and running again with the content, themes, and plug-ins copied over and re-enabled, I was on my way to make an archive of the previous version when I found the culprit in the root of directory.

The offending file: .maintenance

Perhaps appropriately named and sitting there invisible next to .htaccess, here’s what the file contents looked like when I opened with pico:

< ?php $upgrading = 1307724895; ?>

After doing some Google-driven research, I found an article discussing
WordPress Maintenance Mode Without a Plugin. Apparently, this is a feature baked into the application for making the site intentionally unavailable, and something in my upgrade process had failed to trigger its deletion.

Aside: for what it’s worth, there’s also good instructions on creating a custom design for this page in the support forums.

The easy solution

Remove .maintenance from the file system to put WordPress back into normal operation.

Have you ever worked with .maintenance before? Want to share any tips or tricks for working with ssh? Please post them in the comments below!


Parse the Querystring with jQuery

In a number of the web applications I have recently been working on, I have found it necessary to dissect the URL and access the various parts of the querystring. While the window.location object already has some useful properties, I wanted to be able to reference the indices using bracket or dot notation so I put together this handy plugin for my favorite JavaScript library, jQuery.

Plugin

1
2
3
4
5
6
7
8
9
10
11
12
jQuery.extend({
  parseQuerystring: function(){
    var nvpair = {};
    var qs = window.location.search.replace('?', '');
    var pairs = qs.split('&');
    $.each(pairs, function(i, v){
      var pair = v.split('=');
      nvpair[pair[0]] = pair[1];
    });
    return nvpair;
  }
});

Usage

Assuming the URL is http://mydomain.com/page.html?foo=bar&somevalue=myvalue, you can either access an index directly jQuery.parseQuerystring().foo, or by setting a variable, like this:

var qs = jQuery.parseQuerystring();
//qs['foo'] == "bar"
//qs.somevalue == "myvalue"

The goal of extending the jQuery object with this utility (meaning that it does not require a selected set of elements, and in this case does not even require an argument) was flexibility, however it can easily be converted to a function in the global namespace. If you would rather download the files, they are zipped up and ready (zipParseQuerystring jQuery Plugin).

Are there additional operations you’d like to see added to this, or relating to the URL and querystring? Let me know in the comments.

Update: Code posted to GitHub as a Gist snippet


Export Illustrator Vector Artwork to a Canvas Element

Transforming my ugly old bitmap logo graphic into a slick canvas element with polished gradients and smooth curves, using the Ai→Canvas plug-in could not have been any easier.

After downloading and installing the OSX version of the plug-in, I starting with the old graphic as a reference and placed (not linked) the .JPG into an Illustrator artboard. I next overlaid my original vector paths and resized them to the correct proportions. I pulled out all the colors that I needed and inserted a layer underneath to simulate the drop-shadow used previously. Note: I did not consider using CSS3 box-shadow property because my graphic is a circle, not a box. I did not test this presumption however.

Once the weight and color of the stroke were set up, I configured the gradients to match the look of the bitmap and saved a working copy as an EPS. After a quick File > Export a nicely constructed .HTML file was created in my directory, and opened in my default browser.

Some of the alterations that I made to the exported code include:

  1. wrapping the canvas in an a element
  2. initializing the rendering via jQuery $(document).ready(…) instead of <body onload="init()"> and cleaning up the then-unnecessary function declarations
  3. adding alpha channel to the “background” gradient
    1
    2
    3
    
    gradient.addColorStop(0.92, "rgba(66, 101, 47, 1)");
    gradient.addColorStop(0.97, "rgba(160, 178, 151, 0.5)");
    gradient.addColorStop(1.00, "rgba(255, 255, 255, 0)");

Feel free to check out the source code of this site in lieu of specific code examples.

I didn’t include any screenshots of the process, simply because the whole thing took less than an hour to put in place. Would step-by-step screenshots be helpful?


Migration Complete!

No, we’re not talking about the birds returning from the south for spring. I recently made the very difficult decision to get rid of my home-brewed site in favor of one using WordPress. While I am still very proud of the work I did previously, which included programming my own PHP5/MySQL application, the benefits of an open-source CMS certainly cannot be ignored.

Some of the features that compelled me to convert include:

  • Clean separation of content from structure and presentation
  • Secure administrative area for updating posts and my portfolio projects
  • Hook to the LinkedIn API to pull in my resume data, instead of managing two separate profiles
  • Robust system to present code examples and manage downloadable files
  • Central hub for social media presence and web development interests

When it came down to it, I really couldn’t justify having two sites when all the functionality I needed could be provided by only one.

The experience was both challenging and fulfilling, and I not only have a deeper understanding and appreciation for WordPress but I also gained some insight into customizing a theme. While the process seemed daunting initially, I was surprised at how smoothly it went once it was broken down into digestible pieces.

I built on the minimalist Toolbox theme, which in addition to using many of the new semantic HTML5 elements appropriately, offers a decent number of page types and an excellent sample.css for reference. I included many of the aspects of my old layout, adjusting a number of background images for use in the page header and footer. Aspects of the Almost Spring theme that was previously applied to my standalone blog were blended in. Lastly 960.gs was included for a base grid-system to organize and standardize the layout.

Of course I still have a laundry list of features I’d still like to implement:

  1. improve the styling and functionality of the sidebar
  2. create a page to showcase my interest in photography, hooking up to flickr as well
  3. move away from background imagery in favor of slick CSS3 effects
  4. convert my personal logo to a canvas or SVG element Completed! Thanks to the Ai→Canvas plug-in.

I also would like to go back through old posts and establish a more meaningful set of category and tag taxonomy. That, however, will require a whole different kind of thinking.

Feel free to poke around and check things out, and if you have feedback or a suggestion, you’re welcome to provide it in the comments.


Toggle Text Field Values with jQuery

UPDATED: Project moved to Git!

I saw this post on the CSS Tricks Snippet Feed which addresses a commonly desired form behavior: to provide default text in an INPUT element that disappears when the user enters that field. The example provided works, but I have a couple issues with it:

  1. Uses inline JavaScript, and must be reapplied to each element affected
  2. Repeats the contents of the value attribute
  3. The default text is not replaced if the user exits the field without entering new data

So I created a possible solution, using jQuery:

HTML

1
<input type="text" value="Place default text here" />

JavaScript

1
2
3
4
5
6
7
8
9
10
11
12
13
14
jQuery( function(){
  $( 'input[type="text"]' ).each( function(){
    $(this).attr( 'title', $(this).val() )
      .focus( function(){
        if ( $(this).val() == $(this).attr('title') ) {
          $(this).val( '' );
        }
      } ).blur( function(){
        if ( $(this).val() == '' || $(this).val() == ' ' ) {
          $(this).val( $(this).attr('title') );
        }
      } );
  } );
} );

This script first iterates over each of the text input to assign a semantic text attribute, helpful not only in storing the default value, but also providing a tool-tip for reference as the user interacts with the page. It then assigns behaviors for both the onfocus and onblur events, eliminating the need to respecify data for comparison. The script is cleanly separated from the markup and, using jQuery, additional specifications may be made so as to only affect children of a particular FIELDSET or only those that possess a certain class.

I hope you find this snippet useful, and feel free to comment if you have additional information to share.


UPDATED!

We, as designers and developers, cannot help but go back to review our sites and code to make updates and revisions as our skills, philosophies and tastes change. In this spirit, I would like to offer an alternative to the above JavaScript snippet. The one above, in my opinion, is lacking in the following ways:

  1. Applies the behavior to all input[type="text"] elements indiscriminantly.
  2. Overwrites any existing title attribute content
  3. Does not account for existing text field values resulting from pre-population or validation.

So with that in mind, here’s the new solution:

HTML

1
2
<input type="text" title="Place default assistive text here (e.g. First Name)" />
<input type="text" title="Default assistive text (e.g. E-Mail Address)" value="invalid@ddr.ess" />

jQuery Plugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$.fn.toggleField = function(){
  return this.each(function(){
    var $this = $(this);
    if($this.val() === '' && $this.attr('title') !== ''){
      $this.val($this.attr('title'));
    }
    $this.bind('focus blur', function(){
      var $this = $(this);
      if($this.val() === $this.attr('title')){
        $this.val('');
      }else if($this.val() === '' || $this.val() === ' '){
        $this.val($this.attr('title'));
      }
    });
  });
};

JavaScript

1
2
3
jQuery(document).ready(function(){
  $('input[type="text"]').toggleField();
});

By converting the behavior into a plugin, it becomes chainable and more flexible. Perhaps in a future version it would be useful accommodate additional field types or textarea elements. I have also packaged the plugin for download (zipToggleField jQuery Plugin). I look forward to seeing your questions or suggestions in the comments below!

Project Moved to Git

After further review and consideration, I decided to make some more changes to the plug-in to take advantage of some of the new features promoted in HTML5. Specifically the placeholder attribute, since this is essentially the behavior that we are trying to mimic. Here is an example:

<label for="email">Email:</label>
<input type="email" id="email" name="email" title="Enter a valid email address" placeholder="account@domain.tld"/>

The previous zip file will remain available above, but the toggleField.jquery.js project updates will progress on GitHub instead. Thanks to everyone for your suggestions and support!


Open-Source Alternative to Basecamp: ProjectPier

A number of companies use 37 SignalsBasecamp, a hosted project management, collaboration and tracking application online. It features a rich interface and many layers of administration and accountability. basecamp dashboard

Branching from an early open-source version of Basecamp, activeCollab is an alternative that can be installed and managed on a company’s own servers or local network, but has become a licensed product since it left beta.
activeCollab dashboard

Enter ProjectPier, which I installed and have started using for many of my clients after reading about the application.

From the developer site:

ProjectPier is a Free, Open-Source, self-hosted PHP application for managing tasks, projects and teams through an intuitive web interface. ProjectPier will help your organization communicate, collaborate and get things done Its function is similar to commercial groupware/project management products, but allows the freedom and scalability of self-hosting. Even better, it will always be free.

It was easy and intuitive to set up new clients and assign them to projects, and create milestones and to-do items for everyone. Other key features that I found useful include:

  • sharing and tagging of important files
  • communication and notification settings, including e-mail and RSS
  • custom theming and form creation

If you can live without many of the Ajax-y bells and whistles that Basecamp touts, as well as the real-time whiteboard and team time-tracking, ProjectPier is a solid application for collaboration. Download the source code and try it out!


Advice for Experts

Jeff Atwood on the Coding Horror blog recently discussed the phenomenon of being perceived or representing oneself as an expert. He provides examples of the modern “anti-expert” bias, and offers some advice to the New Experts, courtesy of James Bach:

  1. Practice, practice, practice!
  2. Don’t confuse experience with expertise.
  3. Don’t trust folklore — but learn it anyway.
  4. Take nothing on faith. Own your methodology.
  5. Drive your own education — no one else will.
  6. Reputation = Money. Build and protect your reputation.
  7. Relentlessly gather resources, materials, and tools.
  8. Establish your standards and ethics.
  9. Avoid certifications that trivialize the craft.
  10. Associate with demanding colleagues.
  11. Write, speak, and always tell the truth as you see it.

Read the full article.


Innovative Layouts and Content Transitions with JavaScript

I started following @jquery on Twitter sometime ago, and they have provided a lot of great links and information.

One interesting link is to an article about methods for presenting information and creating systems to enhance user experience:

Delivering informative structure is the primary task an interactive user interface should be able to cope with. The more intuitive layout structure is designed, the better users can understand the content.

Read the full article on Noupe.


Examples of jQuery In Action

The jQuery foundation has created a new site showcasing designs that Use jQuery. They currently have only about 30 samples organized by effect/function category, but they do accept submissions so show off that great interface or behavior that you’ve created!


Logo Design Inspiration

I recently stumbled upon a list of 54 Kick Ass Creative Logos which in turn led me to Logo Faves, who accept submissions from designers, and describe themselves as:

A collection of best designed logos around the web is showcased in Logo Faves. We don’t want to be like other Logo repositories, our idea is to bring you all the best of best logos.

Also relying on suggestions and entries from webmasters to compile its collection, Web2.0 categorizes over 100 logos and displays the user-ratings for each.

FontFeed took a bit of a different approach in grouping popular web logos by style, and even though the article was published in 2006, it is still a great source of information.

So what are you waiting for? Check out some of the design resources over at For Web Designers and submit your best work!

Of course, you could always just use a pre-configured generator.


21 Useful Font Utilities

Looking for the perfect font system for your design, compare different styles side-by-side, or embed non-”web-safe” typeface in the layout? There’s a web application for that.

Highlights include:

  • STC fontBROWSER – an online tool for browseing varoius fonts and viewing how your selected text looks with each.
  • WhatTheFont – upload any image with characters and instantly find the closest matches within their database
  • Typetester - compare different fonts for the screen, up to three at a time
  • Font Burner – replace text on your page with one of 1000 vector-based fonts with a simple block of code

Check out the entire list of 21 Typography and Font Web Apps You Can’t Live Without.