Open Comment Author link in new window

I’ve been searching for a way to open a commenter link on a new window for a long time and with no success. Most of the techniques required me to open one of wordpress core files and alter its functions. Thought it did work, the changes were doom to vanish on the next upgrade.

The correct way to do that is to use the built-in hook system in order to alter the link after it was created.

add_filter('get_comment_author_link', 'authorLinkNew');
function authorLinkNew($result){
	return str_replace ('<a', '<a target="_blank" ', $result);
}

Actually all we do here is search and replace on the anchor element and in that way to add the target blank into the link. It’s actually a bit rough, and there must be a dozen of different ways to do it which are more correct (using php domelement would probably be the best one, Using Regex with preg_replace may be another) but it’s surely the fastest way to do that.
Please note that using another plugin that rewrite links might cause a collision that way, and rewrite this function using a domelement will return better results.

Subscribe to blog updates in comments

A comment form imageNot so long ago Automatic added the option to register to sites update on wordpress.com by using a checkbox in the comment form. So apparently by ticking the checkbox one should get email updates on every new blog post – which, is a very good idea I might say.

But if you don’t use WordPress.com services and prefer to use your own installation you are in a bit of a problem because (As far as I know) there is no plugin that does that.
In order to achieve this functionality on a customer’s blog I’ve decided to hack one of the common blog updates by mail pluging. I’ve started by using post-notification plugin and looked for a nice addNewUser($mail) function that I can hook into. After 2 hours all I found was that the admin section got a manual subscription field but it posts the results directly to the DB with no specific function.

The next obvious option was Subscribe2 which was much better for my purpose. I found out that this plugin is actually using a Class structure (OO) and has a add($mail) function as part of its function. That was quite relieving Because it made everything much simple.

After finding the function to use all I had to do is add the checkbox in the comments section. I’ve added the next functions in the template function.php using wordpress hooks system.

add_action('comment_form', 'show_registration_checkbox');
function show_registration_checkbox(){?>
	<p class="subscribe-to-comments">
	<input type="checkbox" name="register" id="register" value="register" style="width: auto;" />
	<label for="subscribe"><?php _e('I want to get updates when the blog update','saar');?></label>
	</p>	
<?}

The first line creates the actual hook to the comments form and set the callback function. the function itself just writes the HTML to the end of the comment form.

The next thing is to listen to a comment post event and again, we can (and always should) use the hook system by defining a listener and creating a callback option to handle the submitted value

add_action('comment_post', 'toto');
function toto()
{
	global $mysubscribe2;
	if($_POST['register'] == 'register')
		$mysubscribe2->add( $_POST['email']);    
}

Please note that because Subscribe2 creates an object we need to use that object – hence – the global.

Simple file based caching system

Once in a time I need one of my sites to grab a RSS feed, parse it and display its results in the page. The main problem is that the processing takes a lot of time (and resources) which intemperate to a large delay on the client side.

This is also quite a silly thing to do due to the fact that unless its your twitter feed it usually doesn’t update so frequently.

So we want to cache the whole process in order to save time and resources and usually it’s been done by saving the feed locally and parsing it from the server. Though it shorts the grabbing time we still need to parse it again and again.

Cache the results
Instead of saving the feed a better way would be to save the parsing results, thus we only serve a text file that is on our server – which is always a lot faster.

The Idea is to have a function that looks for the cache file, if it finds it, the file content will be included, if not, the function will parse the feed and create a new cache file.

function getdatacache(){
$fileName = 'content.cache';
$file = 'cache/'.$fileName;
if (@file_exists($file))
{
$content = file_get_contents($file);
} else {
$content = parseTheFeed();
file_put_contents($file, $content);
}
return $content;
}

