Twitter RSS

Simulating HTML5 Local Storage Support

Thursday, January 14th, 2010

I have been wanting to use HTML5’s local storage for a while, but I haven’t had a project where I can just ignore the older browsers.  So I put together a little ( <1Kb gzipped ) script that checks for HTML5’s local storage API, and simulates the method for browsers that do not support it. For those browsers, the script implements a nearly identical interface to localStorage for persistent storage of name/value pairs, except it uses cookies.  For the impatient types, you can see the repo at github or download the script. Below is a description of usage:


localStorage.setItem( key , value );
// saves a new name/value pair if the key doesn't exist, otherwise
// updates the value

localStorage.getItem( key );
// returns the value associated with the given key, if it exists
// returns null if the key doesn't exist

localStorage.length;
// the number of unique keys stored

localStorage.removeItem( key );
// deletes the name/value pair with the given key, if it exists
// if it does not exist, exits

localStorage.clear();
// delete all name/value pairs currently stored

localStorage.key( n );
// returns the name of the nth key in the list, will return null if n is
// greater than or equal to localStorage.length

If the localStorage object is available, the setup script exits and allows the method to work normally.  Otherwise, it will use the same interface to create a string of name/value pairs to store in cookies.  You can use all the methods described above, but it does not support direct access to data, such as ‘localStorage.name = “bob” ;’.  One issue is that the older browsers with slow performance will experience another setback when storing large amounts of data, because the cookies will be included in headers.

There are two types of storage methods in the new Web Storage Specification: localStorage and sessionStorage.  The sessionStorage data will only persist for the life of the browser window, whereas localStorage will last indefinitely, depending on the browser.  This script uses the localStorage, but can be switched to sessionStorage pretty easily.  There are a few resources out there already where you can learn a little bit more.  Currently, the specification is supported by IE8, Firefox3.5, Safari4, and Chrome (localStorage only).

Download or Check out the repo on github.

