【问题标题】:How to Use AJAX in a WordPress Shortcode?如何在 WordPress 简码中使用 AJAX?
【发布时间】:2012-11-10 00:58:19
【问题描述】:

我有一个显示随机报价的代码。一个人编写了一个函数来实现所有这些。但是由于某种原因通过 AJAX 更新数据不起作用。当您按下“新报价”按钮时,没有任何反应。也许有人知道为什么?以下代码中需要修复什么,以便在单击“新报价”时加载新报价?

PHP

/wp-content/themes/%your_theme%/js/ajax-load-quote.php

 <?php
 /* uncomment the below, if you want to use native WP functions in this file */
// require_once('../../../../wp-load.php');

 $array = file( $_POST['file_path'] ); // file path in $_POST, as from the js
 $r = rand( 0, count($array) - 1 );

 return '<p>' . $array[$r] . '</p>';
 ?>

HTML 结构

在页面内容、小部件或模板文件中:

<div id="randomquotes">
    <p>I would rather have my ignorance than another man’s knowledge,
       because I have so much more of it.<br />
       -- Mark Twain, American author & Playwright</p>
</div>
<a id="newquote" class="button" href="#" title="Gimme a new one!">New Quote</a>

您显然可以根据自己的喜好进行调整,但为了这个示例,这就是我们要做的。
稍后我们将通过简码生成上述内容。

jQuery

​​>

/wp-content/themes/%your_theme%/js/ajax-load-quote.js

function ajaxQuote() {
    var theQuote = jQuery.ajax({
        type: 'POST',
        url: ajaxParams.themeURI+'js/ajax-load-quote.php',
        /* supplying the file path to the ajax loaded php as a $_POST variable */
        data: { file_path: ajaxParams.filePath },
        beforeSend: function() {
            ajaxLoadingScreen(true,'#randomquotes');
        },
        success: function(data) {
            jQuery('#randomquotes').find('p').remove();
            jQuery('#randomquotes').prepend(data);
        },
        complete: function() {
            ajaxLoadingScreen(false,'#randomquotes');
        }
    });
    return theQuote;
}
/* Loading screen to be displayed during the process, optional */
function ajaxLoadingScreen(switchOn,element) {
    /* show loading screen */
    if (switchOn) {
        jQuery(''+element).css({
            'position': 'relative'
        });
        var appendHTML = '<div class="ajax-loading-screen appended">
            <img src="'+ajaxParams.themeURI+'images/ajax-loader.gif"
                alt="Loading ..." width="16" height="16" /></div>';
        if( jQuery(''+element).children('.ajax-loading-screen').length === 0 ) {
            jQuery(''+element).append(appendHTML);
        }
        jQuery(''+element).children('.ajax-loading-screen').first().css({
            'display': 'block',
            'visibility': 'visible',
            'filter': 'alpha(opacity=100)',
            '-ms-filter': '"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"',
            'opacity': '1'
        });
    } else {
        /* hide the loading screen */
        jQuery(''+element).children('.ajax-loading-screen').css({
            'display': '',
            'visibility': '',
            'filter': '',
            '-ms-filter': '',
            'opacity': ''
        });
        jQuery(''+element).css({
            'position': ''
        });
    }
}
/* triggering the above via the click event */
jQuery('#newquotes').click( function() {
    var theQuote = ajaxQuote();
    return false;
});

functions.php

/wp-content/themes/%your_theme%/functions.php

function random_quote( $atts ) {
    /* extracts the value of shortcode argument path */
    extract( shortcode_atts( array(
        'path' => get_template_directory_uri() . '/quotes.txt' // default, if not set
    ), $atts ) );
    $array = file( $path );
    $r = rand( 0, count($array) - 1 );
    $output = '<div id="randomquotes">' .
            '<p>' . $array[$r] . '</p>' .
        '</div>' .
        '<a id="newquote" class="button" href="#" title="Gimme a new one!">New Quote</a>';
    /* enqueue the below registered script, if needed */
    wp_enqueue_script( 'ajax-quote' );
    /* supplying the file path to the script */
    wp_localize_script(
        'ajax-quote',
        'ajaxParams',
        array(
            'filePath' => $path,
            'themeURI' => get_template_directory_uri() . '/'
        )
    );
    return $output;
}
add_shortcode( 'randomquotes', 'random_quote');
/* register the js */
function wpse72974_load_scripts() {
    if ( ! is_admin() ) {
        wp_register_script(
           'ajax-quote', 
            get_template_directory_uri() . '/js/ajax-load-quote.js',
            array( 'jquery' ),
            '1.0',
            true
        );
    }
}
add_action ( 'init', 'wpse72974_load_scripts' );

如何在 WordPress 中使用 AJAX 更新页面上的内容?

