<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>Projector is a project management tool made for consultants and contractors. We focus on putting budget and timeline first, so that you and your clients know where you are at all times of the development cycle.</description><title>Projector - Project management for Web Developers</title><generator>Tumblr (3.0; @projectorapp)</generator><link>http://projectorapp.tumblr.com/</link><item><title>Tracking time with Projector and Harvest</title><description>&lt;p&gt;&lt;span&gt;I’m horrible at tracking the time I spend on projects. Up until recently, I’d be scratching my head at the end of the day trying to put together descriptions to correlate to my time logs.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;Since we first broke ground on &lt;a href="http://www.projectorpm.com" title="Projector" target="_blank"&gt;Projector&lt;/a&gt;, one of our goals was to make the experience of tracking time as simple as starting and stopping project tasks. Today we’re proud to announce that this is no longer a dream.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;iframe frameborder="0" height="473" src="http://player.vimeo.com/video/37913642?byline=0&amp;amp;portrait=0" width="631"&gt;&lt;/iframe&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Linking Projector with your &lt;a href="http://www.getharvest.com" title="Harvest" target="_blank"&gt;Harvest&lt;/a&gt; account is a breeze, for both you and your entire team. The first step (getting your Harvest OAuth identifier into Projector) is somewhat lengthy, but after that it&amp;#8217;s just a few seconds to link future developers and projects to Harvest.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Log in to Harvest, select the ‘Manage’ tab, and click ‘Account Settings’. Scroll down to the ‘3rd Party Integration’ section and click ‘Edit Authentication Tokens’.&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Your administrator will need to create an OAuth token for Projector. Click ‘Add Token’ and put in ‘Projector’ as the name, and ‘http://.projectorpm.com’ as the Redirect URI. The website field doesn’t really matter, but feel free to put in our website.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;Finally, after creating your token copy the ‘Identifier’ in the right sidebar. This is your Client ID that will allow Projector to request a token on your behalf.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Log into Projector and select ‘Account’ and then the ‘Integration’ tab. Choose ‘Harvest’ and paste the identifier into the text field that appears. Click ‘Update’ - you’ll now see an authorization screen from Harvest asking if you want to give Projector permission to access your Harvest account. Click ‘Approve’.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;You’re almost there! For each project that you want to have Projector synchronize with Harvest, go to your project settings (click the gear icon in the left sidebar) and choose the corresponding Harvest project. Harvest also requires that a task be used for any logged time, so select the appropriate task for your project.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Once you save your project settings, anytime you start a task we’ll create a running timer in Harvest with the description set to your task name. Stopping a task stops the timer. It’s that easy.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;If you’re a Harvest user, you can track all the time you spent developing a project automatically with Harvest. Come invoice time, it’s as simple as generating an invoice from the hours you’ve logged within Projector.&lt;/span&gt;&lt;/p&gt;</description><link>http://projectorapp.tumblr.com/post/18749115972</link><guid>http://projectorapp.tumblr.com/post/18749115972</guid><pubDate>Sun, 04 Mar 2012 16:26:00 -0500</pubDate><category>time tracking</category><category>harvest</category></item><item><title>Building Better Clients: 3 ways to make your expectations known</title><description>&lt;p&gt;&lt;span&gt;Making &lt;em&gt;my&lt;/em&gt; expectations known? Most freelancers tend to think that as hired guns, it’s not our job to set expectations. Instead, we work within &lt;em&gt;their&lt;/em&gt; expectations. We’ll be code complete by a certain date. We’re going to be developing X, Y and Z features. We’ll throw in a month of maintenance, free of charge.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;But like any contract, it takes two. In order for you to fulfill your end of the deal, your clients need to do more than sit back and dream of glory and riches.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I’ve worked on probably three dozen or so projects. It’s hard as hell to play hardball with clients, especially when your rent payment depends on that next invoice being paid. For me, I always felt that because someone was paying me - yes, me! - money, I was obliged to be their temporary slave. They ask me to jump, I ask them how high.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;I’m a soft spoken, fear-of-confrontation kind of guy. There’s nothing that makes me reach for the Advil bottle more than the “I have some concerns. Call me.” emails I’ve received in the past. I’m also big on trying to reverse engineer people’s psyches, so I spent some time recently trying to figure out why this kept happening. And then it clicked.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;It’s not about me!&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;A lot of client concerns usually stem from fear. Is this thing going to work? Am I blowing my savings? Wah-wah-wah-wah-wah. And when things aren’t looking up, they love bitching at their development team. &lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;Doing client work is a lot like dating. It’s so great when all is good. And the second anyone starts doubting or fearing, you’re kicked to the couch.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;“Pay your bills”&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;99% of client problems have to do with money. Your contracts with clients are bi-directional: The value they receive is the work you produce for them. The value you receive is cash. The moment this contract is violated, the offended party needs to take action.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;If I’m not paid on time, I stop work. Immediately. Need a quick fix? Pay your bill, then we’ll talk. I also made sure my agreement states that I OWN ALL THE WORK UNTIL I’M PAID. If an invoice isn’t paid, revert their website to what it looked like before the invoice-in-question. Being able to tag invoice dates in git is &lt;em&gt;awesome&lt;/em&gt;.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I give people one shot. If they are delinquent, I demand prepay for all future work. It makes sense - they can’t be trusted to pay on time any longer.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Oh yeah, and get a retainer before you start any new project.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;“Be available when I need you”&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Part of my job is to make sure I’m able to deliver things on time. Sometimes, I’m held back by a lack of information or because I need account information for an external API. But I can also be held back by long feedback loops. If your client isn’t available to verify and vet the work you deliver ASAP, then if and when there are changes, it’s going to take longer to backtrack and make any adjustments.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;When your client takes too long to get back to you, your timeline (and budget) suffers. This kindles the flame for an eventual end-of-project explosion of anger, even though you’re not to blame.&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;I’m so stuck up on making sure my team and I aren’t set back that we built into Projector, our project management app, a feature that will yell and scream &lt;em&gt;every day &lt;/em&gt;until the deliverables you need tested or the information you need is complete.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;&lt;strong&gt;“I can’t read your mind”&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I often think that clients think I’m able to perform a Vulcan mind-meld and know exactly what they want and need. And this is another pain point, as often times my understanding of a feature and a clients can be radically different.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;Everyone screams Agile, but most clients still operate in a fixed bid mentality. And quite frankly, &lt;em&gt;I get it&lt;/em&gt;. I don’t want my car salesman to be “agile”. I want to know exactly how much I’m going to pay, because these things called budgets exist.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I’ve started emphasizing from the outset that I will be as flexible and accommodating as possible, but that adding stuff costs extra money (this should be common sense). I also let them know that I’m probably not seeing eye-to-eye with them about what they need built. &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;I once had a client who wanted users to be able to join groups. Fair enough, we’ll put a ‘Join Group’ or ‘Leave Group’ link on the group pages. While developing the feature, apparently he wanted it to work like LinkedIn groups - some groups are invite only, some require a moderator to accept or reject pending memberships, and so on. Wow, talk about wanting a Lexus for the price of a Toyota!&lt;/span&gt; &lt;/p&gt;
&lt;p&gt;&lt;span&gt;This is one reason I don’t do fixed bid. Clients will &lt;em&gt;always&lt;/em&gt; want the most elaborate features when the price is constant. Alternatively, I could have probably put together a very detailed software requirements spec in the estimation process, but I’d lose hundreds of hours (and thousands of dollars) doing that.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;When estimating, ballpark everything. There’s no way you know exactly what your future client is thinking, and let her know that you’ve been bit in the past with the “Toyota vs. Lexus” problem. You understand their budget constraints, but put them in the drivers seat. It’s up to them to prioritize accordingly and build the right features. And you have no problem estimating granular features, but you aren’t going to estimate “Message Board”.&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;You can also put together a detailed spec, wireframes, and so on, which will allow you to get a better understanding of what they need and maybe even a better estimate. The resulting material is &lt;em&gt;extremely valuable&lt;/em&gt; for the client, so be sure to charge them for it. Don’t waste too much time estimating into oblivion!&lt;/span&gt;&lt;/p&gt;
&lt;div&gt;&lt;span&gt;&lt;br/&gt;&lt;/span&gt;&lt;/div&gt;</description><link>http://projectorapp.tumblr.com/post/14774393002</link><guid>http://projectorapp.tumblr.com/post/14774393002</guid><pubDate>Sun, 25 Dec 2011 14:22:00 -0500</pubDate></item><item><title>Building reuseable interfaces with Backbone.js</title><description>&lt;p&gt;&lt;p class="p1"&gt;&lt;img alt="Popover view in Projector" height="246" src="http://dl.dropbox.com/u/2205912/projector/popover.png" width="640"/&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;span class="s1"&gt;For the last few months I’ve been working on &lt;a href="http://projectorapp.com" target="_blank"&gt;Projector&lt;/a&gt;, my first large scale &lt;a href="http://documentcloud.github.com/backbone/" target="_blank"&gt;Backbone&lt;/a&gt; project. I have to admit: I’m in love with Backbone.View. I’m able to create a view class, add in some business logic, effortlessly attach event handlers to elements within that view, and attach an instance of that view to an element on the page.&lt;/span&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;span class="s1"&gt;I wanted something like an iPad popover for the “Add Story” interface. After failing to find what I was looking for as a jQuery plugin, I figured I’d just write my own. But then I thought about what I was about to do: Define a new function that would take an element, setup some click handlers, position the popover where I need it, and show or hide the popover. The same foundational work I’m doing all the time in my Backbone views! I also knew that this wouldn’t be the only place in the app that I’d want a popover.&lt;/span&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;span class="s1"&gt;Going the Backbone.View route would make manually managing my popovers after they were created a lot easier. jQuery plugins typically have you call the function you need modified &lt;em&gt;again &lt;/em&gt;against your elements, and supply a string argument signifying what you want changed. For instance, if I wanted to disable a jQuery Draggable element after creating it, I’d need to call: $( &amp;#8220;.selector&amp;#8221; ).draggable( &amp;#8220;option&amp;#8221;, &amp;#8220;disabled&amp;#8221;, true ). &lt;/span&gt;I’d much prefer just calling disable() on a draggable’s view instance.&lt;/p&gt;
&lt;p class="p1"&gt;&lt;strong&gt;&lt;span class="s1"&gt;Defining the base class&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;span class="s1"&gt;The base class had to do the following:&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;&lt;li class="li1"&gt;&lt;span class="s1"&gt;Initialize with a reference element (where to position the popover)&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;Render a wrapping element that creates the floating element and the arrow pointing to the reference element&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;Render the template of inherited view inside the wrapping element&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;Respond to toggle(), show() and hide()&lt;/span&gt;&lt;/li&gt;
&lt;li class="li1"&gt;&lt;span class="s1"&gt;Directly position the popover and the arrow under the reference element&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p class="p1"&gt;&lt;span class="s1"&gt;Backbone views are initialized with a JSON object that usually contains an element to attach to (el) and a model instance. The popover doesn’t care about either of these. It creates an element for you and doesn’t depend on any model. Your inherited classes, however, might want a model reference.&lt;/span&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;span class="s1"&gt;The popover’s initialize function remembers the reference element that was supplied and calls an internal _render() function, which renders the wrapping element and then calls render(), which the subclass should define. The internal render method sets this.content to be the content area of the view’s element - I don’t want subclasses to touch the wrapping elements.&lt;/span&gt;&lt;/p&gt;
&lt;p class="p2"&gt;&lt;span class="s1"&gt;&lt;/span&gt;&lt;strong&gt;Using it&lt;/strong&gt;&lt;/p&gt;
&lt;p class="p1"&gt;&lt;span class="s1"&gt;To use the popover, a parent view instantiates the popover during its initialization, and then calls toggle() whenever the click event on the reference element is fired.&lt;/span&gt;&lt;/p&gt;
&lt;script src="https://gist.github.com/1506555.js?file=gistfile1.coffee"&gt;&lt;/script&gt;&lt;/p&gt;</description><link>http://projectorapp.tumblr.com/post/14564134212</link><guid>http://projectorapp.tumblr.com/post/14564134212</guid><pubDate>Wed, 21 Dec 2011 10:09:00 -0500</pubDate></item></channel></rss>