[Note: I've done some brief testing on most browsers, but if you run into a problem, let me know]


Simple Pagination with Rails

Tuesday, May 5th, 2009

While I was developing Motionspire, I needed to implement a pagination system for the video content.  I looked through the existing plugins, but found that I really desired something extremely simple and custom to work within my search controller.  With only a few lines of code, I created a very basic system for managing pagination that can be ported to other sites with ease.

The Search Controller

The Motionspire search controller uses one function and view for returning any content, whether it’s filtered or not, so the pagination only required one copy of the code to be implemented.  I keep a session variable for maintaining the user’s preference for items per page, and if that parameter has been sent to the search function I set the session variable :


if params[:itemsPerPage] then session[:itemsPerPage] = params[:itemsPerPage] end

When I run though the search function, I see if a page parameter has been passed:


if params[:page] then @page = params[:page].to_i else @page = 1 end

After I retrieve the articles pertaining to the search parameters (in this case the results are stored into an array called @videos), I check the :itemsPerPage preference and find the last possible page:


if session[:itemsPerPage] then @per = session[:itemsPerPage].to_i else @per = 24 end

@lastpage = @videos.length/(@per) + 1

if @videos.length%(@per) == 0

    @lastpage = @lastpage - 1

end

I have a default itemsPerPage value of 24 hardcoded, and you can change this for your search.

From here, we simply return the search results for that page, using the current page and the items per page preference:


@videos = @videos[((@page-1)*@per),@per]

For search queries within a large data set, I would recommend using these parameters with the sql query with the ‘ORDER BY’ and ‘LIMIT’ in order to avoid returning extremely large results unnecessarily.

The Helper

First, I created a short helper function that finds the min and max pages, ensuring we don’t show a negative page or a page that doesn’t exist:


def minmaxpage(current,total,option)
    min = current - 2
    if min < 1
        min = 1
        max = 1 + 4
        if max > total then max = total end
    end
    max = min + 4
    if max > total
        max = total
        min = max - 4
        while min < 1
            min = min + 1
        end
    end
    if option == 'min' then return min else return max end
end

The View

For the content from the view, we use the @videos array to present the content for the page.  The only custom coding necessary is in the links for the pages.  For this site, I provide a first and last page link, along with 2 pages on either side of the current page.  You can manipulate this code how you want, but the basic idea will remain the same.

First we grab the min and max page from the helper:


<% min = minmaxpage(@page, @lastpage, 'min') %>

<% max = minmaxpage(@page, @lastpage, 'max') %>

For the code for the page links, we simply check to see if the min page is within two of the current:


<% if min < @page %>

    <%= link_to( "Prev",

        :action => "search",

        :page => (@page - 1) ) %>

<% end %>

<% if min > 1 %>

    <%= link_to( "1",

        :action => "search",

        :page => 1 ) %>

<% end %>

<% x = min %>

Then we loop through the remaining pages, ensuring we don’t go over the max, and make the current page simple text instead of a link:


<% while x <= max %>

    <% if x.to_i == @page.to_i %>

        <span class="current"><%= x %></span>

    <% else %>

        <%= link_to( x.to_s,

            :action => "search",

            :page => x ) %>

    <% end %>

    <% x = x+1 %>

<% end %>

<% if max < @lastpage %>

    <%= link_to( @lastpage.to_s,

        :action => "search",

        :page => @lastpage ) %>

<% end %>

<% if max > @page %>

    <%= link_to( "Next",

        :action => "search",

        :page => (@page + 1) ) %>

<% end %>

The code may look a little long, but the implementation took very little time.  I know exactly what the code is doing and it is very easy to expand this for different situations and code.

There are a lot of solutions for pagination of content, but I found that this simple implementation helped me avoid using plugins and save time.  Let me know if you guys have any questions or comparable solutions.


Twetris: twitter + tetris

Monday, April 6th, 2009

We developed a little creation called Twetris that uses the twitter timeline to create blocks for a tetris game. The high score list is published automatically to @twetris and you can even retweet your high scores right from the game. It’s a simple javascript/html/css creation thats great for wasting time.
Check it out!


April Fools ‘flip text’ Script

Wednesday, April 1st, 2009

Over breakfast this morning, I put together a little JS script that will flip all the text on a page.  Just put this link AT THE BOTTOM of your page, and it should provide a little April Fools joke for some visitors:


<script type="text/javascript" src="http://www.thewojogroup.com/flipEm.js" ></script>

**Make sure to test this on your site, some flash objects or other plugins may not work properly

Enjoy!


Developing vs Programming

Thursday, March 26th, 2009

I’m a mediocre programmer, at best.

When I’m programming, I need 8 different tabs open with every reference site I can get for a particular language.  I google function names constantly, most of my debugging time is spent with dumb syntax errors, and I’m never going to be able to use Regular Expressions off the top of my head.

So what can mediocre programmers like myself do? Develop. I’m going to go over a few tips for good application development, and how to use development methods that can improve your programming, even if you lack superstar skills.

Project Management

There are too many different project management philosophies to mention here, and many of them are developed by very experienced and knowledgeable professionals in the industry.  However, project management and planning remain to be the biggest downfall for most programmers.  Many of these methods are made to apply to development teams, but you can abstract a lot of the ideas to individual projects.  Try to check out a few papers or books on the topic during your free time.

1/3 Rule

For most projects, I try to stick with the 1/3 rule:  spend (approximately) 1/3 of your time on planning, 1/3 on coding, and 1/3 on testing.  Many programmers expect to spend the majority of the project timeline writing code, and believe that good code will drive the project.  However, I have found that most worthwhile final products are created from development timelines that have actual coding as a minority.  This 1/3 flow can often take iterations for different portions of a project, where you plan, code, and test small portions and move on to the next section.  But you will often find dedicating time to plan properly will cut down on actual coding, and proper testing will save you time in the long run.

Start with Your User

I am a big fan of top-down development.  There are a lot of different theories about development strategies and methods, but I have found that for real world applications, the single most important aspect of any program is the interface.

With that in mind, I start my planning with laying out the interface.  Implementation of this idea can vary depending on the project.  For example, you may start with wireframes and a user flow for a web application.  For something like simpleCart(js), I started by listing every way in which the user would interact with the code, including function calls, div classes, and html layout for cart items. When you start your project by building out the interface first, you are ensuring that your program will adhere to the end-user functionality of the project.

Compartmentalize Functionality

It doesn’t matter whether you are a big believer in MVC (I am) or like procedural or object-oriented (I’m a OOP guy); you will find yourself improving your code by creating structure first, and then implementing code.  It is often beneficial to create functions (or objects) that relate to real-world goals or problems.  If you say to yourself, “I am going to need to store the current user preferences in a cookie,” you might want to create a function for exactly that.

By focusing on individual problems, it becomes much easier to create efficient code for that particular purpose.  In turn, you often write better code.  It also becomes much easier to debug; if you are having a problem storing to a cookie, you simply look at your ’store to cookie’ function.  Documentation also becomes extremely easy, as the purpose of your code becomes evident simply by looking at the function name.  I know this may be second nature to many developers, but it can’t hurt to mention it.

Abstract Data Storage

I’ve found that many projects outlast hardware, hosting, or storage implementations.  You may move your code to another server, decide to implement a different database system, or find that you outgrow your storage and need to keep data in more than one place.  In any of these cases, abstracting data storage and retrieval functions from the rest of your code will benefit you immensely.  Data storage is often the last part I consider for my project.  I often do most of my developing with two empty functions: load() and store(). They are usually the last thing I implement, as, in most situations, they are the least important to the functionality of your end-user.  It also becomes extremely easy to maintain consistency of your core functionality when switching to a new data implementation by simply altering these functions.

Conclusion

These are all very high level concepts, and it may or may not be clear how to actually implement some of them in your projects.  The overriding theme that I hope you can take away from this article is that every program looks the same from 10,000 feet.  Most great applications are built with the end-user in mind, and great development isn’t necessarily dependent on great code.  Please let me know if you guys have any other tips.