Blogging Tip: iCal Post Feeds

If you’re a calendar person like I am (I use both a paper calendar and synced online calendars), you may find it helpful to have your blog posts show up across whatever digital calendar system you use.

Here’s how mine looks in Apple’s Calendar app, with only the blog calendar feed visible:

blog ical feed month view

Click to enlarge

It’s easy to set this up by generating an iCal feed from your WordPress site, then adding that to your calendar software.

Generating Your iCal Feed

There’s a great plugin that generates iCal feeds. I’ve used it for awhile now and found it to be stable, and the developer is responsive to feature requests (always nice).


It’s basically plug-and-play – install and activate the plugin, and then head to the settings page to grab your iCal feed URL.

As you can see in the (partially redacted) screenshot below, the plugin provides you with a bunch of different feeds to choose from:

ical feed plugin settings

The public URL contains all posts that are already published, but if you want to also include future (scheduled) posts you can do that by setting a secret parameter value. Your new secret feed URL is then provided for you lower on the page. That’s what I use, since I want to see my upcoming scheduled posts on my calendar.

There’s a setting for how long each calendar “event” should be, which is something I asked the developer to add. I like to have posts on my calendar but I don’t want them taking up a huge chunk of my calendar space so I’ve got mine set to 5 minutes. The time on the calendar matches the publication time for the post (and the calendar item includes the post URL):

ical post detail

You can also grab individual iCal feeds for each category, or for a custom selection of categories:

ical feed multiple categories

I am not really sure why you’d want to separate out your categories like that, unless you are really insane about your color coding, but it’s an option.

Using the Feeds

Most digital calendar apps make it pretty easy to add an iCal/ .ics feed.

Apple Calendar

In Calendar, you go File > New Calendar Subscription, then enter the URL:

add feed to Calendar app

Google Calendar

In a Google Calendar, you go to Other Calendars in the sidebar, then click the dropdown icon and select “Add by URL” then enter the calendar URL:

Google calendar add feed

But why?

Having your blog posts show up on your calendar is definitely not a necessity by any stretch of the imagination, but it’s one of those nice little things that may make your life a little easier.

For me, I find it helpful to mentally plan social media efforts out if I can see my whole week in one view, from client work and launches to holidays, to days I’m particularly busy, to my upcoming posts on the calendar (they’re in yellow in this weekly view, which is what I usually look at):

Calendar weekly view

Click to enlarge

Conversely, I also find it help it helpful to have my whole calendar in view as I plan out and schedule future posts. It helps me post things relevant to upcoming holidays, for example (as a hazard of self-employment, I tend to forget many federal holidays).

And, to tell you the truth, I also just kind of enjoy seeing my posts on there. Enjoyment matters!

Neatly Polished Update, with Sample Lesson

Neatly Polished is clear, friendly, in-depth online front-end web development classes

It has been a long time coming (my goodness, those lessons took a lot longer to write than I expected), but I’m happy to say that all 26+ lessons in my Neatly Polished course on WordPress Theme Development are finally live.

In case you aren’t familiar with this project, Neatly Polished is a subscription-model site I created for more in-depth tutorials and lessons than are really reasonable to provide for free via this blog. There are the lessons, plus a support forum where I answer questions and discuss the lessons (and other stuff, sometimes) with participants.

The first full “course” is on WordPress Theme Development, and basically walks through all the files you’d use in a WordPress theme, along with the various theme components and some workflow tips throughout. You can check out the entire course outline, along with a single full sample lesson, on page templates.

Subscriptions run $29 for a monthly membership and $79 for a quarterly membership, and include all current and future content for the life of the membership.

Future plans for the site include a similar course on Shopify theme development, as well as mini-courses on things like PHP basics, HTML/ CSS layout modules, and other TBD topics. You can keep up to date with what’s going on over there (since I don’t post here about everything) via Twitter and/or by signing up for the Neatly Polished email list.

I’m pretty excited about this project, in part because of the fabulous feedback I’ve gotten that has both helped me keep improving the lessons over time, and also has just made me feel even more sure that sharing what I know like this is the right thing to be doing.

I’ll leave you with some of the awesome things members have said about the lessons and program:

“Awesome lesson! I have used many fabulous tutorials (free and paid) on WordPress theme development, but find that even though the information is valuable , it is not “streamlined” as well as yours.”

Very specific. The checklist was clutch. I was missing 3 things (due to my horrible skimming skills and my antsy pants that are so excited to be learning this stuff). With the checklist, I was able to make sure that I didn’t miss a beat!”

“Great! Can’t believe I picked this up so quickly. Really appreciate your simple and easy to follow instructions.”

If you’d like to register, you can do so here.

Top Hidden Costs of Website Projects

7 Common (But Easily Overlooked) Website Costs

