Demand-based blogging with WordPress and ConvertKit.

demand-based blogging

“Consistency is the key to blogging”, They told me. “And randomness is the spice of life.”

After my interview with They I sat down and crunched some numbers.

If my math is right, that means the key to having a spicy life blog is being consistently random. Or randomly consistent. (Feel free to ponder the difference between those two.)

And just like that, demand-based blogging was born. Or at least I couldn’t find anything similar in 47 seconds worth of Google queries, so I assume it didn’t previously exist.

The concept is simple. The writer sets a threshold of how much his or her audience needs to grow between each post. eg by 2% or by 15 subscribers. That number is automatically updated as each new subscriber hops on board. The number is made clearly visible on the site. And as soon as that number hits 0, writing commences.

Included for free with this new approach are three serious benefits:

  1. It’s fun. People are attracted to fun things.
  2. Without even being asked, readers are encouraged to share, because they’re not going to get any more content until that new subscriber count is reached.
  3. It makes writing more pleasant. Spending eight hours writing something that people aren’t to give a slug’s slime about is the worst. One might not write often with this method, but at least the writing will be desired.

And of course this is all automated. Because having to manually do anything sucks. This is (barely still) 2016. I’m not trying to do work.

There was some code involved in making this happen. I’m going to share that code with you. Maybe you’ll decide to implement this yourself one day. Or maybe you’ll decide to modify this to be way better. Both are encouraged.

To follow this guide you’ll need:

  • A WordPress site.
  • A ConvertKit account. That’s who I use for my newsletter emails. Because they’re awesome. But again, you could tweak this to work with any mail service that has a sufficient API.
  • jQuery. Though the JavaScript component is minimal. You could pretty easily adapt it to another framework or to vanilla JS.
  • A caching module. Doesn’t really matter which one. I used APC in this guide. You can change it to whatever you want.

All of this will be happening in your theme’s directory. Not /themes, but your specific theme. eg, mine is located at /wp-content/themes/patonpurpose/. Would this be better suited for a plugin? Maybe. If there’s demand I’ll make one.


Place this wherever you’d like your subscriber count info to show up.

<!-- This whole element will be replaced when 0 more subscribers are needed. -->
<p class="replace-with-goal-completion">
As soon as <strong class="replace-with-subscriber-count">-</strong> more <span class="people">people</span> join I'll write a new article.

The jQuery

url: "/wp-admin/admin-ajax.php?&action=how_many_more",    
type: "GET",
cache: false,
if(data == 0){
$('.replace-with-goal-completion').html("Woohoo! Enter your custom message here to let people know that a post is coming soon.");
if(data == 1){
//Because "1 people" sounds bad.


Add this to the bottom of your functions.php file. You need to change two things for this to work with your ConvertKit account. The things you need to change are noted in the code.

add_action('wp_ajax_how_many_more', 'get_number_of_subscribers_needed' );
add_action('wp_ajax_nopriv_how_many_more', 'get_number_of_subscribers_needed' );
function get_number_of_subscribers_needed() {
global $wpdb;
How many more ConvertKit subscribers do we need to acquire before we start writing our next post?
A quick rundown of the main variables in play:
$last_post_time: The timestamp of our most recent published post.
$previous_subscriber_count: The number of ConvertKit subscribers we had at the time of our last post.
$previous_subscriber_count_fetch_time: The time when we fetched $previous_subscriber_count.
$current_subscriber_count: The number of ConvertKit subscribers we have RIGHT NOW.
/* Things you NEED to edit. */
define("CONVERKIT_TAG_ID", CHANGE_THIS); //Because converkit does tags instead of lists.
/* Things you CAN edit if you want. */
define("DEMAND_GROWTH_RATE", .02); //Require 2% list growth before you post again.
define("MINIMUM_ABSOLUTE_DEMAND", 15); //In case the previous figure is too small.
define("CACHE_SECONDS", 240); //How often do you want this number to update?
/* DON'T EDIT ANYTHING BELOW HERE. Unless you want to. Then go for it! */
if(apc_exists('subscribers_needed')){ //if the response is already cached
echo apc_fetch('subscribers_needed');
//Retrieve items from cache if applicable.
//Get the time the previous subscriber count was fetched.
//Get the subscriber count at said previous time.
if($convertkit_cache = apc_fetch('convertkit_cache')){ 
$previous_subscriber_count_fetch_time = $convertkit_cache['previous_subscriber_count_fetch_time'];
$previous_subscriber_count = $convertkit_cache['previous_subscriber_count'];
$previous_subscriber_count_fetch_time = 0;
$previous_subscriber_count = 0;
//get the timestamp of the last published post. You could edit this query if you wanted to do this based on a certain category or something like that.
$results = $wpdb->get_results("SELECT post_date FROM {$wpdb->posts} WHERE post_type = 'post' and post_status = 'publish' order by post_date desc limit 1");
foreach ($results as $page){
$last_post_time = strtotime($page->post_date);
//Is our last post more recent than when we've updated the previous subscriber count?
//Subtract some time to safeguard this value from being updated at the exact same time a new post is published.
if($last_post_time > $previous_subscriber_count_fetch_time){
//If so, then NOW is the last time we've updated the previous subscriber count. Set it.
$previous_subscriber_count_fetch_time = time();
$previous_subscriber_count = false;
//Get the CURRENT amount of subscribers.
$url = ''.CONVERKIT_TAG_ID.'/subscriptions?api_secret='.CONVERTKIT_API_SECRET;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$data = json_decode(curl_exec($curl));
$current_subscriber_count = $data->total_subscriptions;  
//If the previous subscriber count is unknown, then a new post was just released. So the previous count and the current count should be the same number.
$previous_subscriber_count = $current_subscriber_count;
//Calculate our target number.
$goal_amount_of_subscribers = $previous_subscriber_count + max(MINIMUM_ABSOLUTE_DEMAND, (DEMAND_GROWTH_RATE * $previous_subscriber_count));
//If we still need more subscribers, say so. Otherwise, party!
if($goal_amount_of_subscribers > $current_subscriber_count){
$subscribers_needed = ($goal_amount_of_subscribers - $current_subscriber_count);
$subscribers_needed = 0;
//Put convertkit stuff back into cache.
$convertkit_cache = array(
'previous_subscriber_count_fetch_time' => $previous_subscriber_count_fetch_time,
'previous_subscriber_count' => $previous_subscriber_count
apc_store('convertkit_cache',$convertkit_cache, 31536000);
//And store the final result in a separate cache. So we don't have to run all this code every time.
echo $subscribers_needed;


What's Next?

Want weekly emails? Too bad, 'cuz that's not how I roll. But if you want occassional emails only when I have something epicly mind-blowing to share with you, then please give me your email address. I will not disappoint you.