Scheduling Client Projects

scheduling client projects
One topic that comes up a lot when discussing running a small business or freelancing is scheduling. It can be really hard to accurately judge capacity and keep track of scheduled projects, not to mention projecting when you’ll have openings for future projects.

I’ve looked at a bunch of apps and systems for handling scheduling for my business but they tend to either be too granular for me (I don’t need to see each day individually for this kind of project scheduling), and/or they have too many other features that I don’t need but that increase the cost of the app or tool.

Instead, I’ve been using the same Google spreadsheet system for quite awhile now and it looks like it’s here to stay. Here’s what it looks like:

scheduling spreadsheet

Click to enlarge

This system is most similar to Gantt charts, I think, but all the Gantt charts I’ve ever used are day-by-day rather than week-by-week, which I prefer.

As you can see, I’ve got one column for each week. I add as many columns as I need for currently scheduled projects and then a few more empty weeks after (so that I can project future project availability and keep an eye on upcoming holidays or vacations).

There is a row for each project “slot.” I have more than one row for myself (usually I have a few, depending on how heavily I want to schedule myself), and then one for each person on my team. There’s also a row just for updates or tweaks for existing clients (those small things that come up and that we try to fit in around our main project schedule).

When I get a new inquiry, I check this spreadsheet to see when the next empty space is and that’s how I determine availability. Once I’m fairly certain a project is going to move forward, I put it on the spreadsheet in italics, with the first week of the project in bold. The bold helps me keep track of how many projects are starting in any given week – I generally try to stagger them a bit.

I use as many cells (weeks) as I think the project will take, sometimes adding in some buffer, especially around holidays. You can see in the screenshot that I also block off holiday weeks, typically the whole week even if I’m planning to work part of the week, which is another way of adding buffer time to my schedule.

Once a deposit has been paid, the italics get taken off, which means we’ve confirmed that slot for that project (things in italics are tentative and subject to change).

There’s nothing especially high tech about this solution, but it’s nice for a few reasons:

  1. It’s pretty easy to see next availability at a glance
  2. It’s also easy to see which projects are coming up soon so that we can touch base with those designers to make sure everything is on track
  3. If we need to move projects around due to delays, we can cut and paste blocks of cells to do that
  4. Brianne (my invaluable business assistant) and I can leave each other notes and comments on the cells
  5. Since it’s a Google spreadsheet, I can access the schedule from anywhere and I can share it with Brianne

I’d be very curious to hear of other systems people use for their scheduling!

Update to Xcode and Git Detached Head

Mac Updates to Xcode and Command LIne Tools

The culprits

I ran the updates shown above to Xcode and the Command Line Tools this morning and found that Git wasn’t working as expected (I tried to push a commit and got a notice about a “detached HEAD” but couldn’t get anything to work to fix it). It took me longer than it should have to realize the updates were related to this issue, so hopefully I can save someone else the trouble with this post.

The problem is that you’ve got to accept the terms of service for the updated version of Xcode before it will complete the installation but my computer didn’t give me any prompts about this (or any notice that the installation was incomplete after the update installed via the App Store Updates screen).

To solve this open up Xcode, accept the terms, and follow any additional installation prompts. Once it’s all installed everything will go right back to normal.

Marking Posts as New in WordPress

I was updating my bookmarks page and wanted a way to indicate the stuff that I’d added recently, which led me to thinking about how to identify posts from a particular timeframe.

The Question

How can I mark recent posts based on a particular timeframe?

The Result

I considered a couple of options (listed below) and ended up with a fairly simple solution using relative time, something WordPress has built-in. On the front-end, it just adds a little clock icon next to the title of any resource added within the last 30 days:

new resource indicator

Potential Solutions

My first thought was that I could use PHP to check whether the post date was within a certain range.

1. Compare Year and Month

I was thinking maybe I’d check the post year against the current year, then if it matched I’d check against the current month. However, I dismissed that before I got past about 20 characters of code because I realized that it would throw off the time frame of the results depending on where in the month we are. Oh well, we all have bad ideas sometimes.

2. Date Calculations

Then I was thinking I’d use PHP to check the date against a relative time frame, e.g. the last 30 days. Something like the reverse of this Stack Overflow question and solution.

That would work, but then I remembered that WordPress has relative post date built in, where you can display the time as “1 day ago” or “30 minutes ago” using the function human_diff_time (function reference). Hooray, even better!

