Posts in: hack
WordPress custom taxonomy conditional tag
For a particular project, I needed WordPress to do something based on a custom post type’s custom taxonomy. WP didn’t have a built in function for checking custom taxonomies so I googled for an answer.
After looking for ways to have WordPress do a conditional test for custom taxonomies I was unsatisfied with what I found since most of the solutions involved making functions. While they do work, it was a bit too much for my use since I really only needed to check the custom post against only one custom taxonomy. And mostly because I know that there is always more than one way to skin a cat… and sometimes I really do want to find “my own solution“.
So here’s my version of the one-time, non-function way to test for a conditional taxonomy on a conditional post type, which admittedly may not be so efficient, but it works! (and if you cache, then it doesn’t really matter) First, you need to put this bit of PHP somewhere before where you need to do your conditional test:
<?php
$tempvar = urldecode(http_build_query(get_the_terms($post->id, 'custom_tax_name')));
if(strpos($tempvar, '[term_taxonomy_id]=101') !== false) {$customtaxis = 'y';}else{$customtaxis = 'n';}
?>
Line 2 puts all the post’s taxonomy information as a string into the $tempvar variable. Line 3 checks whether the a taxonomy with ID of 101 is in $tempvar and sets the $customtaxis variable appropriately.
To make this work for you change the following :
- custom_tax_name to the name of your custom taxonomy (the $taxonomy variable in the register_taxonomy function)
- 101 to the ID of the custom taxonomy you want to test
- $tempvar and $customtaxis to whatever variables you want, if you want
Then, where ever you want to test for your custom taxonomy, use this:
if($customtaxis == 'y') {
// if yes, whatever you want
}else{
// if not, whatever you want
}
And that’s it!
Note: This must be used inside the loop. Tested in WP version 3.1 – 3.1.3
WordPress comments meta data: Adding a checkbox
Posted in comments, hack, WordPress
Recently at work, there was a need to ask for additional data in the comments section of a WordPress site. A checkbox needed to be added to the comments form asking a question.
This sounded like a good use for WordPress comments meta data. There isn’t a lot of information out on the interwebs about how to use it, so I had to more or less figure this out…
So, what needed to be done was:
- add a check box to the comments form
- show in the WordPress comments admin whether or not the checkbox was selected
- indicate in the comment notification email whether or not the checkbox was selected
Adding the checkbox to the comments form is the easiest part. To add the checkbox to the comments form open up your themes comments.php file and paste this into the area where you need it:
<p><label><input name="publishc" type="checkbox" id="publishc" value="this is the value I want to capture" tabindex="90" /> Whatever sentence that you want commenters to use the checkbox for</label></p>
Now that the checkbox is in place, we need to make sure that the data (the checkbox value) is saved to the database. We also want that data to be visible when viewing the comments from within the WordPress admin. So, paste this in your theme’s functions.php file:
// allow the saving of comment meta data
function fpo_allow_show_comment ( $post_id ) {
$allow_show_comment = $_POST['publishc'];
if ( $allow_show_comment ) {
add_comment_meta( $post_id, 'publishc', $allow_show_comment, true );
}}
add_action( 'comment_post', 'fpo_allow_show_comment', 1 );
// display meta in the edit comments admin page
function show_commeta() {
if (is_admin()) {
echo get_comment_text(), '<br/><br/><strong>', get_comment_meta(get_comment_ID(), 'publishc',1), '<strong>';
}}
add_action('comment_text', 'show_commeta');
The first function will allow comments meta data to be collected and to save it to the database. The second functions will show it in the comments admin pages.
Adding the comments meta data to the notification email proved to be the hardest to figure out – I couldn’t figure out a way to do it via plugin or editing functions.php. So, I decided to do this the least desirable way, which is to edit the WordPress core files, namely wp-includes/pluggable.php.
So find the function wp_notify_postauthor and look for the part that says if (‘comment’ == $comment_type) {. Paste these lines of code in whatever area of the notification email where you would like the comment meta to be included:
$notify_message .= __('Comment meta: ') ;
$notify_message .= sprintf( get_comment_meta($comment->comment_ID, 'publishc',1)) . "\r\n\r\n";
And that is that, hours and hours worth of trial and error. Hope you find it useful!
Test and works in WordPress versions 2.9 through 3.0.4.
WordPress: make posts expire or auto-delete
While working on a website, the client needed the homepage to function differently from other websites and blogs.
Rather than having the home page show the last x number of posts or editing the loop through query_posts to only show posts within a certain timeframe, the posts would either need to appear on the homepage until:
- a specific date – and then the post will either be archived or deleted
- or if no date is set, the post should appear for a month
I knew that there was a way to makes posts “expire” by setting a date and time as a custom field and editing the loop. A search on Google reveals several articles (all of which are identical – exactly the same, so I don’t know the original article which I could link to). I then also found an article that edited the expire posts code so that the post would auto delete rather than expire: Modify you WordPress theme to enable an expiration date for your posting.
There a few drawbacks to the methods I found:
- they needed post custom fields, which aren’t the most user friendly interface for end users to employ
- custom fields do not look nice
- the custom field entry needed to be in the format mm/dd/yyyy 00:00:00 not exactly user friendly nor easy to understand (is 17:00:00 7pm or 5pm??)
- posts would either only expire (be archived) or be deleted
So now I needed to put on my PHP hat and find a way to get what needed to be done and avoid the drawbacks listed above. I knew right away that I would need to use custom write panels to make everything easy to look at and use. I wrote about using them here, WordPress Custom Write Panels & prioritizing what to display and used this as my reference, Revisited: Creating Custom Write Panels in WordPress
In the end, this is what my WordPress custom write panel looked like:

Obviously, this is for posts in the “announcements” category. Anyway, open up your themes functions.php (or make one) and add this code in:
<?php
//start post meta box
$key = "Announcements";
$meta_boxes = array(
"expimo" => array(
"name" => "expimo",
"title" => "Expiration Month",
"description" => "Select a date in the future for this post to expire. Default date is one month into the future",
"option" => array('01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12')),
"expida" => array(
"name" => "expida",
"title" => "Expiration Day",
"description" => "Select Day",
"options" => array('-', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31')),
"expiye" => array(
"name" => "expiye",
"title" => "Expiration Year",
"description" => "Select Month",
"options" => array('-', '2013', '2012', '2011', '2010')),
"expiti" => array(
"name" => "expiti",
"title" => "Expiration Time",
"description" => "Select Time",
"options" => array('00:00:00', '01:00:00', '02:00:00', '03:00:00', '04:00:00', '05:00:00', '06:00:00', '07:00:00', '08:00:00', '09:00:00', '10:00:00', '11:00:00', '12:00:00', '13:00:00', '14:00:00', '15:00:00', '16:00:00', '17:00:00', '18:00:00', '19:00:00', '20:00:00', '21:00:00', '22:00:00', '23:00:00')),
"autodelp" => array(
"name" => "autodelp",
"title" => "Delete Post On Expiration",
"description" => "Choose if a post should be deleted after expiration. Choosing NO will remove the post from the homepage and archive it upon expiration",
"options" => array('no', 'yes')),
);
function create_meta_box() {
global $key;
if( function_exists( 'add_meta_box' ) ) {
add_meta_box( 'new-meta-boxes', ucfirst( $key ) . ' Post Options', 'display_meta_box', 'post', 'normal', 'high' );
}
}
function display_meta_box() {
global $post, $meta_boxes, $key;
?>
<div class="form-wrap">
<?php
wp_nonce_field( plugin_basename( __FILE__ ), $key . '_wpnonce', false, true );
foreach($meta_boxes as $meta_box) {
$data = get_post_meta($post->ID, $key, true);
?>
<?php if($meta_box[ 'name'] != 'expimo' &&
$meta_box[ 'name'] != 'expida' &&
$meta_box[ 'name'] != 'expiye' &&
$meta_box[ 'name'] != 'autodep' &&
$meta_box[ 'name'] != 'expiti' &&
$meta_box[ 'name'] != 'autodelp'
) { ?>
<div class="form-field form-required">
<label for="<?php echo $meta_box[ 'name' ]; ?>"><?php echo $meta_box[ 'title' ]; ?></label>
<input type="text" name="<?php echo $meta_box[ 'name' ]; ?>" value="<?php echo htmlspecialchars( $data[ $meta_box[ 'name' ] ] ); ?>" />
<p><?php echo $meta_box[ 'description' ]; ?></p></div>
<?php } elseif ($meta_box[ 'name'] == 'expimo') {
echo '<div class="form-field form-required"><label for="Post Expiration Date">Post Expiration Date</label>';
echo '<select name="expimo" id="expimo">';
foreach ($meta_boxes['expimo']['option'] as $option) {
if ($option == '01') {$optionez = 'January';
} elseif ($option == '02') {$optionez = 'February';
} elseif ($option == '03') {$optionez = 'March';
} elseif ($option == '04') {$optionez = 'April';
} elseif ($option == '05') {$optionez = 'May';
} elseif ($option == '06') {$optionez = 'June';
} elseif ($option == '07') {$optionez = 'July';
} elseif ($option == '08') {$optionez = 'August';
} elseif ($option == '09') {$optionez = 'September';
} elseif ($option == '10') {$optionez = 'August';
} elseif ($option == '11') {$optionez = 'November';
} else {$optionez = 'December';}
echo '<option', ' value="', $option, '"', $data[ 'expimo' ] == $option ? ' selected="selected"' : '', '>', $optionez, '</option>';
}
echo '</select>';
echo '<select name="expida" id="expida">';
foreach ($meta_boxes['expida']['options'] as $option) {
echo '<option', ' value="', $option, '"', $data[ 'expida' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
}
echo '</select>';
echo '<select name="expiye" id="expiye">';
foreach ($meta_boxes['expiye']['options'] as $option) {
echo '<option', $data[ 'expiye' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
}
echo '</select>';
echo '<select name="expiti" id="expiti">';
foreach ($meta_boxes['expiti']['options'] as $option) {
if ($option == '00:00:00') {$optionez = '12MN';
} elseif ($option == '01:00:00') {$optionez = '1AM';
} elseif ($option == '02:00:00') {$optionez = '2AM';
} elseif ($option == '03:00:00') {$optionez = '3AM';
} elseif ($option == '04:00:00') {$optionez = '4AM';
} elseif ($option == '05:00:00') {$optionez = '5AM';
} elseif ($option == '06:00:00') {$optionez = '6AM';
} elseif ($option == '07:00:00') {$optionez = '7AM';
} elseif ($option == '08:00:00') {$optionez = '8AM';
} elseif ($option == '09:00:00') {$optionez = '9AM';
} elseif ($option == '10:00:00') {$optionez = '10AM';
} elseif ($option == '11:00:00') {$optionez = '11AM';
} elseif ($option == '12:00:00') {$optionez = '12NN';
} elseif ($option == '13:00:00') {$optionez = '1PM';
} elseif ($option == '14:00:00') {$optionez = '2PM';
} elseif ($option == '15:00:00') {$optionez = '3PM';
} elseif ($option == '16:00:00') {$optionez = '4PM';
} elseif ($option == '17:00:00') {$optionez = '5PM';
} elseif ($option == '18:00:00') {$optionez = '6PM';
} elseif ($option == '19:00:00') {$optionez = '7PM';
} elseif ($option == '20:00:00') {$optionez = '8PM';
} elseif ($option == '21:00:00') {$optionez = '9PM';
} elseif ($option == '22:00:00') {$optionez = '10PM';
} else {$optionez = '11PM';}
echo '<option', ' value="', $option, '"',$data[ 'expiti' ] == $option ? ' selected="selected"' : '', '>', $optionez, '</option>';
}
echo '</select>';
echo '<p>Select a date in the future for this post to expire. Default date is one month into the future</p></div>';
} elseif ($meta_box[ 'name'] == 'autodelp') {
echo '<label for="Auto Delete">Auto Delete?</label>';
echo '<select name="autodelp" id="autodelp">';
foreach ($meta_boxes['autodelp']['options'] as $option) {
echo '<option', $data[ 'autodelp' ] == $option ? ' selected="selected"' : '', '>', $option, '</option>';
}
echo '</select><p>', $meta_box[ 'description' ], '</p></div>';
} else {}
?>
<?php
}; ?>
<?php
if (get_the_time('m') == 12) {$mononet = 1;
} else {$mononet = 1 + get_the_time('m');}
$slashhh = '/';
$spaceeee = ' ';
if ( $data[ 'expida'] == '-') {$datarr = $mononet.$slashhh.get_the_time('d/Y').$spaceeee.$data[ 'expiti' ];
} else {$datarr = $data[ 'expimo' ].$slashhh.$data[ 'expida' ].$slashhh.$data[ 'expiye' ].$spaceeee.$data[ 'expiti' ];} ?>
<?php update_post_meta($post->ID, 'expiration', $datarr); ?>
</div>
<?php
}
function save_meta_box( $post_id ) {
global $post, $meta_boxes, $key;
foreach( $meta_boxes as $meta_box ) {
$data[ $meta_box[ 'name' ] ] = $_POST[ $meta_box[ 'name' ] ];
}
if ( !wp_verify_nonce( $_POST[ $key . '_wpnonce' ], plugin_basename(__FILE__) ) )
return $post_id;
if ( !current_user_can( 'edit_post', $post_id ))
return $post_id;
update_post_meta( $post_id, $key, $data );
}
add_action( 'admin_menu', 'create_meta_box' );
add_action( 'save_post', 'save_meta_box' );
//end post meta box
?>
It’s a bit lengthy, but it does what it needs to.
Now open up your index.php or whichever file has the loop which you will need to edit and modify your loop between the while (have_posts()) and endwhile statements as such:
<?php while (have_posts()) : the_post(); $data = get_post_meta( $post->ID, 'Announcements', true );
$expirationtime = get_post_custom_values('expiration');
if (is_array($expirationtime)) {
$expirestring = implode($expirationtime);
}
$secondsbetween = strtotime($expirestring)-time() + 14400;
if ( $secondsbetween <= 0 && $data[ 'autodelp'] == 'yes') {
wp_delete_post($post->ID, false);
} elseif ( $secondsbetween <= 0 && $data[ 'autodelp'] == 'no') {
} elseif ( $secondsbetween > 0) {
?>
<!--start your loop contents here. For example...-->
<h2><a href="<?php the_permalink() ?>"><?php the_title(); ?></a></h2>
<p>Posted on <?php the_time('M.d, Y') ?></p>
<?php the_content('Read more »'); ?>
<!--end your loop contents here-->
<?php } else {}
endwhile; ?>
Please note that 14400on line 06 is to change the time to my current time zone, US Eastern Time. For best results, you should change this number to reflect your current timezone. To calculate the number you would use for your timezone, use this from Modify you WordPress theme to enable an expiration date for your posting:
Let say, you are in GMT +7 time zone, you are ahead of time, so instead of “+”, you will need to “-” the difference, 7 hours = 7 * 60 *60 = 25200.
Don’t forget to save and upload your changes. To use the panel, while writing or editing a post, in the custom write panel named Announcements Post Options, simply select the date and time which you would like the post to expire under the Post Expiration Date section. If you want the post to be deleted upon expiration, select yes in the Auto Delete section. If no date is chosen, the post will automatically expire one month from the “publish date” of the post.
Hope you like that and find it useful.
