1

I am working on an issue-based publishing system for a friend of mine. So far I have created a custom taxonomy called "Issue"; added several custom fields to the custom taxonomy (like "Issue number", "PDF URL" and "Is Published?"); and expanded the taxonomy management page with additional columns to show these custom term data.

Now I want to implement a convenient method to publish (and unpublish) the individual issues. My plan is to add an additional custom column to the taxonomy management page which contains "Publish" and "Unpublish" buttons. So I tried to populate the custom column with a form which contains hidden data fields and a visible submit button; basically I duplicated the functionality of the default term edit form, and put it in the table cells.

The problem is that the whole taxonomy management table is wrapped in a form, called "posts-filter", and forms cannot be nested. So my solution doesn't work properly.

Is there a proper solution for adding such buttons to a custom column? Any suggestions are welcomed!

An image for clarification: http://img845.imageshack.us/img845/669/customcol.png

add_filter("manage_issue_custom_column", 'manage_issue_columns', 10, 3);

// The function that manages the custom columns
function manage_issue_columns($out, $column_name, $issue_id) {
    $issue = get_term($issue_id, 'issue');
switch ($column_name) {
    case 'issue_pdf_url':
        $term_meta = get_option( "taxonomy_term_$issue_id" );
        if ( isset( $term_meta["issue_pdf_url"] ) ){
            $out .= $term_meta["issue_pdf_url"]; 
        }   
    break;

    case 'issue_num':
        $term_meta = get_option( "taxonomy_term_$issue_id" );
        if ( isset( $term_meta["issue_num"] ) ){
            $out .= $term_meta["issue_num"];
        }
    break;

    //This is the column where I need to add buttons
    case 'issue_published':
        $term_meta = get_option( "taxonomy_term_$issue_id" );
        $term_object = get_term($issue_id, "issue");
        if ( isset( $term_meta["issue_published"] ) && $term_meta["issue_published"] == "yes" ){
            //This is the form which shows the publishing buttons; not working due to being nested in other form
            $out .= '<form name="edittag" id="edittag" method="post" action="edit-tags.php" class="">  <input type="hidden" name="action" value="editedtag" />  <input type="hidden" name="tag_ID" value="' . esc_attr($issue_id) . '" />  <input type="hidden" name="taxonomy" value="issue" />  ' . wp_original_referer_field(true, 'current') . wp_nonce_field('update-tag_' . $issue_id) . ' <input name="name" id="name" type="hidden" value="' . $term_object->name . '" />  <input name="slug" id="slug" type="hidden" value="' . $term_object->slug .'" />  <input name="description" id="description" type="hidden" value="' . $term_object->description .'" />  <input type="hidden" value="" checked="" id="term_meta[issue_published]" name="term_meta[issue_published]">  <input type="submit" value="Unpublish" class="button-primary" id="submit" name="submit"></form>';
        } else {
            $out .= '<form name="edittag" id="edittag" method="post" action="edit-tags.php" class="">  <input type="hidden" name="action" value="editedtag" />  <input type="hidden" name="tag_ID" value="' . esc_attr($issue_id) . '" />  <input type="hidden" name="taxonomy" value="issue" />  ' . wp_original_referer_field(true, 'current') . wp_nonce_field('update-tag_' . $issue_id) . ' <input name="name" id="name" type="hidden" value="' . $term_object->name . '" />  <input name="slug" id="slug" type="hidden" value="' . $term_object->slug .'" />  <input name="description" id="description" type="hidden" value="' . $term_object->description .'" />  <input type="hidden" value="yes" checked="checked" id="term_meta[issue_published]" name="term_meta[issue_published]">  <input type="submit" value="Publish" class="button-primary" id="submit" name="submit"></form>';
        }
    break;

    default:
    break;
}

return $out;
}

1 Answer 1

3

For something like this you might consider adding an 'action'; which appear when you hover other the item.

The following code is not complete, and hasn't been tested - but should get you on the right track.

Add the action

First, to add the action link, use the tag_row_actions hook. (Keep in mind a function hooked onto this will be fired on every taxonomy, so you need to check the taxonomy). Something like:

add_filter('tag_row_actions','my_term_action',10,2);
function my_term_action($actions,$tag){
if($tag->taxonomy == 'issue'):
    $actions['my-action-class'] = '<a href="#"> My action </a>';
endif;
return $actions;
}

The $actions array is associative, where the key will become the class of the span element that wraps the action. The value, is what the span will wrap around.

You can use use the $tag (it's an object, the term id is given by $tag->term_id) to determine which action to display, so if you wish to display the 'publish' action

$actions['my-action-class'] = '<a class="Publish" termid="'.$tag->term_id.'" href="#"> Publish </a>';

and if you wish to display the 'unpublish' action, instead add:

$actions['my-action-class'] = '<a class="Unpublish" termid="'.$tag->term_id.'" href="#"> Unpublish </a>';

I give them different classes and an extra attribute. This will be used by jQuery/AJAX to perform the relevant action...

The jQuery /AJAX

jQuery(document).ready(function(){
    jQuery(".my-action-class a").click(function(){
        change_publish_states(jQuery(this));
    });
});
    function change_publish_states(el){
   if(el.hasClass('Publish')){
      new_state = 'Unpublish';
   }else{
      new_state = 'Publish';
  }
        jQuery.getJSON(ajaxurl,
            {   term_id: el.attr("termid"),
                action: "my_change_publish_state",
                new_state: new_state
            },
            function(data) {
                if (data.error){
                    alert(data.error);                      
                }else{
                    //Update label and class
                    el.text(data.new_state);
                    el.attr('class', data.new_state)
                }
            });
    }

You need to add this script on the custom taxonomies page, you can run a function on admin_enqueue_scripts to check the page being viewed and conditionally enqueue it;

add_action('admin_enqueue_scripts','load_my_ajax_script');
function load_my_ajax_script(){
 //Check globals like $pagenow=='edit-tags' and $taxonomy=='issues' or $current_screen 
 //to make sure you are on the right page and enqueue script - or add a filter 
 //to print the script at the footer.

 global $current_screen;
 if ( $current_screen->id != 'edit-issue' )
  return;

 wp_enqueue_script( 'my_ajax_save', get_stylesheet_directory_URI() . '/my_ajax_save.js' );
}

Then it remains to add a function onto the AJAX action-hook :

AJAX action

add_action('wp_ajax_my_change_publish_state', 'change_the_publish_state');
function change_the_publish_state(){

   $term_id = $_GET['term_id'];
   $new_state = $_GET['new_state'];

   //Perform checks / logic & update publish status.
   $term_meta = get_option( "taxonomy_term_$term_id" );

   if ( $new_state == "Unpublish" )
    $term_meta['issue_published'] = 'yes';

   if ( $new_state == "Publish" )
    $term_meta['issue_published'] = '';

   update_option( "taxonomy_term_$term_id", $term_meta );    

//return the new state of the term
   $result['new_state'] = $new_state;
    echo json_encode($result);
    exit();
}
1
  • Thanks, Stephen! Your help is really appreciated. I managed to successfully implement the solution. Commented Jan 27, 2012 at 11:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.