Tracking New Year’s Resolutions With a Custom WordPress App

Tracking New Year’s Resolutions With a Custom WordPress App

It’s that time of year again! Time to commit to doing things you’ve always wanted to do, to taking up new habits for self-improvement and defining what you want to be in the New Year.

New Year’s resolutions are an annual tradition for some, but they don’t always have to be promises to yourself that you break. If you want a way to keep score, WordPress can be the perfect companion to help you stay on track and smash your goals.

In today’s post, I’m going to show you how to create a simple goal tracking app that supports one-time goals, habit-type goals, a resolution diary and also produces some statistics using a widget.

Let’s get started!

Setting Up Goals

The idea behind this New Year’s project is straight forward: I want to measure the activity level of my goals based on the number of posts I write about them. Pretty simple, right? The easiest way to do this is to create goals as categories and then assign those categories to posts.

First, the goals. Here are some of mine, which I’ve added as categories with descriptions to WordPress:

Goals as categories

I used two top level categories, “Habits” and “One Time,” to make distinguishing between the two different types of goals easy.

I also added a special top level category named “Habit Status” with two sub-categories: Incomplete and Complete. The plan is to use these sub-categories to indicate the success or failure of a habit. For example, one of my goals is to drink more water. I’ve decided to start with a minimum of four glasses a day. I’ll add the number of glasses every day and if it is more than or equal to four I’ll use the “Complete” category otherwise I’ll use the “Incomplete” category.

We could detect this automatically with some code but all our habits will have different success or failure criteria, which would make it tricky. Manually determining how goals progress is easier.

Adding New Goal Entries

If you just want to take it this far, you’re done! You should now have a system of categories that will help you sort through your resolutions and track your progress. You can start adding new posts to your site skip the rest of this tutorial.

To add new entries, create a post as you normally would and assign it a goal from the “Habits” or “One Timers” categories. If you’ve assigned a habit, make sure to indicate if it is a “Complete” or “Incomplete” entry.

Some entries in our goal tracker
Some entries in our goal tracker

If you want to take your goal tracking a step further, read on.

Getting Started With Modifications

For the rest of this tutorial, we’ll be adding new features to an existing theme, modifying the backend and front-end views, adding options and all sorts of other bits and pieces.

Much of this should be placed in a plugin. Modifying a theme, however, calls for a child theme. To make things more manageable I’ve decided to put all the plugin functionality into a child theme as well.

Warning: this is not best practice! If you plan to implement any of the code below into a site that is not strictly for your personal use, please use a plugin and a child theme together. Any features you want to keep in place when you switch themes (admin post list modifications and post options, for example) needs to go into a plugin.

The theme I’ve chosen for this project is the default Twenty Fifteen theme since I want something nice and minimal.

Creating a Child Theme

Creating a child theme is a straightforward process, but if you’ve never set one up before it’s best you read our guide, How to Create a WordPress Child Theme.

But here’s a quick rundown: To create a child theme, add a folder in the main “themes” folder. I’ve named my folder goal-tracker. Create two files within this folder: style.css and functions.php. And then add this to your stylesheet:

In the functions file, we need to make sure the style of the parent theme is applied so we enqueue it like so:

Additionally, you can add a screenshot.png image so your child theme looks nice in the Appearance > Themes screen in the backend of your WordPress site. You can download the image I made below:

Theme image preview
Theme image preview

Thanks to Greg Rakozy for the great image. If you decided to create your own image, make sure to make it 880×660 to pass the theme requirements.

Modifying the Backend View

There are a few modifications we can make to the backend of WordPress that will not only make the goal interface cleaner, but will also make it easier to navigate.

The post list view (pictured at the top of this article) looks and works just fine, but there is some information I’d like to see that isn’t there and some information that is redundant doesn’t need to be displayed. For now, let’s get rid of the comments and the tag and author columns. Later on, we’ll add extra information to the post view as we add new options.

To modify the number of columns used in a post list, you need to use the manage_[post_type]_posts_columns hook, where [post_type] should be the actual post type you’re applying it to.

The hooked function passes an array of default columns. You can add to it or remove items – below, I’m removing the three columns – comments, tags and author – that we don’t need:

Our category names are also a bit long. Since we’ve removed some columns, there’s not plenty of space to display the names in full. So let’s add an admin stylesheet that gives more room to our categories.

Let’s write our styles first. Create a new file named post-list.css and save it in your child theme’s folder. Add the following code to the file:

All we need to do is enqueue this in the functions file. We’ll do this using the admin_enqueue_scripts hook, using the get_current_screen() function to help us attach it only to the post list screen:

The get_current_screen() function provides all sorts of useful information about our current page. Print it out and take a look! Make sure to call it after the admin_init hook is run, otherwise it won’t work.

