Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I needed to assign categories to post from frontend and found this fantastic thread here on this site, which generates a form at frontend with selectboxes. The plugin automatically appends the form after the content and works like charm.

<?php 
/*
Plugin Name: WPSE Crowded Cats
Plugin URI: http://wordpress.stackexchange.com/questions/43419/how-do-i-create-a-way-for-users-to-assign-categories-to-a-post-from-the-frontend
Description: Allow visitors to change categories of posts. Ready to use with custom taxonomies and post types. 
Version: 0.1
Author: WPSE
Author URI: http://wordpress.stackexchange.com/users/2110/maugly
License: GPL2
*/

add_action('plugins_loaded','wpse_init_crowd_cats_class');
function wpse_init_crowd_cats_class(){
    new WPSECrowdCatsClass();
}

class WPSECrowdCatsClass { 
    function __construct() {
        // APPEND THE FORM AUTOMATICALLY TO EVERY POST
        add_filter( 'the_content', array( $this,'append_form' ) );

        // TEMPLATE ACTION TAG TO BE USED IN THEME
        // Usage: do_action('wpse_crowd_cats_form');
        // Usage: do_action('wpse_crowd_cats_form', $post_id, $taxonomy );
        add_action( 'wpse_crowd_cats_form', array( $this,'wpse_crowd_cats_form' ), 10, 2 );

        // FORM PROCESSING
        add_action( 'template_redirect', array( $this,'process_request' ) );
    }

    function process_request(){
        // check submission
        if ( ! isset($_POST['crowd-cat-radio']) || ! is_array($_POST['crowd-cat-radio']) )
            return;

        //TODO: check nonce
        // sanitize and check the input
        $suggested_terms = array_map( 'absint', $_POST['crowd-cat-radio'] );
        $post_id = absint( $_POST['crowd-cats-pid'] );
        $tax = $_POST['crowd-cats-tax'];
        if ( ! taxonomy_exists($tax) )
            return;

        // Allow only existing terms. Not sure if this is needed.
        $args = array( 'hide_empty' => false );
        $args = apply_filters( 'mcc_allowed_terms_args', $args, $post_id, $tax );
        $args['fields'] = 'ids';
        $allowed_terms = get_terms( $tax, $args );
        foreach ( $suggested_terms as $key => $term_id )
            if ( ! in_array( $term_id, $allowed_terms ) )
                unset( $suggested_terms[$key] );

        // Add terms to taxonomy
        $affected_terms = wp_set_object_terms( $post_id, $suggested_terms, $tax, false );
        update_term_cache($affected_terms);
        return $affected_terms;
    }

    function get_form( $post_id=null, $tax='category' ) {
        if ( is_null($post_id) || ! taxonomy_exists($tax) )
            return false;

        $args = array( 'hide_empty' => false );
        $args = apply_filters( 'mcc_get_terms_args', $args, $post_id, $tax );
        $all_terms = get_terms( $tax, $args );

        if ( ! $all_terms )
            return false;

        $post_terms = wp_get_object_terms( $post_id, $tax, array( 'fields' => 'ids' ) );
        $permalink = get_permalink( $post_id );
        $out = "<form id='crowd-cats' action='$permalink' method='POST' >
            <ul >";

        foreach ( $all_terms as $t ) :
            $checked = in_array( $t->term_id, $post_terms) ? 'checked' : '';
            $out .= "<li>
                        <input type='checkbox' id='crowd-cat-$t->term_id' name='crowd-cat-radio[]' value='$t->term_id' $checked /> 
                        <label for='crowd-cat-$t->term_id' >".esc_attr($t->name)."</label>
                     </li>";
        endforeach;

        $out .= "</ul>
                <input type='submit' value='Submit' name='crowd-cats-submit'/>
                <input type='hidden' value='".esc_attr($tax)."' name='crowd-cats-tax'/>
                <input type='hidden' value='$post_id' name='crowd-cats-pid'/>";

        //TODO: set nonce
        $out .= "</form>";
        return $out;
    }

    function append_form($content){
        global $post;
        if ( 'post' != $post->post_type )
            return $content;

        $form = $this->get_form( $post->ID );
        if ( ! $form )
            return $content;

        return "$content \n $form";
    }

    function wpse_crowd_cats_form( $post_id=null, $taxonomy='category' ) {
        if ( is_null($post_id) ) {
            global $post;
            $post_id = $post->ID;
        }
        echo $this->get_form( $post_id, $taxonomy );
    }
} // end of class               

However I did not want the form to appear right after the content but after a few other important divs i have, after the content. So I used the following action tag ( mentioned in code as commented out lines) to use it in the template single.php. Doing so the form appeared in the desired place.

<?php do_action('wpse_crowd_cats_form'); ?>

The issue is it does not remains selected on submit neither the option gets saved. Please suggest me a solution.

share|improve this question
1  
Can you also share the code snippet you have been trying? –  Maruti Mohanty Sep 23 '13 at 9:34
    
@MarutiMohanty , I am using the same code so I just copied the same code from the thread. It works fine when used as it is but gives the issue mentioned above when used as template tag. –  gurung Sep 23 '13 at 14:43
    
Did you try with do_action('wpse_crowd_cats_form', get_the_ID());? –  brasofilo Sep 23 '13 at 20:43
    
@brasofilo , yes..exactly what i needed. thanks. How do I accept it as an answer? –  gurung Sep 24 '13 at 5:05

1 Answer 1

up vote 1 down vote accepted

In the code documentation:

// TEMPLATE ACTION TAG TO BE USED IN THEME
// Usage: do_action('wpse_crowd_cats_form');
// Usage: do_action('wpse_crowd_cats_form', $post_id, $taxonomy );

If the do_action is going to be placed in the loop, then do_action('wpse_crowd_cats_form', get_the_ID()); should work.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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