Dashboard Update

In preparing for upcoming job interviews, I’ve been working on my dashboard a little more. Here’s a preview of some of the changes. I’ll most likely write a post explaining some of them, and the problems encountered along the way, very soon.

Highlight Selected Page: Jquery + CSS

While working on my latest side project, I realized that I’ve never highlighted the current page in the navigation menu of any site I’ve worked on. While it doesn’t initially sound like it would be an issue, it’s a tad more involved than it sounds. I read up on a few different methods, but ended up creating my own. It’s only a few lines of code, and although it requires adding an ID and class to each page in navigation, it does the trick. It’s a similar solution to one of the popular ways of doing this, but without as much convoluted CSS.

First, the HTML. Since I’m working in a framework that declares the body tag for each page statically, I added a unique div ID to each of my main pages to identify it, and then gave each div the same class. Then assigned the same ID to the navigation links that correspond to the pages.

<div id="home_page" class="current"></div>
<div id="about_page" class="current"></div>

<div id="nav">
      <a href="index" id="home_page"><li>home</li></a>
      <a href="about" id="about_page"><li>about</li></a>

Now that we’ve got the HTML, we need to set the styles for the selected page. For my project, I just wanted a simple grey background behind the selected page. I decided to make the selected style the exact same for the navigation hover.

.selected_nav, #nav a:hover {
padding: 3px 0;

Finally, we just need to grab that ID on every page load, and tack on the styling class. I added this JQuery function to the default layout page so that it’s included in every page request.