Over a couple of years of client projects, one thing I’ve learned is that there are a lot of costs for website that site owners often don’t know to anticipate or plan for. It is not fun being the bearer of unexpected news about additional costs, so I try to be pretty up front about these potential “extra” costs at the contract and invoicing stage of the project.

There are seven main costs that many clients may not know about (especially if it’s their first big web project):

1. Hosting (Especially Quality Hosting)

While most clients know that they’ll have to pay for hosting of some sort, many don’t realize that quality business-level hosting can be pricey. While inexpensive shared hosting may be okay for some sites, there are definite downsides to cut-rate hosting (everything from reliability to security issues to variable customer service quality).

Once you move beyond inexpensive shared hosting, the cost for hosting can vary wildly and tends to increase pretty rapidly in price. This can be a real surprise for clients, and is something worth discussing early in the process. It helps to be able to discuss the benefits of more premium hosting services.

Typical Cost: $3-6/ month for inexpensive shared hosting, $15/ month and up for premium hosting

2. Domain Registration

If you’ve been working with websites for awhile, it’s easy to forget that the concepts of domain registration versus hosting are not actually that obvious to the general internet user. It’s a good idea to check in early with clients to make sure they’ve got a domain registered, and you’ll also want to help them understand the cost for registration.

Some things clients may not know about domain registration include:

  • It’s a recurring (usually yearly) cost
  • Some (but not all) hosting providers include a year or more of free domain registration with a new plan
  • There are add-on services needed along with the domain for things like privacy or added security
  • The domain can be registered separately from the hosting, if desired

I’ve found that clients also appreciate tips on registering similar domains, such as the .org version of the primary domain or a common misspelling.

Typical Cost: starts at about $10/ year per domain registration alone (more for high-value domains and certain TLDs)

3. Email Accounts

Some hosting providers include email of some sort (forwarding accounts, or even email inboxes) with hosting plans, others do not. Since many people are used to free personal email accounts, it may not occur to them that business-class email often comes at a cost and that the cost may be per-email-address.

I typically recommend Google Apps for Work as a great business-class email option, and that service runs $5/ inbox/ month, or $50/ inbox/ year.

Typical Cost: $50 per inbox per year

4. Licenses

It’s not uncommon for clients to believe that any and all functionalities and design elements within a website are part of the overall project cost, but I tend to separate out license fees from my rates unless I already have an unlimited developer license for a particular purpose.

One of the reasons I do it this way is that I prefer to have licenses for each project in the client’s name. This is especially true for things with recurring costs like subscription font services, but is also true for one-off licenses that require a new license for each site.

Font Licenses

I’ve written at length on web fonts and licensing, but those are not topics that the average site owner is going to know a lot about.

Ideally, font licensing comes up in the design phase of a project but I like to cover myself by also bringing it up in my invoices and contracts. That way I don’t have to be the one telling the client late in the project that the fonts they’ve fallen in love with are going to cost them a lot of money.

Typical Cost: varies widely from free to hundreds of dollars per year depending on font(s) chosen, traffic levels, etc.

Software Licenses

Beyond font licensing, some jQuery plugins, WordPress plugins, and Shopify apps come at added cost. For example, MagicZoom is a very popular jQuery plugin for e-commerce product zoom functionality, and it has a per-site cost unless you’ve got a developer license you’re using for all your clients.

This is another place where it’s a good idea to talk early about special functionality requirements and for the designer and developer to be on the same page about functionality that is “free” (or built into a regular scope of work) versus functionality that may have associated extra licensing costs.

Typical Cost: varies – jQuery plugins tend to run $30-100 for a one-time license, premium WordPress plugins and Shopify apps often have yearly or monthly recurring costs

5. Security Provisions

Depending on the type of site and the setup, there may be added security needs.

SSL and Dedicated IPs

If you’re running any kind of secure content through your site, you’ll likely need an SSL certificate, which is an added yearly cost for most hosting accounts. SSL also requires a dedicated IP address, another added cost in some cases (especially on shared hosting).

Typical Cost: on one shared host, a dedicated IP address is just over $3 per month on top of a regular hosting plan; SSL certificates tend to run $20-50 per year up to $200+ for wildcard coverage

Monitoring Services

Even if you’re not storing or using sensitive information, it can be helpful to have security monitoring on your site. For WordPress, this typically looks like third-party services that keep an eye out for hacked sites or for necessary updates/ upgrades. Some clients may also want ongoing help with their site updates, which is a long-term cost that will need to be negotiated.

Typical Cost: leading provider Sucuri has an antivirus plan runs $89.99/ year for a single site

6. Backup/ Restore

This is another feature that depends on the site and hosting provider, but that sometimes incurs extra costs. Regular automated backups and a one-click restore are one of the reasons I really like WP Engine hosting [affiliate link], but other hosting providers may not include those things standard, or may only allow access to parts of the backups.

