Sử dụng AJAX trong shortcode


9

Tôi có đoạn mã sau vào shortcode để hiển thị một trích dẫn ngẫu nhiên. Câu hỏi: làm thế nào để làm cho một nút hiển thị một trích dẫn ngẫu nhiên mới? Ý tôi là, điều đó sẽ nhấn nút và hiển thị cho bạn một trích dẫn mới (tất nhiên không cần làm mới trang).

function random_quote() {

    // quotes file
     $array = file("/path to txt file");

    // generate a random number between 0 and the total count of $array minus 1
    // we minus 1 from the total quotes because array indices start at 0 rather than 1 by default
    $r = rand(0,count($array)-1);

    // return the quote in the array with an indices of $r - our random number
    return $array[rand(0,count($array)-1)];
}

add_shortcode( 'randomquotes', 'random_quote');

Tôi quan tâm đến cách bạn có thể cập nhật nội dung trên trang bằng ajax trong WordPress? Trong tình huống của tôi, bởi vì trên thực tế chính xác là như vậy.

Xin lỗi vì tiếng Anh của tôi không tốt. Tôi hy vọng bạn hiểu tôi. Cảm ơn!

Câu trả lời:


4

Trước hết, đây là ranh giới trong phạm vi của WPSE.
Ngoài shortcode để kích hoạt đầu ra HTML ban đầu, đây thực sự chỉ là AJAX.

Dù sao, điều đó đã được nói, đây là cách nó được thực hiện:

PHP

Giả sử rằng đoạn mã PHP ở trên mà bạn cung cấp có chức năng, hãy đặt đoạn mã sau vào tệp php cho lệnh gọi ajax:

/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>';
 ?>

Để tham khảo trong tương lai và để làm cho câu trả lời này hữu ích cho người khác: Lưu ý rằng wp-load.phpphải được đưa vào để sử dụng chức năng WordPress gốc. Trường hợp commom nhất có thể là nhu cầu WP_Queryhoặc $wpdb.

Cấu trúc HTML

Trong một nội dung trang, một widget hoặc một tệp mẫu:

<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>

Điều này rõ ràng bạn có thể điều chỉnh theo ý thích của mình, nhưng vì lợi ích của ví dụ này, đây là những gì chúng ta sẽ làm.
Chúng tôi sẽ tạo ra ở trên thông qua một shortcode sau.

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;
});

Đặt nó cùng nhau trong hàm.php

Bên dưới đoạn trích trên của bạn (mà bạn sẽ tìm thấy được bao gồm sửa đổi bên dưới), dán như sau:

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' );

Tùy chọn: Css cho màn hình tải

.ajax-loading-screen {
    display: none;
    visibility: hidden;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    width: 100%;
    background: #ffffff; /* the background of your site or the container of the quote */
    filter: alpha(opacity=0);
    -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
    opacity: 0;
    -webkit-transition:  opacity .1s;
    -moz-transition:  opacity .1s;
    -ms-transition:  opacity .1s;
    -o-transition: opacity .1s;
    transition: opacity .1s;
    z-index: 9999;
}
.ajax-loading-screen img {
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -8px 0 0 -8px;
}

Tài nguyên / Đọc


1
Bất kỳ lý do nào để không sử dụng API AJAX tích hợp?
fuxia

@toscho Thành thật - không quá quen thuộc với nó. Đáng đọc?
Julian Pille

Phải, chắc chắn rồi. :) Tôi sẽ thêm một sự thay thế.
fuxia