$(document).ready(function() {



Good night, and good luck.

Dashboard: Commit #796cfbcff764

Around this time two years ago, in Zuckerberg-ish like attempt to distract myself from a bad breakup, I joined with my good friend Breland in an attempt to create a killer web app called Joupes. After months of working on it (I would design and market, Breland would code), we released the Alpha version. Yeah, you heard right – Alpha, not Beta. This here is real. Long story short, it was a very un-Zuckerberg-ish like failure. We had big ideas and little patience, and while I still believe we had some excellent features, they were far from ready.

Fast forward two years. I’m a Senior in college, engaged and working an internship which has allowed me to learn and practice web development on a daily basis. On top of this, I’ve been blessed to be given a few art opportunities over the last year, which is a dream come true. As with any success, mediocre as it may be, there arise challenges. Over the past few months, I have become increasingly aware of the lack of stable system for tracking canvas orders. Surely, a task-minded, sometimes OCD list-maker would have a system in place to keep track of a years worth of sales? Unfortunately for this list-maker, the answer was no. Over the last few weeks, in the bits of spare time I’ve found between classes and my work schedule, I sought out to remedy this. Below are the details and outline of my progress thus far.


I’m building this application on top of the open source Scaffolding framework by Jimmy Sawczuk.

This is commit #796cfbcff764 and can be viewed here on Bitbucket.


The original plan for this dashboard is that it would be a simple list of canvas orders and prices, kept in a database and displayed in a table format somewhere in depths of my server. As with all coding projects, though, this quickly turned into much more.

At the base, I wanted to have a working, intuitive system for adding and tracking orders. In it, I would track the price, size, description, customer and if the order had been completed. The gross totals would be added and displayed, along with information pulled from the Facebook fan page. All of this information, including a brief “Recent Orders” list, would be displayed on the main dashboard index. The entire list, including the ability to add items, would be on a separate page.

Also, just for fun, I wanted some way to countdown to my wedding day. Call me crazy, but I cannot wait to be married, and having a visual reminder that the day is drawing nearer is something I’d love to have every time I log in.


This has probably been the most fun thing to work on so far in the app. It’s pretty simple, but I played around with some JQuery that let me do some neat things. The code for the countdown is fairly straight forward, though I had to do some research as I had never used the mktime() function. I ended up using a slight variation of this code, which not only figures out the remaining time, but breaks it into hours and days.

$time = ( (mktime ($hour,0,0,$month,$day,$year) – time(void) )/3600 );
$hours = (int)$time;
$days = (int)($hours/24);

After that, I thought it would be neat to pull both of our Facebook pictures from Facebook and display them alongside the countdown. As it turns out, this is incredibly simple and doesn’t require an auth token. In fact all you have to do is use the Graph API picture URL as your image src:


Finally, I thought it should be livened up with some neat JQuery effects. I decided to animate the containing div by making it grow as soon as the page is loaded, the dropping in the content.

$(‘.box’).animate({width:”930px”}, 2000, function() {

Basically, that just tells the ‘box’ class to increase its width to 930px, do it at a speed of 2000, and once the action is complete, slide down the contents of ‘#marriage’. Aside from the cool effects, here is the end result.

Order Tracking

This piece actually went fairly smoothly. I searched through old emails, Facebook messages, photo comments and text messages to create an order history spreadsheet. I imported this into my database and pulled all orders into the Palmetto Graffiti page.

The one thing I will say about this is that I decided to only show prices for completed orders. For the orders that had not yet been completed (meaning I had not yet collected money), I showed a “Mark As Complete” link. This simply grabbed the ID of the selected order and updated the database to show the order had been complete.

Though most of the functionality is completed for the task list, it’s still not quite done. I’ve also had to rethink the Flickr idea, since the load time for this was a little ridiculous. Once I get these things done, I’ll follow this post up with my next major commit.

Chrome Development

Magic Elves

It’s safe to say that, over the past year, my confidence in web development and design had greatly diminished. Coming out of a small private school, I was the only student within 3 grade years who was even remotely interested in computing – web development or otherwise. After landing an amazing internship last year with a local startup, I was immediately overwhelmed by the new language (PHP), writing SQL queries, and working with source control and virtual hosts.

Even as a Computer Information Science student, I always subconsciously thought certain things on the internet were made by magical programming elves – stuff that was much too difficult for even the average programmer. I’m not sure exactly why I thought this way, but I suspect it has to do with two main things. First, I went to a very small high school, and there was only one computer course offered. This one course taught Microsoft Office, Paint, and other basic Windows utilities and programs. That’s it. The only programming I was introduced to in high school was BASIC on my TI-83. Secondly, upon arriving at USC, I was only introduced to 2 languages in my first two years – Visual Basic and Java. The problem, I think, is that the end result of our assignments was usually something not too far from what I had built in high school on my calculator, just on a bigger scale, with fancier graphics. Again, I thought, can’t everyone do this?

It was not until I started this internship that I saw programmers making useful web apps. And it was awesome. And absolutely overwhelming. Over the next few months, I provided my superiors with an endless stream of questions, problems, and things I had messed up. I infuriated them, infuriated myself, and felt I was going no where. Although I am by no means a good programmer yet, I have come a little ways since then, I think. The thing that has helped to drive me the most is the desire to make useful web applications – things that I previously thought were untouchable. The following is my first successful attempt, apart from projects at work, at doing so.


The Problem

Every web app should, in some way, solve a problem. Going into this project, here are the 2 things I knew:

I wanted to develop a Chrome extension that would make life easier for me, if not other people.
I wanted to tap into some API to get/post data
After searching around, I realized that one thing that keeps me from using my YOURLS installation to shorten links, is that it requires me to copy the link, log in to my installation, paste, shorten and copy again. Although I think the idea of a link shortener on my own personal domain, I had not been using it as frequently as I thought I would, for the reasons stated above. Therefore, I decided to build some extension that would automate the process for me – taking the URL of the current page tab, shortening it, and spitting out the shortened link.

Learning Extensions

Although I had tinkered around with extensions before, I had never had any success. This tutorial from Google is really helpful in learning how extensions work – it gives just enough to get you started, and leaves the door wide open for pursuing your extension development.

Building shortenYOURLS

To begin, every extension requires a manifest.json file that includes important details about the functionality, permissions, pages and icons. As shortenYOURLS is pretty basic, I don’t need a whole lot in my file.

“name”: “shortenYOURLS”,
“version”: “1.0″,
“description”: “Creates a YOURLS shortened URL and copies to a text box for the user to copy.”,
“browser_action”: {
“default_icon”: “icon.png”,
“popup”: “popup.html”
“options_page”: “options.html”,
“permissions”: [

The name, version and description are all pretty self explanatory. Browser action basically defines the icons to be displayed in the browser, as well as the HTML pages used in the extension. A chrome extension can ONLY read an HTML file for a popup window – PHP and other files will not work. For this example, we have only defined a popup window, which is the window that expands from the extension’s icon when you click it. For the time being, don’t worry about the “options_page” definition – we’ll get to that in a bit.

Permissions are very important. Essentially, this tells Chrome what outside resources you need access to in order for your extension to work properly. If you don’t have these defined correctly, your extension won’t work. For my project, I needed to connect to the YOURLS installation, and to read the current tab URL. The tab part was easy – I just set a “tabs” permission. The YOURLS API was a little trickier. The problem is that the API file I need to access is located at a different place for each user, since the point of YOURLS is to provide a URL shortener on your own server. After asking the community at Stack Overflow, I decided to just ask for global web permissions – “http://*/”.

So now that we have the manifest completed, we can build the app. At its heart, it was very little code and fairly quick to write. All I needed to do was hit up the YOURLS API, including POST parameters for the unique user signature, the URL being shortened, and the action (shorten, expand, etc). All of this information can be found on the “Tools” page of your YOURLS installation. As I said before, you must use an HTML page for your extension popup, so I chose to add some JQuery to get the job done. First, I needed to grab the current tab URL.

chrome.tabs.getSelected(null, function(tab) {
var tabUrl = tab.url;

Pretty straightforward. Having that, I nested the following inside the getSelected() function to send the information along to the YOURLS installation.

$.post(localStorage[“domain”]+”/yourls-api.php”, { signature: localStorage[“sig”], action: “shorturl”, url: tabUrl, format: “text” }, function(data) {

This is a pretty straightforward JQuery $.post(). The required parameters are attached (signature, action, url and format). This will return data to the variable defined in the function call, in this case “data”. I simply threw this into the input box in my HTML page, selected the text to make it easier to copy, and I’m done!

Now, you may be wondering what “localStorage” is. When I first wrote the extension, I did it just for me, so I hardcoded the signature and domain. However, as this is hopefully going to be used by more people, and most likely if it is, those people aren’t going to want to modify code, pack the extension and load it, it would be useful to have an options page that made this process much simpler. Every extension is allowed to have its own options page, accessible from Options->Tools->Extensions. The obvious answer, then, was to create a quick options form that allows users to enter their domain and signature.

Remember when I said to forget about the “options_page” definition in manifest.json? Well, now’s the time to remember it. That definition simply defines which HTML page you want shown as your option page. If nothing is defined, there will be no options link beside your extension on the Tools page. However, if there is something defined, the link will open your specified HTML document in a new tab for users to set their preferences.

Much like the popup, you can just construct a simple HTML form (or whatever) to set user data. What’s great is that you can save information to “localStorage”, allowing you to access it anywhere (except manifest.json) in your code. So, with a quick Javascript function and an HTML form, I had my options page.

function save_options() {
var domain = document.getElementById(”domain”).value;
var sig = document.getElementById(”signature”).value;
localStorage[“domain”] = domain;
localStorage[“sig”] = sig;

Obviously, this is 2 lines longer than it needs to be, but I did it for clarity’s sake. I also chose to include a separate function that adds the values of localStorage to the form when a user arrives at the options page, so they know if they’ve set options yet.

And that’s it! You know have a fully functioning, packable Chrome extension. Sorry for the lack of brevity – I haven’t written in almost a year, and I’ve learned a great deal through this venture and recent work I’ve been doing. Hope it helps!