So, we set the file name, look for that file and if it exists we takes its content. Else we parse the feed (parseTheFeed is the function that does the actual parsing) and save the result (The function should return a string or to use output buffering ob-start – http://php.net/manual/en/function.ob-start.php).

What about Time To Live (TTL)?

Unless we want a one time only feed parsing (and what would be the point in that?) we need a TTL system. One way is to run a cron job on the cache folder that will delete files older than the required TTL. It can work but only if you’re hosting supplier supports cron jobs.
Instead of deleting files, we can set the TTL using php date function as the file name.
Instead of $fileName = ‘content.cache’; we can use
$fileName = date(‘H’).’.cache’;

With that change the script will create a new file every hour and save it to the cache folder. Although the first user in every hour will have a delay the system will be much faster for every user after that.

In order to prevent that from happening one can run a script on the last-minute of the hour that will create the next hour cache it can be done using a boolean switch and a separate call from the end of our script or by a different script called by a cron job.

 function getdatacache($nextHour = false){
if($nextHour &amp;&amp; date('i')&gt;=57)
$fileName = (date('H')+1). '.cache';
else
$fileName = date('H').'.cache';
$file = 'cache/'.$fileName;
if (@file_exists($file))
{
$content = file_get_contents($file);
} else {
$content = parseTheFeed();
file_put_contents($file, $content);
}
return $content;
}

Note
Bare in mind that in order for this script to run properly, the cache folder should have write permissions.

How to check for category descendants

The best thing about using wp_list_categories as a menu builder is that wordpress already marks each list item with the hierarchy attributes as styling class. In that way, if a user is in a category page the “current-cat” class will be added and “current-cat-parent” will be added if one is in a child category.

All is good when you are trying to use Textual menus, but once in a while, you will come across a designer who decides that the menu should use a unique font – one that you can only embed as an image. Soon you will find out that the menu should react to mouseovers or be highlighted in relevant occasions.

Basically – we have 4 alternatives:
a. Category page
b. Descendant category page
c. Post under the category
d. Outside of the category tree

function is_my_current_cat($id) {	
	if (is_category($id))
		return true;
	if (is_category()) {	
		$descendants = get_term_children( (int) $id, 'category');
		if ( $descendants  )
			foreach($descendants as $cate){
				if(is_category($cate ))
					return true;
			}
		}
	if (is_single()) {			
		if (in_category($id) || in_child_category($id)) {
			return true;
		}		
	}
	return false;
}

The function returns true in cases A-C, or false if its not a relevant item and in order to use it to add a class you can do something like that:

class="<?php if( is_my_current_cat($id)) echo "selected"; ?>">

Creating a “tell your story” page

In the past month I got 3 or 4 RFPs to wordpress projects that required a “Client stories” section – which can be achieved in one of three ways.
1. Allow user registration as contributers and let them write in the admin.
2. Create a form, mail the data to yourself and create posts later-own the copy-paste way.
3. Use a guest writer and wordpress functions to create a form automatically.

The problem with the first way is that the user is given access to the admin panel and can see / read pending posts and comments. This can be problematic though can be hacked (at least the post reading, not sure about the comments), and yet – if you want to keep your slick look, you’ll need to theme your admin.
The second solution is much simpler but can be very annoying, especially if you receive a lot of stories on weekly base.
The Third option, which is my favorite actually combines the first and the second solutions into a nice and elegant way – no more copy-paste and no need to provide anyone with access to your admin.

Preparations

First you need to create your guest user – So in your admin panel go to Users–>Add New and add a new user. Set the user Role to “contributer”. The name is not really important because we won’t be using that, but we do need the User_id value.

Because we are using only one guest user for all the stories, we can add a custom meta field for the person name. open a post and add a new meta field, lets call it “storyteller”.

The last task is to create a category for the user submitted stories, its not a “Must” because we can always use the author page to index all the stories, but I prefer a category.

Let the coding begin

The form

<form id="tellastory" method="post" action="">
<label for="fullname">Full Name </label>
<input id="fullname" name="fullname" type="text" maxlength="255" value=""/> 
<label for="title">Title </label>
<input id="title" name="title" type="text" maxlength="255" value=""/>
<textarea id="editor" name="editor" rows="20" cols="50">
</textarea>
<input type="hidden" name="form_id" value="123456" />		
<input id="saveForm" type="submit" name="submit" value="submit" />
</form>

This gives us a very basic form with 3 fields – the storyteller’s name, the story title and the story content. also notice the hidden field called “form_id” with the value of “123456″.

$storyteller_user_id = "2";  //your guest user id here
$stories_category = "3";  //your stories category id here
$key = "storyteller";

if($_POST['form_id']=="123456"){
  $my_post = array(); 
  $my_post['post_title'] =$_POST['title'];
  $my_post['post_content'] = $_POST['fullname'];
  $my_post['post_status'] = 'draft';
  $my_post['post_author'] = $storyteller_user_id;
  $my_post['post_category'] = array($stories_category);
  $post_Num = wp_insert_post( $my_post );
  add_post_meta($post_Num, $key, $_POST['fullname']);
}

The code is pretty straight forward – we check if we got a post request and if so we create a new post using the “wp_insert_post” function. The variable $post_num should get the id of the new post if all went well.
Now that we know the post ID we can add the meta field with the storyteller’s name with add_post_meta.

IMPORTANT
Pleas notice that for the example I did not sanitize the received Post data. If you do use this code, please remember to do so.

Category listing
Copy your category.php (or index.php if no category.php file) file to a new file and name it category-X.php (X stands for your stories category number). Edit the file and replace “the_author()” call with these lines:

$key= "storyteller";   
if($storyteller = get_post_meta($post->ID, $key, true))
           echo $storyteller; 

Here we took the teller name from the meta field and placed it in the Author position so instead of getting a list of stories from “guest” we can display the full name.

Post listing

The code is very similar to the category code, with a tiny difference. because all the stories are actually posts they use the single.php template file. so we will check if the post has a meta author field and decide by that.

$key= "storyteller";   
if($storyteller = get_post_meta($post->ID, $key, true))
           echo $storyteller; 
else
           the_author();

Customizing the look and feel of your sidebar widgets

Every now and then, you realize that you might not have been doing something wrong, but you’ve been working hard and stupidly. One of these revelations was figuring out just how simple it is to customize the different types of sidebar widgets without some serious fumbling around.

Sure, you could work extra hard to re-create the entire sidebar via code, so everything there is perfect and beautifully designed, but at the same time, the widgetized sidebar is no longer functional, which makes this not only extra work, but also a rather lame solution.

The smart alternative is using the unique class names which WordPress (or any widgety plugin) assigns to the various widget types. Just because the template we’re working on doesn’t contain styling for these elements doesn’t mean that we can’t do that ourselves!

For example, if we want to decorate the Search box or the categories, we can simply create styling for the built-in widget_search or widget_categories, and voila!

Of course, you mustn’t forget to also create a generic design that can style any widgets that might be added in the future, or your clients might find themselves wondering why the hell that newfangled box they added themselves looks like crap.

Getting the category ID on a category page

Once in a while, a customer would ask for a set of category pages with a small difference between them, for example – a nice image to match the category name. WordPress has many functions that handle categories, but I always wanted a get_the_category_id() that will return the current category number in a category page.

It usually takes me around half an hour of googling before I browse the source of earlier project, and every time this happens, I bang my head when I recall that the solution was so simple. In a category page, the variable $cat holds the category number. So, if you have a “category.php” page and you need to print the category id all you need is to use a simple “echo $cat”.

What can we do with this? Well, one can save a bunch of images with the category id as name (1.jpg, 2.jpg etc.) and call them like that:

<img src="<?php bloginfo('stylesheet_directory');>/images/<?php echo $cat ?>.jpg" alt="" />

HTML Tables in WordPress

Lately, a client of mine wanted to insert Word/Excel tables into his wordpress site.

When we tried simply using copy -> paste from Word (using the Word paste tool), the result was terrible and un-editable.

Some digging into WordPress plugins led me to find wp-table-reloaded, this wonderful plugin does it all:

  • creates new tables
  • manages tables
  • imports tables from CSV
  • Displays tables
  • Sorts & Filters tables

All I needed and then some more.

After installing the plugin just go to tools->WP-Table Reloaded and get started.

In my case all that was needed was to save the excel file as .csv file, go to Wp-Table Reloaded admin screen and choose the import-a-table option.

Choose the import format (available formats are: HTML, XML, csv), and upload the file

This is it, the data is now uploaded to the plugin and can be edited if needed.

In order to display the table in a post or a page all you need to do is paste the table shortcode.

The result looks like this:

The plugin has a very detailed manual that can be found here.

Excerpts the right way

As of WordPress 2.9 there are 2 new filters that helps us control the excerpts look&feel.

These two filters are:

  • excerpt_more – lest us define the excerpt trailing character
  • excerpt_length – lets us define the excerpt length (in words)

These functions ease the modification of WordPress excerpts for custom-made themes.

Here is example for using them:

Make wordpress mail you on 404 errors

One of the problematic black holes in a website is the 404 error page, and while the uninformative ones may look nice, they are usually the worst. The main cause for a 404 page is that we, as editors, broke something; and the main problem is that we usually won’t notice that.

The 404 event is usually logged in the Apache log, a log most of us never bother looking at, not to mention, never bother looking after – so if you changed something, you’ll probably won’t know about it for a long time.

The next tip I learned from Milo317 who solved  my question with a nice and elegant answer – Well, why not tell WordPress to email you whenever that happens?

$adminemail = get_bloginfo('admin_email');
$website = get_bloginfo('url');
$websitename = get_bloginfo('url');
if (!isset($_SERVER['HTTP_REFERER']))
echo "Seems like you have done something that's uncool, because we can't find whatever you are after";
elseif (isset($_SERVER['HTTP_REFERER'])){
$failuremess = "A user tried to go to $website" .$_SERVER['REQUEST_URI']." and received a 404 (page not found) error. ";
$failuremess .= "It wasn't their fault, so try fixing it. They came from ".$_SERVER['HTTP_REFERER'];
mail($adminemail, "Bad Link To ".$_SERVER['REQUEST_URI'],
$failuremess, "From: $websitename &lt;noreply@$website&gt;"); }

The code is pretty straight forward – WordPress grabs the admin’s email and the blog details and checks if the user got to that page by referal or by mistake (wrong copy-paste for example).

If there was a reference to that page, WordPress will generate an email message with all the relevant details and send it to the admin. Setting a 301 (moved permanently) reference will usually solve most of these problems.