Hoàn hảo! Cảm ơn bạn! <br/> Một tập lệnh sẽ hoạt động, nếu bạn đặt đối số chức năng? Ví dụ, để ở trong shortcode để cung cấp một liên kết đến một tệp văn bản? <br/> function random_quote ($path) {      $ array = file ("$ path");<br/> ... [randomquote file = "http://exampe.com/file.txt"]<br/> Vậy nó có hoạt động không? Tôi không quá thành thạo lập trình.
dùng23769

Tôi đã cập nhật câu trả lời. Bây giờ nó bao gồm một filepath được đặt bởi shortcode [randomquotes path="path/to/file.txt"], được truyền xuống js và từ đó đến tập lệnh php.
Julian Pille

7

Bạn có thể đăng ký một tập lệnh trong một shortcode. Nó sẽ được in vào phần chân trang, với chủ đề chứa wp_footer().

Làm thế nào nó hoạt động:

  1. Đăng ký gọi lại shortcode với add_shortcode().
  2. Trong cuộc gọi lại mã ngắn, đăng ký tập lệnh, sau đó trả lại đầu ra.
  3. Trong tập lệnh thêm nút cập nhật, gửi yêu cầu POST đến admin_url( 'admin-ajax.php' )và tìm nạp dữ liệu mới. Chèn dữ liệu trả về vào phần tử với shortcode.

Đây là một kịch bản mẫu làm điều đó. Hai tệp: một lớp PHP và một tệp JavaScript. Cả hai nên ngồi trong cùng một thư mục, ví dụ ajax-shortcode-demo.

ajax-shortcode-demo.php

<?php
/**
 * Plugin Name: AJAX Shortcode Demo
 * Description: How to use AJAX from a shortcode handler named <code>[ajaxdemo]</code>.
 */

add_action( 'wp_loaded', array ( 'Ajax_Shortcode_Demo', 'get_instance' ) );

class Ajax_Shortcode_Demo
{
    /**
     * Current plugin instance
     *
     * @type NULL|object
     */
    protected static $instance = NULL;

    /**
     * Unique action name to trigger our callback
     *
     * @type string
     */
    protected $ajax_action = 'load_demo_data';

    /**
     * CSS class for the shortcode, reused as JavaScript handle.
     *
     * Must be unique too.
     *
     * @type string
     */
    protected $shortcode_class = 'ajaxdemo';

    /**
     * Remeber if we had regsitered a script on a page already.
     *
     * @type boolean
     */
    protected $script_registered = FALSE;

    /**
     * Create a new instance.
     *
     * @wp-hook wp_loaded
     * @return  object $this
     */
    public static function get_instance()
    {
        NULL === self::$instance and self::$instance = new self;
        return self::$instance;
    }

    /**
     * Constructor. Register shortcode and AJAX callback handlers.
     */
    public function __construct()
    {
        add_shortcode( 'ajaxdemo', array ( $this, 'shortcode_handler' ) );

        // register the AJAX callback
        $callback = array ( $this, 'ajax_callback' );
        // user who are logged in
        add_action( "wp_ajax_$this->ajax_action", $callback );
        // anonymous users
        add_action( "wp_ajax_nopriv_$this->ajax_action", $callback );
    }

    /**
     * Render the shortcode.
     */
    public function shortcode_handler()
    {
        $this->register_scripts();

        return sprintf(
            '<div class="%1$s"><b>%2$s</b></div>',
            $this->shortcode_class,
            $this->get_rand()
        );
    }

    /**
     * Return AJAX result.
     *
     * Must 'echo' and 'die'.
     *
     * @wp-hook wp_ajax_$this->ajax_action
     * @wp-hook wp_ajax_nopriv_$this->ajax_action
     * @return int
     */
    public function ajax_callback()
    {
        echo $this->get_rand();
        exit;
    }

    /**
     * Random number.
     *
     * @return int
     */
    protected function get_rand()
    {
        return rand( 1, 1000 );
    }

    /**
     * Register script and global data object.
     *
     * The data will be printent before the linked script.
     */
    protected function register_scripts()
    {
        if ( $this->script_registered )
            return;

        $this->script_registered = TRUE;

        wp_register_script(
            // unique handle
            $this->shortcode_class,
            // script URL
            plugin_dir_url( __FILE__ ) . '/jquery-ajax-demo.js',
            // dependencies
            array ( 'jquery'),
            // version
            'v1',
            // print in footer
            TRUE
        );

        wp_enqueue_script( $this->shortcode_class );

        $data = array (
            // URL address for AJAX request
            'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
            // action to trigger our callback
            'action'    => $this->ajax_action,
            // selector for jQuery
            'democlass' => $this->shortcode_class
        );

        wp_localize_script( $this->shortcode_class, 'AjaxDemo', $data );
    }
}

jquery-ajax-demo.js

jQuery( function( $ ) {

    var buttonClass = AjaxDemo.democlass + 'Button',
        // insert AJAX result into the shortcode element
        updateDemo = function( response ){          
            $( '.' + AjaxDemo.democlass ).find( 'b' ).html( response );
        },
        // fetch AJAX data
        loadDemo = function() {
            $.post( AjaxDemo.ajaxUrl, { action: AjaxDemo.action }, updateDemo );
        };

    // add an update button
    $( '.' + AjaxDemo.democlass )
        .append( ' <button class="' + buttonClass + '">New</button>' );

    // assign the clock handler to the button
    $( '.' + buttonClass ).click( loadDemo );
});

Kết quả trong một bài đăng trên blog:

nhập mô tả hình ảnh ở đây


+1 & Cảm ơn vì những điều trên. Trông chắc chắn đáng đọc lên. Tôi nghĩ rằng tôi nhận được hầu hết những gì đang diễn ra ở trên, các trang codex nằm trong chương trình đọc của tôi và tôi có thể sẽ kiểm tra nguồn nào. Tuy nhiên, cho phép tôi đưa ra 2 câu hỏi tiếp theo nhanh chóng: Tôi có thể thấy rằng việc sử dụng API sẽ có lợi cho tôi, lập trình viên (sạch sẽ, súc tích, gắn liền với môi trường (ví dụ WP)). 1. Làm thế nào về hiệu suất? Bất kỳ lợi ích hay bất lợi nào so với việc sử dụng trực tiếp jQuery (nhận thức được khoảng cách hiệu suất so với js thẳng)? 2. Nó có linh hoạt không? Tức là tôi có thể sử dụng các cuộc gọi lại và đối số tương tự không?
Julian Pille

@JohannesPille Hiệu suất không hoàn hảo . Mặt khác, bạn hành động ngay bây giờ trong một môi trường có thể dự đoán được, các plugin khác có thể sử dụng lại mã của bạn (hook, hàm) và bạn không cần phải biết WP được cài đặt ở đâu (thư mục plugin / URL có thể khác người phục vụ). Bên cạnh đó, nó giống như một giải pháp tùy chỉnh.
fuxia

@toscho Khi tôi kích hoạt define('WP_DEBUG', true);trong wp-config.php, giải pháp này đã phát sinh lỗi : Strict Standards: call_user_func_array() expects parameter 1 to be a valid callback, non-static method Ajax_Shortcode_Demo::get_instance() should not be called statically in /var/www/.../public_html/wp-includes/plugin.php on line 496. Đây có phải là quan trọng? Tôi đã thay đổi một chút: wordpress.stackexchange.com/q/196332/25187
Iurie Malai

1
@Iurie Vâng, phương pháp đó phải được khai báo là static. Tôi đã thực hiện một chỉnh sửa cho bài viết của tôi cho điều đó. Cảm ơn đã thông báo. Tôi sẽ không viết mã như thế này nữa. :)
fuxia
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.