是否从数组中检索SELECT标记自定义值并使用wp_Query将其显示在当前页面中?

时间:2017-10-19 作者:Nick83

我有一个select标签(在filter.php中),有不同的培训价格(80美元、120美元、500美元等等)。这些值存储在数组$选项中(感谢Tom):

当访问者点击80美元时,我想显示所有包含此值的页面(prix\\u 1),以此类推

  • 。。。然后在当前页面(选择标记下方)中显示结果
  • 我想做的事情:

    我尝试了array\\u values()$选项->price\\u 1,选项和不同组合中的a href,以显示相关页面但有错误。我认为javascript是必要的。

    要在当前页面中显示结果,我必须在操作表单标记中插入\\u permalink,并在过滤器下方创建自定义循环以显示这些结果,对吗?

    最后一件事,此代码位于过滤器内部。php包含在4个类别页面中(),显示结果会有问题吗?

    谢谢你,如果有人能给我一些曲目,我会很有帮助的。我不是一个发展者,但我花时间挑战自己。

    <form action="<?php the_permalink(); ?>">
    
    <?php
        $args = array(
            \'post_type\'      => \'page\',
            \'posts_per_page\' => \'-1\',
            \'meta_key\'       => \'prix_1\',
        );
    
        $price_query = new WP_Query( $args );
    
    数组中的所有价格自定义值(以避免值重复)

     $options = array();
    
     if ( $price_query->have_posts() ) {   
        while ( $price_query->have_posts() ) {
            $price_query->the_post();
            $field = get_field( \'prix_1\' );
            if ( !in_array( $field, $options ) ) {
                $options[] = $field; 
            }
        }
    }
    
    ?>
    
    选择标签中的价格自定义值:如何显示所选每个值的页面?

    <div class="col-lg-3">
        <select name="page-dropdown">
    
            <?php if ( !empty( $options ) ) {
    
                foreach ( $options as $option ) { ?>
    
                    <option value=""><a href="<?php the_permalink(); ?>"><?php echo $option->\'price_1\'; ?></a></option>
    
                <?php } //end foreach
    
            } //endif ?>
        </select>
    </div>
    
    显示页面结果:自定义循环以在当前页面中显示选定的标记结果,但此时不起作用。我可能需要传递值。

    if ( $price_query->have_posts() ) :
        while ( $price_query->have_posts() ) : ?>
    
         <div class="row">
            <div class="col-lg-12">
    
                My own pages layout here             
    
            </div>
        </div>
    
        <?php endwhile; ?>
    <?php endif; ?>
    

    1 个回复
    最合适的回答,由SO网友:Tom 整理而成

    @Nick83,

    虽然我不想让答案过于复杂,但为了正确地完成您要做的事情,我相信您需要通过Ajax调用WordPress。

    我的建议如下:

    创建两个ajax调用。第一个获得价格(无重复)。第二个选择用户选择的价格,并在数据库中查询具有该价格的meta\\u值的页面或帖子。

    创建页面加载时为空的HTML表单。Javascript将获取价格值并将其插入select字段。一旦用户选择了价格,脚本将再次做出反应,获取该价格并在函数中调用ajax函数。php,提供价格,并输出结果帖子。

    我继续创建了一个WordPress站点的本地副本来创建一个示例。以下是您需要的代码:

    functions.php

    /*
     * Adding scripts to the theme. Note the wp_localize_script: This is how we provide ajax URL and security to the custom.js file.
     *
     * Sources and further reading:
     *  https://developer.wordpress.org/reference/functions/wp_enqueue_script/
     *  https://codex.wordpress.org/Function_Reference/wp_localize_script
     *  https://www.barrykooij.com/check-nonces-wordpress-ajax-calls/
     *  https://codex.wordpress.org/Function_Reference/wp_verify_nonce
     */
    add_action( \'wp_enqueue_scripts\', \'nick83_enqueue\' );
    function nick83_enqueue() {
        wp_enqueue_script( \'customjs\', get_stylesheet_directory_uri() . \'/custom.js\', array( \'jquery\' ), \'1.0\', true );
        //nklocal
        wp_localize_script( \'customjs\', \'nklocal\', array(
            \'ajaxurl\'  => admin_url( \'admin-ajax.php\' ),
            \'security\' => wp_create_nonce( \'nick83_security_key\' ),
        ) );
    }
    
    /*
     * This is your first ajax call. I have two actions because WordPress allows non-logged-in users to call ajax via "wp_ajax_nopriv"
     * We are also checking a nonce value (provided by wp_localize_script and custom.js)
     *
     * Sources:
     *  https://codex.wordpress.org/AJAX_in_Plugins
     *  https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_(action)
     *  https://codex.wordpress.org/Plugin_API/Action_Reference/wp_ajax_nopriv_(action)
     */
    add_action( \'wp_ajax_nopriv_nick83_get_posts_with_meta\', \'nick83_get_posts_with_meta\' );
    add_action( \'wp_ajax_nick83_get_posts_with_meta\', \'nick83_get_posts_with_meta\' );
    function nick83_get_posts_with_meta() {
        $data = esc_sql( $_POST );
        if ( ! wp_verify_nonce( $data[\'security\'], \'nick83_security_key\' ) ) {
            wp_die( \'Security check\' );
        }
    
        $options = nick83_query_meta_posts();
    
        if ( ! empty( $options ) ) {
            echo json_encode( array( \'msg\' => \'success\', \'data\' => $options ) );
        }
    
        wp_die();
    }
    
    /*
     * For a clean functions.php, I have broken the AJAX function and the query into two separate functions. This function contains the query and method we used previously to remove duplicates. Once complete, it returns the non-duplicate array of prices.
     */
    function nick83_query_meta_posts() {
        $args = array(
            \'post_type\'      => \'post\', //define the post type you want
            \'posts_per_page\' => \'-1\',
            \'meta_key\'       => \'prix_1\',
        );
    
        $price_query = new WP_Query( $args );
    
        $options = array();
    
        if ( $price_query->have_posts() ) {
            while ( $price_query->have_posts() ) {
                $price_query->the_post();
                $field = get_field( \'prix_1\' );
    
                //Here we make sure there are no duplicates
                if ( ! in_array( $field, $options ) ) {
                    $options[] = $field;
                }
            }
        }
    
        return $options;
    }
    
    
    /*
     *  This is the second ajax call. In custom.js, we grab the price the user has chosen and include it in the $_POST (which is turned into $data). If $data[\'price\'] exists, we can give it to the function \'nick83_query_meta_posts_with_price\' and hopefully have posts returned.
     */
    add_action( \'wp_ajax_nopriv_nick83_render_list_of_posts\', \'nick83_render_list_of_posts\' );
    add_action( \'wp_ajax_nick83_render_list_of_posts\', \'nick83_render_list_of_posts\' );
    function nick83_render_list_of_posts() {
        $data = esc_sql( $_POST );
        if ( ! wp_verify_nonce( $data[\'security\'], \'nick83_security_key\' ) ) {
            wp_die( \'Security check\' );
        }
    
        if ( ! isset( $data[\'price\'] ) || empty( $data[\'price\'] ) ) {
            wp_die( \'No Price\' );
        }
    
    
        $options = nick83_query_meta_posts_with_price( $data[\'price\'] );
        if ( ! empty( $options ) ) {
            echo json_encode( array( \'msg\' => \'success\', \'data\' => $options ) );
        }
    
        wp_die();
    }
    
    /*
     * This is the function that takes a price ($data[\'price\'] from the ajax function) and uses it in a WordPress query to see if we can find a meta_key of \'prix_1\' and a meta value of the price chosen.
     *
     * Note here that I am creating an empty array, $links, and then adding the title of the post as the array key and the URL of the post as the array value.
     */
    function nick83_query_meta_posts_with_price( $price = false ) {
        if ( $price ) {
            $args = array(
                \'post_type\'      => \'post\', //define the post type you want
                \'posts_per_page\' => \'-1\',
                \'meta_key\'       => \'prix_1\',
                \'meta_value\'     => $price,
            );
    
            $links = array();
            $meta_query = new WP_Query( $args );
            if ( $meta_query->have_posts() ) {
                while ( $meta_query->have_posts() ) {
                    $meta_query->the_post();
    
                    //Array[key] = value;
                    $links[ get_the_title() ] = get_permalink();
                }
            }
    
            if ( ! empty( $links ) ) {
                return $links;
            }
        }
    
        return false;
    }
    
    /*
     * *** WARNING ***
     * I am only using this piece of code because I do not have ACF installed.
     * If you have ACF you will not need this.
     */
    if ( ! function_exists( \'get_field\' ) ) {
        function get_field( $key ) {
            global $post;
    
            return get_post_meta( $post->ID, $key, true );
        }
    }
    

    custom.js

    /*
     This is a clean way to write javascript since it is all encapsulated in an \'iife\'
    
     Sources:
     https://developer.mozilla.org/en-US/docs/Glossary/IIFE
     */
    window.NICK83APP = (function (window, document, $, undefined) {
        \'use strict\';
        var app = {};
    
        /*
         We can build functions into our mini-javascript application by defining them as app.name = function(){}
         */
        app.init = function () {
    
            //This is our select field that the user will find has pricing inside and will choose a price from.
            app.select = jQuery(\'#page_price_options\');
    
            //This is the empty <ul> on your page. When the user chooses a price, the links will appear here.
            app.page_list = jQuery(\'.nick83_page_list\');
    
            if (app.select.length > 0) {
                app.get_price_options();
    
                /*
                 Uses jQuery "on" function.
                 Sources: http://api.jquery.com/on/
                 */
                app.select.on(\'change\', app.render_pages);
            }
        };
    
        /*
         This function is called if the select exists on the page.
         We disable the select, then set up our ajax call (using the data from wp_localize_script inside functions.php
         If our ajax call is successful, we expect a JSON string to come back with pricing data inside. If we receive that, we create select <option> elements and place them inside our select.
         */
        app.get_price_options = function () {
    
            app.select.attr(\'disabled\', \'disabled\'); //Disable the select since there is no data inside it.
    
            var data = {
                \'security\': nklocal.security, //here is the nonce security
                \'action\': \'nick83_get_posts_with_meta\' //here is our ajax call
            };
    
            app.ajax_call(data, function (response) { //This is a custom function but it is simply a jQuery $.ajax call.
                if (response.msg === \'success\') {
    
                    app.select.empty().append(jQuery(\'<option>\').text("Please choose...").attr(\'value\', \'-1\'));
                    jQuery.each(response.data, function (i, price) {
                        app.select.append(jQuery(\'<option>\').text(price).attr(\'value\', price));
                    });
    
                    app.select.attr(\'disabled\', false);
    
                } else {
                    console.log(response);
                    alert(\'Could not find posts with meta...\');
                }
            }, function (error) {
                console.log(error);
                alert(\'Could not find posts with meta...\');
            });
        };
    
        /*
         This function is fired every time the user changes the select field.
         When the script detects a change, the script executes an ajax call (nick83_render_list_of_posts) and passes the selected price to the ajax script inside functions.php (look for $data[\'price\']).
         */
        app.render_pages = function () {
            var selected = app.select.val();
            if (selected !== \'-1\') {
                var data = {
                    \'security\': nklocal.security,
                    \'action\': \'nick83_render_list_of_posts\',
                    \'price\': selected
                };
    
                app.ajax_call(data, function (response) {
                    if (response.msg === \'success\') {
                        app.page_list.empty();
                        jQuery.each(response.data, function (title, link) {
                            var html = \'<li><a href="\' + link + \'">\' + title + \'</a></li>\';
                            app.page_list.append(html);
                        });
                    } else {
                        console.log(response);
                        alert(\'Could not find posts with price...\');
                    }
                }, function (error) {
                    console.log(error);
                    alert(\'Could not find posts with price...\');
                });
            }
        };
    
        /*
         Just a wrapper for $.ajax.
         Source: http://api.jquery.com/jquery.ajax/
         */
        app.ajax_call = function (data, success, fail) {
            var $validationApiCall = $.ajax({
                url: nklocal.ajaxurl,
                type: "POST",
                data: data,
                dataType: \'JSON\'
            });
    
            $.when($validationApiCall).then(
                function (response) {
                    success(response);
                },
                function (error) {
                    fail(error);
                });
            return false;
        };
    
        $(document).ready(function () {
            //This only loads the script if the form exists with a class meta_search. If you don\'t have this form nothing will work!
            if ($(\'form.meta_search\').length > 0) {
                app.init();
            }
        });
        return app;
    
    })(window, document, jQuery);
    

    Required HTML for the script to work

    <!-- This is our form with the required "meta_search" class. We are also required to have select with ID "page_price_options" and the <ul> with nick83_page_list-->
    <form action="" class="meta_search">
        <select name="page_price_options" id="page_price_options">
            <option value="">Please choose...</option>
        </select>
    </form>
    
    <div class="page-container">
        <h2>Pages will appear here...</h2>
        <ul class="nick83_page_list"></ul>
    </div>
    
    如果这是一种更清晰的阅读代码和注释的方法,那么这里有一个要点:https://gist.github.com/tmort/f80658c3f02ae63e5636aa562f312bd6

    这是一个快速视频演练,因为通过文本有点难以理解:https://youtu.be/-WyScMmjENo

    结束

    相关推荐

    自定义SELECT按元键查询两个表

    我正在使用一个事件插件wp_ftcalendar_events 数据库中的表start_datetime 柱这是整张桌子的图像:我想通过以下方式查询我的帖子start_datetime. 我知道我不能用常规查询做到这一点。我也知道这个查询需要一些条件等。但首先,我想做一个简单的工作查询,稍后再添加条件。在codex中,我发现这个示例结合了两个表:<?php global $wpdb; $querystr = \" SELECT * FROM $wp