This is a post for those who like to manipulate WordPress themes to behave how you like. I modified an existing theme recently to add a couple of new features that weren’t already present on the theme. In addition I couldn’t find a suitable plugin quickly enough so I went ahead and made some changes to my template files.
While I modded a couple template files to accomplish these tasks, you could realistically use this information as a base and create some small plugins or even make the changes to a child theme. I’m personally not so sophisticated.
How to sort posts by Facebook share count
The first mod I want to demonstrate is offering the ability to sort your WordPress posts in order by most popular on Facebook. When poking around in the Facebook Graph you will see that each URL has a number associated with it. That number represents the number of times that URL was shared on Facebook.
There are a few different ways to accomplish this task but I chose to access that number in the Graph each time a single post was displayed. I then store that number in the database for later retrieval and sorting.
The first change to make to your template will be in the Single Post (single.php) file. The code that I used is below:
This could go immediately after the line similar to:
if(have_posts()) : while(have_posts()) : the_post();
// Update FB Count $obj_fb = json_decode( file_get_contents( 'http://graph.facebook.com/?id='.get_permalink() ) ); $likes_fb = $obj_fb->shares; update_post_meta($post->ID, '_kjl_fb_likes', $likes_fb, false);
Simple right? We are just passing along the URL to the graph using the data-interchange format JSON, and asking for the number of shares, then storing that value in the database.
After that I created a custom loop to sort the posts by that value, naturally having the most shared at the top.
The code is below. I added it to an include file that I then included into the sidebar. But you can add it anywhere in your template. You should have some understanding of WordPress functions, HTML and PHP to play around with this.
<?php $blog_args = array( 'posts_per_page' => 5, 'post_type' => 'post', 'meta_key' => '_kjl_fb_likes', 'orderby' => 'meta_value_num', 'order' => 'DESC' ); $blog_query = new WP_Query($blog_args); // The above code creates a record set of posts sorted by FB shares // The code below loops through those records (it's very basic, you can get more creative and include images, share counts, and so on) ?> <ul> <?php if($blog_query->have_posts()) : while($blog_query->have_posts()) : $blog_query->the_post(); ?> <li><a href="<?php echo get_permalink(); ?>"><?php echo get_the_title(); ?></a></li> <?php endwhile; endif; wp_reset_query(); ?> </ul>
That’s all pretty straightforward I feel, so I will move on to the next change I made.
How to sort WordPress posts by the number of views
I wanted to be able to sort posts by number of views. In a similar way to how I updated the Facebook share count I also updated the view count each time a post was viewed.
Here’s the code:
Again, this can go in the same spot as the Facebook code above, just below the have_posts() statement.
// Update Post Views $kjl_count_key = '_kjl_post_views_count'; $kjl_count = get_post_meta($post->ID, $kjl_count_key, true); if($kjl_count=='') { delete_post_meta($post->ID, $kjl_count_key); add_post_meta($post->ID, $kjl_count_key, '1'); } else { $kjl_count++; update_post_meta($postID, $kjl_count_key, $kjl_count); }
The code above just updates the “views” if there is a field for it and it has a value, otherwise it creates the field and starts it off with a view count of 1.
Now, we could use a similar custom WordPress loop to get the records and sort them by “views.”
I wanted to take it a little further though. I wanted to be able to show different sets of records, based on specific time frames. I don’t timestamp the views, but of course there is a timestamp for the posts.
So, I decided to create sort of a “tabbed” representation of the different record sets.
First I have “Today,” then “Week,” then “Month,” and then “All.”
“Today” and “Week” may have to be eliminated for smaller sites based on the nature of how they work.
Essentially when clicking “Today” there is a listing of all posts that were published TODAY, sorted by views.
Likewise, when clicking “Week” there is a listing of posts that were published in the past week, sorted by views.
For “Month,” I decided to show posts that were created since the “last day of the previous month,” again… sorted by views.
Lastly, “All” does what you probably expect, sorts the posts by views, but regardless of publish date.
I didn’t want the page to refresh each time a new “tab” was clicked, so I used AJAX to make it happen. I put the word “tab” in quotes because I actually styled mine to be just plain hyperlinks, but true tabs would work just as well. It depends on your tastes. I will include the CSS I used for the way I did it below.
But first, here is the AJAX that shows/hides the contents of the “tab” when clicked:
<script type="text/javascript" src="https://code.jquery.com/jquery-1.7.2.js"></script> <script> $(document).ready(function() { $('.kjl_nav-tabs > li > a').click(function(event){ event.preventDefault();//stop browser to take action for clicked anchor //get displaying tab content jQuery selector var active_tab_selector = $('.kjl_nav-tabs > li.active > a').attr('href'); //find actived navigation and remove 'active' css var actived_nav = $('.kjl_nav-tabs > li.active'); actived_nav.removeClass('active'); //add 'active' css into clicked navigation $(this).parents('li').addClass('active'); //hide displaying tab content $(active_tab_selector).removeClass('active'); $(active_tab_selector).addClass('hide'); //show target tab content var target_tab_selector = $(this).attr('href'); $(target_tab_selector).removeClass('hide'); $(target_tab_selector).addClass('active'); }); }); </script>
Every bit of code, including the AJAX above and the styles below, for this little “hack,” I included ALL in one PHP page, then used a PHP include to place it where I wanted it in my template.
CSS Code
Here are the styles that I used:
<style type="text/css"> .top-view-lst li { list-style: none; } .top-view-lst li:before { content: "> "; font-family: 'Voltaire' , sans-serif; font-weight: 600; font-size: 14px; margin-right: 10px; color: #000; float: left; } /** Start: to style navigation tab **/ .kjl_nav { margin-bottom: 18px; margin-left: 0; padding-left: 0; list-style: none; } .kjl_nav > li > a { display: block; } .kjl_nav-tabs { *zoom: 1; } .kjl_nav-tabs:before, .kjl_nav-tabs:after { display: table; content: ""; } .kjl_nav-tabs > li { float: left; } .kjl_nav-tabs > li { margin-bottom: -1px; } .kjl_nav-tabs > li > a { padding-right: 6px; padding-left: 6px; line-height: 14px; color: #0000ff !important; } .kjl_nav-tabs > .active > a, .kjl_nav-tabs > .active > a:hover { cursor: default; text-decoration: underline !important; color: #0000ff !important; } .tab-content.active{ display: block; } .tab-content.hide{ display: none; } </style>
Now here is the code to draw the “tabs”:
<div> <ul class="kjl_nav kjl_nav-tabs"> <li> <a href="#today">Today</a> </li> <li> <a href="#week">Week</a> </li> <li> <a href="#month">Month</a> </li> <li class="active"> <a href="#all">All</a> </li> </ul> </div>
Put a class=”active” on the list item (li) that you want to be the default.
Below I will paste the code for just one of the sections. You can duplicate it for the rest and make the minor tweaks to each one. I will explain how afterwards.
<section id="today" class="tab-content hide"> <div> <?php $blog_args = array( 'posts_per_page' => 10, 'post_type' => 'post', 'post_status' => 'publish', 'meta_key' => '_kjl_post_views_count', 'orderby' => 'meta_value_num', 'order' => 'DESC', 'date_query' => array( array( 'after' => 'yesterday' ) ) ); $blog_query = new WP_Query($blog_args); ?> <ul class="top-view-lst"> <?php if($blog_query->have_posts()) : while($blog_query->have_posts()) : $blog_query->the_post(); ?> <li><a href="<?php echo get_permalink(); ?>"><?php echo get_the_title(); ?></a></li> <?php endwhile; endif; wp_reset_query(); ?> </ul> </div> </section>
The “id” for the section matches the name given to the “#anchor” in the previous code (the code that draws the tabs).
You can replace the word “hide” with “active” for the default section.
The ‘date_query’ part is the most important bit for each section.
In the case for “Today” we are asking for all posts published after “yesterday,” which is the same thing as “today” clearly.
For “Week” we can ask for posts published after “1 week ago.”
For “Month” we can ask for posts published after the “last day of last month.”
Eliminate the “date_query” part for “All.” When doing that, remove the comma after ‘DESC’ on the line above it since that becomes the last element in the array.
Also change the variable names used for each section. Namely: $blog_args and $blog_query
Well there you have it. You now have the ability to sort your WordPress posts by Facebook shares/likes and by view count. Naturally, you can make changes to the query to filter by category or make other changes. For example, on our site, I made it so that only posts in the “news” category were included in the Facebook sorting. There are lots of ways to customize this code, but I hope that it provides as a good starting point for you.
Leave a Reply