WordPress Taxonomy Archive Override

We had a need to link the first page of results for a Category (and other hierarchical taxonomies) to other content on the site.

class Taxonomy_Archive_Links {
    
    public $taxonomies = array();
    
    public function __construct() {
        $taxonomies = get_taxonomies( false, 'objects' ); 
        foreach ( $taxonomies as $taxonomy ) {
            if ( $taxonomy->hierarchical ) {
                // trigger_error( 'This is a taxonomy: ' . $taxonomy->name );
                add_action( $taxonomy->name . '_add_form_fields', array( $this, 'add_form_fields'), 10, 2 );
                add_action( $taxonomy->name . '_edit_form_fields', array( $this, 'edit_form_fields' ), 10, 2 );
                add_action( 'created_' . $taxonomy->name, array( $this, 'add_meta' ), 10, 2 );
                add_action( 'edited_' . $taxonomy->name, array( $this, 'update_meta' ), 10, 2 );
                $this->taxonomies[] = $taxonomy->name;
            }
        }
        add_filter( 'term_link', array( $this, 'term_link_filter' ), 10, 3);
        add_filter( 'redirect_canonical', array( $this, 'redirect_canonical' ), 10, 2 );
    }
    
    static function get_instance() {
        static $instance = null;
        if( $instance == null ) {
            $instance = new self();
        }
         
        return $instance;
    }
    
    function add_form_fields( $taxonomy ) {
        ?><div class="form-field term-group">
            <label for="archive_page"><?php _e('Archive Page', 'alumni-ubc-events'); ?></label>
            <?php wp_dropdown_pages( array( 'name' => 'archive_page', 'show_option_none' => ' ' ) ); ?>
        </div><?php
    }
    
    function edit_form_fields( $term, $taxonomy ){

        $archive_page = get_term_meta( $term->term_id, 'archive_page', true );

        ?><tr class="form-field term-group-wrap">
            <th scope="row"><label for="feature-group"><?php _e( 'Archive Page', 'alumni-ubc-events' ); ?></label></th>
            <td>            
                <?php wp_dropdown_pages( array( 'selected' => $archive_page, 'name' => 'archive_page', 'show_option_none' => ' ' ) ); ?>
            </td>
        </tr><?php
    }
    
    function add_meta( $term_id, $tt_id ) {
        if( isset( $_POST['archive_page'] ) ) {
            $archive_page = intval( $_POST['archive_page'] );
            add_term_meta( $term_id, 'archive_page', $archive_page, true );
        }
    }
    
    function update_meta( $term_id, $tt_id ){

        if( isset( $_POST['archive_page'] ) ){
            $archive_page = intval( $_POST['archive_page'] );
            update_term_meta( $term_id, 'archive_page', $archive_page );
        }
    }
    
    function term_link_filter( $url, $term, $taxonomy ) {
        if ( in_array( $taxonomy, $this->taxonomies ) ) {
            $archive_page = get_term_meta( $term->term_id, 'archive_page', true );

            if ( !empty( $archive_page ) ) { 
                $url = get_permalink( $archive_page );
            }
        }
        return $url;
    }
    
    function redirect_canonical($redirect_url, $requested_url) {
        if ( is_tax( $this->taxonomies ) ) {
            $page = get_query_var( 'paged', 1 );
            if ( $page > 1 ) { 
                return $requested_url;
            }
            else {
                return remove_query_arg( 'post_type', $redirect_url );
            }
        }
        return $redirect_url;
    }
}

add_action( 'init', array( 'Taxonomy_Archive_Links', 'get_instance' ) );

Another geek blog.