3. Using Relative Time

So then I was thinking, with that relative time I just need to check and see if we’re in the right time frames to be what I’d consider “recent.” The numerical values returned won’t be useful but the words are definitely useful. I double checked when the transition in words happens by looking at the core code underneath that function. I was able to confirm that anything with a relative time in minutes, hours or days has been posted in the last 30 days, and I’d consider that recent.

Full Solution

Here’s the full solution I ended up with (limited to just the template code within the loop, since the rest of the template is irrelevant to the question):

<?php while ( $the_query->have_posts() ) : $the_query->the_post(); ?>
    <?php
        $postdate = human_time_diff( get_the_time('U'), current_time('timestamp') ); // get the post date in relative time
        $recentvals = array('min','mins','hour','hours','day','days'); // the values I consider "recent"
    ?>                          
    <li class="filterable">
        <a href="<?php the_field('url'); ?>">
            <span class="project-title"><?php the_title(); ?><?php foreach ( $recentvals as $recentval ) : if ( strpos($postdate, $recentval) !== FALSE) : echo ' <i class="fa fa-clock-o"></i><span style="display:none;">new</span>'; endif; endforeach; ?></span>
        </a>
        <span class="small"><?php the_field('description'); ?></span>
    </li>
<?php endwhile; ?>

The Breakdown

Let’s take a closer look piece by piece at what this code does:

Set Variables

First up, there are two pieces of information I want to use in my comparison. That’s this part of the code:

<?php
        $postdate = human_time_diff( get_the_time('U'), current_time('timestamp') ); // get the post date in relative time
        $recentvals = array('min','mins','hour','hours','day','days'); // the values I consider "recent"
    ?>

There are two variables set up here:

  1. The post’s relative publication date, meaning how long ago it was posted in words (e.g. “20 mins” or “2 days”)
  2. The time frames I want to include as “recent,” using the words provided by that relative time function (options are: “mins,” “hours”, “days,” “weeks,” “months,” and “years” and the singular of each of those)

For the first, I just used WordPress’s built-in function, straight off the Codex page except I’m assigning it to a variable rather than echoing it (displaying it) on the page.

For the second, I have created an array of the words I’ll accept as “recent,” using both the singular and plural forms. I’m actually not sure if it’s possible to just use the singular and I don’t feel like testing it so I’ve just used both for safety’s sake.

Compare the Two

Next, I need to figure out whether the current post date for each post contains any of the words in my array. I referenced this thread on Stack Overflow for this code:

<?php 
foreach ( $recentvals as $recentval ) : 
    if ( strpos($postdate, $recentval) !== FALSE) : 
        echo ' <i class="fa fa-clock-o"></i><span style="display:none;">new</span>'; 
    endif; 
endforeach; 
?>

This runs through each of the allowed time frame words in my array and compares them against the post date. If one comes up as a match, it prints out the code in the echo line.

Show the Icon, Plus Search

The printed HTML from that snippet is:

<i class="fa fa-clock-o"></i><span style="display:none;">new</span>

That creates the Font Awesome clock icon along with a hidden span (I know, I know, lazy inline CSS). The hidden span is there so that it’s possible to use the in-page “search” function to pull up the new posts.

Implementation Keys

If you’re going to implement this yourself, the key things to remember are:

  1. The code needs to be within the loop, including the bit where you set the variables.
  2. You’ll need to determine which words constitute “recent” and update your array accordingly.
  3. You’ll likely also need to update your icon/ display HTML to fit your purposes (whether it’s just displaying text or adding in an image or another icon font or whatever).

Business & Web Development Summer Reading List

Summer Reading List
While the summertime means more time spent with my family, away from the computer, I’ve been trying to keep on top of my blog and article-ready. I just skim most things that cross my Twitter and RSS feeds, but the articles in my “to read” list are things that looked good enough at first glance that I want to hold on to them for a deeper read or for future reference. Here they are, split by the topic:

New Technology

Web development is constantly evolving, so a lot of my reading is to keep up with the new stuff coming out across the languages and technologies I use.

Accessibility

I’m eager to learn more about accessibility and to incorporate more best practices into the sites I build so I’ve been saving references right and left.

Specific Techniques

These articles cover techniques I haven’t used yet but want to for various projects/ concepts/ ideas.

