0

I have app archive site with two different taxonomy type: Seller and Kind, I want to have a page for every seller and inside that page, I want to have multiple lists for every term of "Kind" taxonomy.

for Example if i have two posts as below:

Post 1 => "Seller: Apple" and "Kind: Action" 
Post 2 => "Seller: Apple" and "Kind: LifeStyle"

I want a page for "Apple" as seller, and I want to have two boxes for "Action" and "LifeStyle" (terms of 'Kind' taxonomy that actually containing posts) and I want the related post to be shown inside any of those boxes.

any idea of how can I make this?


here is my code:

<?php //start by fetching the terms for the animal_cat taxonomy
$terms = get_terms( 'kind', array(
    'orderby'    => 'count',
    'hide_empty' => 0
) );
?>
<?php
// now run a query for each animal family
foreach( $terms as $term ) {

    // Define the query
    $args = array(
        'post_type' => 'appstore',
        'kind' => $term->slug
    );
    $query = new WP_Query( $args );

    // output the term name in a heading tag                
    if( $query->have_posts() ){

       echo'<h2>' . $term->name . '</h2>';
    }
    // output the post titles in a list
    echo '<ul>';

        // Start the Loop
        while ( $query->have_posts() ) : $query->the_post(); ?>

        <li class="animal-listing" id="post-<?php the_ID(); ?>">
            <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        </li>

        <?php endwhile;

    echo '</ul>';

    // use reset postdata to restore orginal query
    wp_reset_postdata();

} ?>

it shows all post of kind term: ios and all posts of kind term: mac no matter what seller page im viewing.

i just need to add extra layout of filtering to this code. limit the app by "Seller taxonomy" before "Kind Taxonomy".

i want to remove the result of seller apple post from seller gameloft archive page. and inside Gameloft Archive page i want to seperate post by iOS or mac.

Screenshot: enter image description here

1 Answer 1

0

No custom programming answer:

A plugin like https://facetwp.com/ will allow you to set up filters as you have described.

Custom programming answer:

You can create a shortcode that renders fields for the user to check and submit. Then, attach a javascript submit handler to the form so that when the user checks a box or two, the form submits to an ajax handler and hands the selected taxonomy over to the custom ajax function.

The custom ajax function formats the users selection properly into a WordPress query, runs a loop and renders HTML and passes it back to the javascript. The javascript then loads it into a container defined by your shortcode.

The following code block is a quick and dirty example of what I am describing above. It's rough, untested and needs polish but it will give you a head start. Hope this helps.

<?php

//Do you want non-logged-in users to use this? Then you need the "nopriv" action below as well as standard wp_ajax
add_action( 'wp_ajax_nopriv_erfan_get_results', 'wperfan_ajax' );
add_action( 'wp_ajax_erfan_get_results', 'wperfan_ajax' );

function wperfan_ajax() {

    //Check security of ajax request
    check_ajax_referer( 'erfan_security', 'my_security_param' );

    $args = array();
    //Need security here.
    $custom_tax_a = ( isset( $_POST['fields']['custom_tax_a'] ) && is_array( $_POST['fields']['custom_tax_a'] ) ? $_POST['fields']['custom_tax_a'] : false );
    $custom_tax_b = ( isset( $_POST['fields']['custom_tax_b'] ) && is_array( $_POST['fields']['custom_tax_b'] ) ? $_POST['fields']['custom_tax_b'] : false );

    $tax_query = array();

    if ( $custom_tax_a ) {
        foreach ( $custom_tax_a as $slug => $tax_name ) {
            $tax_query[] = array(
                'taxonomy' => 'custom_tax_a', //REPLACE
                'field'    => 'slug',
                'terms'    => $slug,
            );
        }
    }

    if ( $custom_tax_b ) {
        foreach ( $custom_tax_b as $slug => $tax_name ) {
            $tax_query[] = array(
                'taxonomy' => 'custom_tax_b', //REPLACE
                'field'    => 'slug',
                'terms'    => $slug,
            );
        }
    }


    $args['tax_query'] = array(
        'relation' => "AND",
        $custom_tax_a,
        $custom_tax_b,
    );

    $args['post_type'] = 'MY_CUSTOM_POST_TYPE'; // REPLACE
    $args['showposts'] = '10'; // REPLACE

    //Add other args here... showposts, etc
    $query = new WP_Query( $args );

    $returndata = false;
    if ( $query->have_posts() ) {
        while ( $query->have_posts() ) {
            $query->the_post();

            // Need to customize your template here.
            // Also a better way to do this, but for answer purposes:
            $returndata .= sprintf( '<article id="item-%s" class="post-result"><h2>%s</h2><div>%s</div></article>', get_the_ID(), get_the_title(), get_the_content() );
        }
    }

    if ( $returndata ) {
        return json_encode( array( 'msg' => 'filtered', 'data' => $returndata ) );
    }

    return json_encode( array( 'msg' => 'no_filter', 'data' => $returndata ) );
}

