Support » Plugins » Hacks » Front End Custom Taxonomy Editing

  • Hello,

    I have added the custom taxonomy “Campaigns” to my site, which I use as another version of Tags. I have created a page where the Campaigns can be created, but I am struggling to create a dropdown menu (hopefully with a search function) of the campaigns that have been created which can then be assigned to a post, I was hoping to have this at the end of each post so that the logged in users can assign their campaigns to a post without going to the back-end as they will be subscribers.

    I hope somebody has any help to offer

    Kind Regards,

Viewing 10 replies - 1 through 10 (of 10 total)
  • Hello Will,

    There’s quite a few elements to your question so I’m going to try and answer the main one, which is, essentially, how do I create a drop-down menu of the campaigns that have been created.

    This will create your select menu:

    <?php
    $args = array(
      'name' => 'campaigns'
    );
    $taxonomies = get_taxonomies( $args );
    if ( $taxonomies ) {
      echo '<select name="select" id="campaigns">';
      foreach ( $taxonomies as $taxonomy ) {
          echo '<option value="' . $taxonomy . '">' . $taxonomy . '</option>';
      }
      echo '</select>';
    }
    ?>

    Hopefully that will tick the first box and allow you to progress!

    See here for more information on get_taxonomies.

    Thanks for your help Morgy!

    I have created a shortcode to apply this temporarily to the sidebar, the result is seen as a drop down menu that only contains one option called “campaigns” and not my campaigns taxonomy.

    I’ve tried a couple of tweaks to get around this issue but my PHP knowledge is still in it’s early stages.

    Do you know might be causing this problem?

    Kind Regards,
    Will

    Ahh okay.. I misunderstood. Let’s try this:

    <?php
    $args = array(
      'taxonomy' => 'campaigns'
    );
    $taxonomies = get_categories( $args );
    if ( $taxonomies ) {
      echo '<select name="select" id="campaigns">';
      foreach ( $taxonomies as $taxonomy ) {
          $name = $taxonomy->name;
          echo '<option value="' . $name . '">' . $name . '</option>';
      }
      echo '</select>';
    }
    ?>
    Moderator bcworkz

    (@bcworkz)

    If by search function you are referring to an auto complete feature much like that used by wordpress.org and many other sites these days, these are not actual dropdown form elements even though they often appear as such. The functionality is achieved with AJAX methods and CSS. It’s fairly involved to create an auto complete feature. Fortunately, code is available to show you the way. There are many auto complete plugins you can try. Some are specific, others generic. Some customizing may be needed for the feature to work with a custom taxonomy.

    A drop down like you are trying will be much easier to code than an auto complete, and will serve well if there are not too many terms in the list.

    To actually add the selected term to the post from the front end, whether by drop down or auto complete, you’re going to need some custom code to do this. Once again, AJAX will yield the best user experience. A basic overview of AJAX in the WP environment is available starting here:
    https://developer.wordpress.org/plugins/javascript/

    Your AJAX request should include a nonce to ensure the request is from your script, as well the requisite action argument and whatever else you need to add a term to a post – post id, term id or slug, etc. Naturally your code would verify the nonce and that the user is logged in before adding the term. Don’t forget to validate and sanitize any data coming from a client!

    The final step would be to update any part of the page displaying the current terms to include the term just added.

    Thanks Morgy however this shows up blank, once again I tried some tweaks but no joy.

    Thanks for clearing that up bcworkz! I think the autocomplete feature would really help as there will end up being a lot of campaigns (possibly hundreds eventually) and could be tedious to scroll through them.

    I’ve seen a few plugins and tried them out but they’re either outdated and not working or don’t have the ability to use custom taxonomies, which is why I thought some custom coding might be need as you say.

    Moderator bcworkz

    (@bcworkz)

    Hmmm. That’s disappointing about plugins not working for you. Your next best option is probably working from a plugin that does auto complete for categories, then altering it to work for your taxonomy instead. It should just be a matter of changing what taxonomy is queried for terms. Easier said than done, I know. Digging into someone else’s code can be pretty confusing. Ideally there would be a filter to alter the taxonomy, but many plugin devs are not very good about offering filters to use.

    You’d likely need to directly hack the code, which means your hack would be overwritten when the plugin is updated. You could essentially fork it by giving it a new name to avoid updates, but then you would miss out on any security patches.

    Another option would be to find some example code, not necessarily for WP, as guidance for how auto complete basically works, then developing your own plugin to do this. This would be too much as a beginner coding project, but it’s not all that complicated for someone comfortable coding AJAX.

    All of that can be down the road right now. To get things started, getting a basic drop down working would be highly desirable to serve until the number of terms gets too unwieldy. morgyface’s code looks like it should work for you. If you’re getting nothing, I’d guess that get_categories() isn’t returning anything, meaning there is a mismatch between ‘campaigns’ and whatever taxonomy slug is assigned when the taxonomy is registered. For example, perhaps the slug is ‘campaign’? You can confirm the problem is with get_categories() by adding print_r( $taxonomies ); right after get_categories() is called. A listing of term objects is expected. If you get an empty array, get_categories() isn’t working due to an arguments error of some sort.

    So I’ve figured out that the code was showing blank because the ‘Campaigns’ that were created aren’t assigned to a post, once they are assigned, they show up on the drop down.

    This is great but a lot of the campaigns would be empty before they are originally assigned, and the drop down I am wanting to create is the only way to assign a campaign. So I need a way of showing all ‘Campaigns’ even if they are not assigned to a post yet.

    Any ideas?

    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_shortcode( 'editcamp', 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='campaigns' ) {
    
            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 .= "
                            <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>
                         &nbsp;-&nbsp;";
    
            endforeach;
    
            $out .= "</ul>
                    <input class='campeditcss' 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 "<button class=accordion>Assign Campaigns</button>
    <div id=foo class=panel>
      $out
      <br />
    </div>";
    
        }
    
        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='campaigns' ) {
    
            if ( is_null($post_id) ) {
                global $post;
                $post_id = $post->ID;
            }
    
            echo $this->get_form( $post_id, $taxonomy );
        }
    
    } // end of class

    This seems to work fine, a few issues such as once a Campaign has been assigned, it cannot be unassigned if it is the last Campaign Assigned to that post (basically there has to be one campaign assigned at least)

    This shows an accordion which holds checkboxes of the Campaigns (to allow people to unassign a Campaign). Is there a way to convert this into a dropdown?

    Moderator bcworkz

    (@bcworkz)

    The reason you cannot remove that last term is when no terms are checked, $_POST['crowd-cat-radio'] does not even exist, so your code does not execute. You need to do the term removal part regardless of the existence of $_POST['crowd-cat-radio'] or not.

    A standard drop down form element cannot contain check boxes, so you do not want to do this. What you can do is create a term list that behaves like a drop down, but contains check boxes. You should be able to find examples of this online somewhere. You’re not the first one wanting this. It might involve some javascript. When you search, the example does not need to be WP specific. Just remember that any javascript needs to be enqueued in WP. Non-WP examples will naturally not address this aspect.

    I would try locating a CSS only example first. I’m not sure if this is possible, but if it is, it would be preferable. Good luck!

    I’m not sure how I would do that. This isn’t my code so I’m not 100% with it.

    And I’ll have a look around and see what I can find!

Viewing 10 replies - 1 through 10 (of 10 total)
  • The topic ‘Front End Custom Taxonomy Editing’ is closed to new replies.