Business

And last, but not least, I am constantly ruminating on business topics. These articles cover things I’m thinking about or want to learn more about:


I also share articles of interest to me on the regular over on Twitter. If you’ve got suggestions/ tips on great things you’ve read lately (or have on your to-read list), put ‘em in the comments!

Problem Solving Threaded Comments in Shopify Blogs

Problem Solving Threaded Comments in Shopify
I recently had a potential client ask for threaded comments (where replies are shown below the original comment) in a Shopify blog, which is not a feature the platform offers natively. It got me thinking about how we might be able to make it work.

I thought it’d be interesting to share the thought process I went through when approaching this problem, since one of the key components of a web developer’s job is tackling implementation problems like this but the actual problem solving is not something we talk about as much as we probably should.

The Problem

Shopify blog comments are a single level, with no reply hierarchy. WordPress does offer threaded comments, and it’s what many blogs use so that’s become a familiar feature. Beyond familiarity, threaded comments are excellent for building community and generating a real conversation with readers.

How can we get comment replies in Shopify to be visually linked to the original comment so as to show the conversation?

The Thought Process

The first set of questions that came up when I started thinking about this problem:

  • Is there a way to have a reply link on the comments like you’d see on WordPress so anyone can reply to any top level comment (we’re only aiming for one level of replies for now)?
  • If not, is there a way to have the site owner able to reply to comments, even if it isn’t something the general public is able to do?

A Potential HTML & jQuery End Model

My initial thought was that we could associate replies to the original comment in the thread using the comment id, which is something Shopify stores for each comment (accessed via the liquid tag {{ comment.id }}).

My thought was that if we put the parent comment ID in the markup for both the parent comment and any reply comments, we could then use jQuery to move the replies up just under the parent (using append() or something similar).

This would look something like this:

<div id="comment-1">
    I'm the parent comment.
</div>
<div id="comment-2">
    I'm an unrelated comment.
</div>
<div id="comment-3" class="comment-1">
    I'm a response to the first comment.
</div>
<div id="comment-4" class="comment-1">
    I'm another reply to the first comment.
</div>

With that structure, we could use jQuery to find all the comments with the class comment-1 and then move them after the comment with the matching ID.

Getting the Comment ID in the Markup

The problem now is that we’ve got to associate a different comment’s ID with the replies somehow. Some ways this could potentially work (depending on Shopify’s system constraints):

  1. We include a hidden field in the comment form that contains the parent ID (probably put there by jQuery when the reply link is clicked?) and that pushes that information to the comment object or to a metafield. Then we pull that out from the comment object in the class.
  2. Only the shop owner can submit replies, using the backend to write them and including the parent comment ID as a metafield on their comments. We use that metafield for the class.
  3. Only the shop owner can submit replies, including the parent comment ID in the body of their comment in a way that we can strip out and use in jQuery but that doesn’t look terrible if the jQuery fails for some reason (javascript off, future bug, etc.).
  4. The comment ID gets submitted in the body of the comment, put there somehow when the reply button is clicked, and in a way that we can strip it out and use it but it doesn’t look terrible if jQuery fails (maybe invisible or on submit).

That list makes it seems like those ideas all came up together, but really it was a little more linear. The first one was my ideal case, but was quickly shot down because the comment form can’t be modified to submit information that way (womp womp).

That led me to think about the second idea, since for a lot of content types in Shopify we can add custom metafields in the admin. Unfortunately, it seems as though metafields are not a thing for comments (womp womp again).

Those two dead ends lead me to the final two choices, where we’re submitting the values via the field we do have (which is pretty much just the comment content area). The fourth is likely preferable as it’s the most flexible and the most automated (less chance of things breaking), so that’s what we’ll be tackling.

Further Considerations

Did you read this far hoping for a solution? Sorry, I don’t have one for you yet. As of this writing we haven’t tackled the problem any further, but if/ when we do I’ll be sure to write it up.

For now here the things on my mind for the next phase of tackling this problem:

  • How do I put information from my parent content markup (the ID) into the comment textarea on a link click? (Here’s a Stack Overflow thread that may help)
  • What does that information in the textarea look like, if it’s even visible? How can I make sure it gets submitted without getting accidentally edited first?
  • How does that information get parsed in the printed comment so that it isn’t in the comment content and is in the markup.