add_shortcode( 'erfan_filters', 'erfan_filters_shortcode' );
function erfan_filters_shortcode() {
    $custom_tax_a = get_terms( 'custom_tax_a', array( //REPLACE
        'hide_empty' => true,
    ) );

    $custom_tax_b = get_terms( 'custom_tax_b', array( //REPLACE
        'hide_empty' => true,
    ) );

    ob_start(); ?>

    <div class="erfan-custom-filter">
        <form action="">
            <div class="filter-block custom-tax-one">
                <?php foreach ( $custom_tax_a as $ctone ) {
                    echo sprintf( '<div>
                    <input type="checkbox" id="%s" name="%s" value="%s">
                    <label for="%s">%s</label>
                </div>', $ctone->slug, 'custom_tax_a[]', $ctone->slug, $ctone->slug, $ctone->name );
                } ?>
            </div>
            <div class="filter-block custom-tax-one">
                <?php foreach ( $custom_tax_b as $cttwo ) {
                    echo sprintf( '<div>
                    <input type="checkbox" id="%s" name="%s" value="%s">
                    <label for="%s">%s</label>
                </div>', $cttwo->slug, 'custom_tax_b[]', $cttwo->slug, $cttwo->slug, $cttwo->name );
                } ?>
            </div>

            <?php wp_nonce_field( 'erfan_security', 'my_security_param', true, true ); ?>
            <input type="submit" value="Submit"/>
        </form>
    </div>

    <div class="erfan-results-container">
        <div class="erfan-results">
            <?php // The Custom Posts found will go here...
            ?>
        </div>
    </div>

    <?php
    echo ob_get_clean();
}

add_action( 'wp_footer', 'wperfan_footer_script' );
function wperfan_footer_script() {
    ob_start();
    ?>

    <script type="text/javascript">
        /**
         * jQuery serializeObject
         * @copyright 2014, macek <[email protected]>
         * @link https://github.com/macek/jquery-serialize-object
         * @license BSD
         * @version 2.5.0
         */
        !function (e, i) {
            if ("function" == typeof define && define.amd) define(["exports", "jquery"], function (e, r) {
                return i(e, r)
            }); else if ("undefined" != typeof exports) {
                var r = require("jquery");
                i(exports, r)
            } else i(e, e.jQuery || e.Zepto || e.ender || e.$)
        }(this, function (e, i) {
            function r(e, r) {
                function n(e, i, r) {
                    return e[i] = r, e
                }

                function a(e, i) {
                    for (var r, a = e.match(t.key); void 0 !== (r = a.pop());) if (t.push.test(r)) {
                        var u = s(e.replace(/\[\]$/, ""));
                        i = n([], u, i)
                    } else t.fixed.test(r) ? i = n([], r, i) : t.named.test(r) && (i = n({}, r, i));
                    return i
                }

                function s(e) {
                    return void 0 === h[e] && (h[e] = 0), h[e]++
                }

                function u(e) {
                    switch (i('[name="' + e.name + '"]', r).attr("type")) {
                        case"checkbox":
                            return "on" === e.value ? !0 : e.value;
                        default:
                            return e.value
                    }
                }

                function f(i) {
                    if (!t.validate.test(i.name)) return this;
                    var r = a(i.name, u(i));
                    return l = e.extend(!0, l, r), this
                }

                function d(i) {
                    if (!e.isArray(i)) throw new Error("formSerializer.addPairs expects an Array");
                    for (var r = 0, t = i.length; t > r; r++) this.addPair(i[r]);
                    return this
                }

                function o() {
                    return l
                }

                function c() {
                    return JSON.stringify(o())
                }

                var l = {}, h = {};
                this.addPair = f, this.addPairs = d, this.serialize = o, this.serializeJSON = c
            }

            var t = {
                validate: /^[a-z_][a-z0-9_]*(?:\[(?:\d*|[a-z0-9_]+)\])*$/i,
                key: /[a-z0-9_]+|(?=\[\])/gi,
                push: /^$/,
                fixed: /^\d+$/,
                named: /^[a-z0-9_]+$/i
            };
            return r.patterns = t, r.serializeObject = function () {
                return new r(i, this).addPairs(this.serializeArray()).serialize()
            }, r.serializeJSON = function () {
                return new r(i, this).addPairs(this.serializeArray()).serializeJSON()
            }, "undefined" != typeof i.fn && (i.fn.serializeObject = r.serializeObject, i.fn.serializeJSON = r.serializeJSON), e.FormSerializer = r, r
        });

        window.wperfan_filter = (function (window, document, $, undefined) {
            'use strict';
            var app = {};

            app.init = function () {

                app.the_form = $('.erfan-custom-filter form');
                the_form.on('submit', app.process_form);

            };


            app.process_form = function (e) {
                e.preventDefault();

                var data = $(this).serializeObject();

                var $filter_call = $.ajax({
                    url: ajaxurl,
                    type: "POST",
                    data: {
                        'action': 'erfan_get_results',
                        'security': data.my_security_param
                        'fields': data
                    }
                });

                $.when($filter_call).then(
                    function (response) {
                        if (response.msg === 'filtered') {
                            console.log('Filter worked');
                        }
                        if (response.msg === 'no_filter') {
                            console.log('Default results, no filter.');
                        }
                        $('.erfan-results').html(response.data);
                    },
                    function (error) {
                        console.log('ERROR');
                        console.log(error);
                        alert('An error occured on the server.') //REPLACE
                    });
                return false;
            };

            $(document).ready(function () {
                if ($('.erfan-custom-filter').length > 0) {
                    app.init();

                    //If you want the form to load data on page load, uncomment the following:
                    // app.the_form.trigger('submit');
                }
            });
        })(window, document, jQuery);

    </script>

    <?php
    echo ob_get_clean();
}

Resources:

1
  • Thanks a lot Tom, but i just need to show my current taxonomy term archive based of another taxonomy. for example i have a taxonomy named: seller . i a seller taxonomy term named: gameloft. in archive page of Gameloft i have both "kind" (kind is another custom taxonomy) term : iPhone and mac in archive page of game loft i want to separate posts based on mac or iphone and list them. i have updated the question with my custom code. i appreciate it if you could review it again please.
    – ErfanMHD
    Commented Jul 25, 2019 at 9:41

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.