Sometimes you can add better backup systems through a hosting provider for an additional cost, or there are third-party tools and services such as VaultPress and BackupBuddy.

Typical Cost: VaultPress runs $55/ year for their “Lite” backup/ restore plan

7. SPAM Filtering (WordPress)

For WordPress blogs, in particular, there’s typically a need for additional SPAM filtering. While there are some free options out there, I prefer using Akismet as it’s a tried-and-true provider that does a good job filtering out SPAM with few false positives. You can use it for free for a personal blog, but it does have a fee for commercial sites.

Typical Cost: Akismet is $5/ month

Total Cost

Looking at a “typical” WordPress business site that includes a blog a reasonable cost breakdown might be something like:

Shared Hosting:

Since it’s a lower price point, shared hosting is often a good place for a new business to start. The downsides are usually reliability and service/ support, and as traffic grows or as storage needs increase, shared hosting may become less of a viable option.

Service Yearly Cost
Domain Registration $10
Whois Privacy $3
Hosting $60
Email (provided by hosting) $0
Sucuri Monitoring $90
VaultPress Backup Bundle (includes Akismet) $99
Total: $262 (plus any one-time licensing fees)

Premium Hosting:

While clearly more expensive, premium hosting can be worth the price for ease of use, uptime and site speed, and quality of customer service. Premium hosting providers also often optimize for things like traffic spikes and dedicated WordPress hosting providers have WordPress-specific features that can save site owners time.

Service Yearly Cost
Domain Registration $10
Whois Privacy $3
WP Engine (“Personal” Plan*) $348
Email $50
Akismet $60
Total: $471 (plus any one-time licensing fees)

* The personal plan is the lowest plan offered by WP Engine and is based on the number of visits per month, despite the name it can be used for business sites.

There you have it – an overview of some of the most common website project costs along with some very approximate numbers for rough budgeting purposes. I’m sure I’m missing something(s), so if you’ve got something that pops up a lot in your projects that I haven’t mentioned, post it in a comment.

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(); ?>
        $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>
        <span class="small"><?php the_field('description'); ?></span>
<?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:

        $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:

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

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).

Display Top WordPress Posts by Page Views

A recent client project has a component that shows top posts by views, which took some figuring out. WordPress doesn’t log views by post out of the box, but the Jetpack plugin does so that’s what we used as our data set. There are a couple Stack Overflow threads that talk about querying the posts by view count using Jetpack but none of them have the full code necessary so I thought it’d be useful to share how I did it.

Posts by views carousel

the end result

The post display is done using a custom loop via WP_Query, and the carousel in this particular example is done with bxSlider, which I use all the time for sliders and carousels.

Full Template Code

Here’s the full code for that area, which would go in the template file for the particular page or area you’re displaying the posts within. In this case, they’re on every page in the header so they’re in the theme’s header.php file.

The first and last lines are a conditional that checks for the stats function. If it returns false because the function isn’t there (e.g. if there’s no Jetpack installed) then nothing else will happen, preventing errors or other weirdness.

The Breakdown

Let’s run through the pieces of that snippet. (I won’t be covering the CSS and jQuery in this tutorial, since the focus is on getting the content to appear on the page, but let me know in the comments if you’d like to see a tutorial on carousels.)

Grab Top Posts’ IDs

The first few lines are getting the posts by views as registered by Jetpack:

The first line pulls up the top posts by views, using the last 21 days’ worth of data (that’s the first parameter in the array). The -1 value means that we are not limiting the number of posts returned. In the client project, I used custom fields for the number of days so that the client can change that if they’d like, and I also set a high but not unlimited value for the items returned since unlimited seems kind of unnecessary (the default is 100 if you omit that parameter entirely).

Set Custom Query Arguments

The remaining lines in that snippet create an array of post IDs for the posts returned by that first line, which is key because we need that array to plug into the post__in parameter for our query:

If you’ve ever built a custom loop using WP_Query, the above snippet will likely be familiar. It’s the arguments for our query, the first of which, post_type specifies that we want to pull only posts (the stats will return both posts and pages).

Major hat tip to Greg Rickaby for helping me level this up by adding a transient, which is essentially like a cookie and stores the query for a specified length of time, which speeds things up.

The other two parameters are post/ page specifics. First, post__in (that’s two underscores in there) specifies that we only want to return posts with IDs in that array we just built. Finally, posts_per_page limits the number of posts displayed on the page, overriding any other pagination you may have going on (from your regular loop settings, for example). I gave the client a setting for that value as well, so that she can control the number of posts in the carousel herself.

Create The Loop

Finally, the rest of the code is a standard WordPress loop structure:

In this construct, each item is wrapped in an <a> element (could just as well be a <div>) that links to the post permalink, and then the post thumbnail and title are displayed. I’ve arranged the markup so that I can have the title appear over the thumbnail on hover using CSS.

And there you have it, a snippet that returns top posts by views!