At the end of all this, we should have a new post list view that looks like this:

Admin view modifications
Admin view modifications

Modifying the Front-End View

Right now our goals look quite nice but I want to make more modifications (of course!).

Before we get started making changes, here’s what posts should look like now on the front-end:

A post about our goal
A post about our goal

Initially, I want to remove the comments link. I also want to remove the “Incomplete” and “Complete” category names from displaying in posts and instead display a little icon instead of text.

The Twenty Fifteen theme uses a function called twentyfifteen_entry_meta() to output meta data. Since the theme’s developers wrapped it in a function_exists() call, you can overwrite this function simply by defining it in your child theme. Copy-paste this whole function from the inc/template-tags.php file in Twenty Fifteen to the functions file of your child theme.

Next, the very bottom of this function contains the code for the comment link. Remove the whole if block at the bottom.

The categories will require some more work but we can leave everything as is and get a filter to do our heavy lifting. Here’s how the whole twentyfifteen_entry_meta() should look:

Twenty Fifteen uses the get_the_category_list() function to retrieve a list of categories. If you look at the source code of this function in wp-includes/category-template.php you can see that a filter is run on the list of categories and is called the_category_list. It takes the list of categories as the first parameter and the post ID as the second. Let’s hook a function in there and remove the habit status:

Next, let’s re-add the habit status as a red or green indicator, depending on the status. First, I wrote a function that returns the status of a post. The final result of my get_habit_status() function is a term object, the status term:

We need to retrieve the parent term of habit statuses and then get all child terms of it. From there, we need to do a little array juggling. I created two new arrays, one contains just the IDs of the statuses, the other is essentially the same as before but the array keys are the term IDs.

We then need to grab the term IDs related to the post. The intersection of the $habit_status_ids and $categories array should give me habit statuses assigned to the post. We need to use the first status (it should be the only one) and look up the related term object in our $habit_list array and then return it.

Back in the twentyfifteen_entry_meta() function, I added a little snippet at the bottom:

I first grabbed the habit status. If the post doesn’t have a habit status the function always returns false, in which case we don’t output anything. Otherwise, a simple span with the class of habit-status-indicator plus a class derived from the slug is displayed. In our case we end up with indicators with the class of incomplete or complete.

All that remains doing is adding some CSS to style this. I chose to absolute position it to the left by adding the following to the stylesheet:

Our current habit post view
Our current habit post view

Displaying Stats With a Simple Widget

The best way to get a good overview of our habits is with statistics, and the best way to display statistics for WordPress is with a widget.

To get started, create a gt-stats.class.php file in your theme’s directory – this will hold our widget class. Add the following content into it:

This is the frame we’ll use. The constructor will give the widget its name, description and some other properties in the admin. The form() function will define the form used to add options to the widget, and the widget() function displays the widget on the front-end.

I’ll add a single option to the widget, the ability to add a title. In the display function I’ll grab all our statuses, go through them and display the post count for each. Here’s the full code for the widget class:

WordPress doesn’t know about this widget yet so we need to include the file and register the widget. I’ve done this in the functions file, like so:

And here’s what it looks like on the front-end:

Stats widget
Stats widget

Extra Options

You can add more data and fine tune your tracker with custom fields to it. If you’ve read some of my posts you know I’m a big fan of Advanced Custom Fields and I use this plugin for many applications. If you would like to add custom fields to your habits, I recommend reading Creating The Perfect WordPress Travel Blog or Creating A Customizable Post List Template. Both these articles have a ton of information on how to use ACF.

But let me show you a quick example. After you’ve installed Advanced Custom Fields you can create a field group named “Water Options.” Within that group, add a number field named “Glasses Today.” In the location options make sure to assign it to only posts that are assigned the “Drink More Water” category. This will keep your admin clean and you can assign different options to different goals.

ACF location options
ACF location options

I can now go to any post in that category and indicate how many glasses of water I have had.

Water options field
Water options field

This information is saved in the meta table, which means I can retrieve it pretty easily. Let’s add this to the entry footer using the twentyfifteen_entry_meta(). Add the following at the end of the function:

I also added a tiny tidbit of CSS to the stylesheet to make it look nice:

Finally, it should look something like the image below.

Custom field display
Custom field display

Smashing New Year’s Goals

The customizations we just covered are just the tip of the iceberg and you could do so much more to make this your own. You could more custom data, show that data in interesting ways inside posts themselves, use custom data to generate more elaborate statistics, modify the admin to show the custom data, and so much more!

I hope you all have a great New Year! I’ll be trying to learn even more about WordPress in 2016 and contribute as much as I can. How about you? Share your WordPress goals for the New Year in the comments below.