【问题讨论】:

    标签: php ajax wordpress shortcode


    【解决方案1】:

    好问题!

    但是,由于您的代码从一个不好的做法开始 - require_once('wp-load.php'); -,我决定选择一个我的工作 sn-ps 并对其进行调整。

    观察

    • 与您的代码不同,没有外部quotes.txt 被抓取,这里使用帖子类型作为来源(post),在方法@​​987654325@
    • 在给定页面中只能有一个短代码实例,因为它基于特定的元素 ID(#newpost-shortcode#randomposts
    • 像往常一样,it's better to create a plugin。遵循代码 cmets。

    /wp-content/plugins/so-ajax-shortcode/so-ajax-shortcode.php

    <?php
    /**
     * Plugin Name: (SO) Ajax Shortcode
     * Description: Demonstration of WordPress Ajax working as a shortcode.
     * Plugin URI:  http://stackoverflow.com/a/13614297/1287812
     * Version:     2013.10.25
     * Author:      Rodolfo Buaiz
     * Author URI:  https://wordpress.stackexchange.com/users/12615/brasofilo
     * License:     GPLv3
     */
    
    add_action(
        'plugins_loaded',
        array ( B5F_SO_13498959::get_instance(), 'plugin_setup' )
    );
    
    class B5F_SO_13498959
    {
        private $cpt = 'post'; # Adjust the CPT
        protected static $instance = NULL;
        public $plugin_url = '';
        public function __construct() {}
    
        public static function get_instance()
        {
            NULL === self::$instance and self::$instance = new self;
            return self::$instance;
        }
    
        /**
         * Regular plugin work
         */
        public function plugin_setup()
        {
            $this->plugin_url = plugins_url( '/', __FILE__ );
            add_shortcode( 'randomposts', array( $this, 'shortcode') );
            add_action( 'wp_enqueue_scripts', array( $this, 'enqueue' ) );
            add_action( 'wp_ajax_query_rand_post', array( $this, 'query_rand_post' ) );
            add_action( 'wp_ajax_nopriv_query_rand_post', array( $this, 'query_rand_post' ) );
        }
    
        /**
         * SHORTCODE output
         */
        public function shortcode( $atts ) 
        {
            # First post
            if( ! $random_post = $this->get_random_post() )
                $random_post = __( 'Could not retrieve a post.' );
            # Prepare output
            $output = sprintf(
                '<div id="randomposts">%s</div>
                 <button id="newpost-shortcode" type="button" title="%s">%s</button>',
                $random_post,
                __( 'Gimme a new one!' ),
                __( 'New random post' )
            );
            return $output;
        }
    
        /**
         * ACTION Enqueue scripts
         */
        public function enqueue() 
        {
            # jQuery will be loaded as a dependency
            ## DO NOT use other version than the one bundled with WP
            ### Things will BREAK if you do so
            wp_enqueue_script( 
                 'ajax-random-post',
                 "{$this->plugin_url}ajax.js",
                 array( 'jquery' )
            );
            # Here we send PHP values to JS
            wp_localize_script( 
                 'ajax-random-post',
                 'wp_ajax',
                 array( 
                     'ajaxurl'      => admin_url( 'admin-ajax.php' ),
                     'ajaxnonce'   => wp_create_nonce( 'ajax_post_validation' ),
                     'loading'    => 'http://i.stack.imgur.com/drgpu.gif'
                ) 
            );
        }
    
        /**
         * AJAX query random post
         * 
         * Check for security and send proper responses back
         */
        public function query_rand_post()
        {
            check_ajax_referer( 'ajax_post_validation', 'security' );
            $random_post = $this->get_random_post();
            if( !isset( $random_post ) )
                wp_send_json_error( array( 'error' => __( 'Could not retrieve a post.' ) ) );
            else
                wp_send_json_success( $random_post );
        }
    
        /**
         * AUX FUNCTION 
         * Search a random Post Type and return the post_content
         */
        public function get_random_post()
        {
            $array = get_posts( 
                array( 
                      'post_type' => $this->cpt,
                      'numberposts' => -1 
                ) 
            );
            if( empty( $array ) )
                return false;
    
            # Select a random post index number from the current array
            $r = rand( 0, count($array) - 1 );
            return $array[$r]->post_content;
        }
    }
    

    /wp-content/plugins/so-ajax-shortcode/ajax.js

    /* 
     * @plugin SO Ajax Shortcode
     */
    
    jQuery( document ).ready( function( $ ) 
    { 
         var data = {
             action: 'query_rand_post',
             security: wp_ajax.ajaxnonce
         };
         var image = '<img src="' + wp_ajax.loading + '" alt="Loading ..." width="16" height="16" />';
    
        $( '#newpost-shortcode' ).click( function(e) 
        {
            e.preventDefault();
            $( '#randomposts' ).html( image );
            $.post( 
                wp_ajax.ajaxurl, 
                data,                   
                function( response )
                {
                    // ERROR HANDLING
                    if( !response.success )
                    {
                        // No data came back, maybe a security error
                        if( !response.data )
                            $( '#randomposts' ).html( 'AJAX ERROR: no response' );
                        else
                            $( '#randomposts' ).html( response.data.error );
                    }
                    else
                        $( '#randomposts' ).html( response.data );
                }
            ); 
        }); // end click
    });
    

    【讨论】:

    • 嘿,我知道这是一篇旧帖子,但我需要一些帮助。当您添加 ajaxUrl 时,您会将用户发送到 admin-ajax.php,但是您没有在上面显示此文件。您如何验证此页面上的 nonce
    • admin-ajax.php 是一个核心 WP 文件,我们不需要触及它。 wp_localize_script 告诉 JS 它需要的参数,并且在 Ajax 调用的 PHP 函数中使用 check_ajax_referer 检查随机数。
    【解决方案2】:

    这里是示例插件作为问题的答案。在前端使用 ajaxurl。

    so-random-quotes.php

    <?php
    /*
    Plugin Name: SO Random Quotes
    Plugin URI: http://azzrael.ru
    Description: Reference to http://stackoverflow.com/questions/13498959/how-to-use-ajax-in-a-wordpress-shortcode
    Version: 1.0.0
    Author: Azzrael
    Author URI: http://azzrael.ru
    */
    
    new SoRandomQuotes();
    
    /**
     * Class SoRandomQuotes
     */
    class SoRandomQuotes{
    
        const SHORTCODE_KEY = 'randomquotes'; // usage [randomquotes path='/path/to/file/another.quotes.csv']
        const AJAX_ACTION = 'so_getnewquote'; // ajax action
        const DOM_TARGET =  'randomquotes'; // dom element to put the quotes
    
        /**
         * SoRandomQuotes constructor.
         * init actions
         */
        function __construct() {
            // adding shortcode
            add_shortcode('randomquotes', array($this, 'addShortcode'));
    
            // adding ajax callbacks
            add_action( 'wp_ajax_'.self::AJAX_ACTION, array($this, 'getQuoteAjax')); // admin
            add_action( 'wp_ajax_nopriv_'.self::AJAX_ACTION, array($this, 'getQuoteAjax')); // front
        }
    
        /**
         * Shortcode callback
         * @param $atts
         * @return string
         */
        public function addShortcode($atts){
    
            // getting path value from shortcode atts
            $got =shortcode_atts( array(
                'path'    => plugin_dir_path( __FILE__ ).'quotes.txt',
            ), $atts );
    
            // shortcode replacement
            $out = sprintf(
                        '<div id="%s">%s</div><a id="newquote" class="button" href="#" title="Gimme a new one!">New Quote</a>',
                        self::DOM_TARGET,
                        $this->getQuote($got['path'])
                   );
    
            // loading js
            // jquery depends
            wp_enqueue_script('sorandquo-js', plugin_dir_url( __FILE__ ).'quote-loader.js', array('jquery'));
            // passing to js needed vars
            wp_localize_script( 'sorandquo-js', 'ajaxParams',
                array(
                    'path'      => $got['path'], // path to qoutes file
                    'targetDom' => '#'.self::DOM_TARGET, // dom path to put resulting qoute
                    'ajaxurl'   => admin_url( 'admin-ajax.php'), // for frontend ( not admin )
                    'action'    => self::AJAX_ACTION, //
                )
            );
    
            // render shortcode replacement
            return $out;
        }
    
        /**
         * Ajax Callback
         */
        public function getQuoteAjax(){
            echo $this->getQuote($_POST['path']);
            die();
        }
    
        /**
         * Getting random Qoute from the file
         * @param $path
         * @return mixed
         */
        public function getQuote($path){
            $quotesFile = is_file($path) ? file_get_contents($path):"File {$path} not found";
            $quotesArr = $quotesFile ? explode("\n", $quotesFile):['Quotes File is empty'];
            return $quotesArr[array_rand($quotesArr)];
        }
    
    }
    

    quote-loader.js

    jQuery.noConflict();
    jQuery(document).ready(function($) {
        $(document).on('click', '#newquote', function (e) {
            e.preventDefault();
    
            $.post(ajaxParams.ajaxurl, {
                'action':ajaxParams.action,
                'path'  :ajaxParams.path
            }, function (ret) {
                $(ajaxParams.targetDom).html(ret);
            }, 'html');
        });
    });
    

    【讨论】:

      【解决方案3】:

      Wordpress 短代码与您提供参数的函数相同,

      要创建 ajax 请求,您可以在带有 add_action wp_head 钩子的头文件或函数文件中使用 jQuery.ajax 或 xmlhttp。

      您应该在主题文件夹中创建 ajax.php,并在文件顶部包含 wp-load.php。并以适当的方式放置所有 ajax 函数。

      【讨论】:

        【解决方案4】:

        触发器中使用的选择器与按钮 ID 不匹配。

        jQuery('#newquotes') 更改为jQuery('#newquote')

        【讨论】:

        • @Доктор-Скальпинг 这有帮助吗?
        【解决方案5】:

        在function.php中添加这个函数:

            <?php
            add_action('wp_head','ajaxurl');
            function ajaxurl()
            {
            ?>
                <script type="text/javascript">
                var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
                </script>
            <?php
            }?>
        

        【讨论】:

          猜你喜欢
          • 2014-11-22
          • 1970-01-01
          • 2023-03-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-16
          • 1970-01-01
          相关资源
          最近更新 更多