Gunakan AJAX dalam kode pendek

9

Saya memiliki kode berikut ke kode pendek untuk menampilkan kutipan acak. Pertanyaan: bagaimana cara membuat tombol menampilkan kutipan acak baru? Maksud saya, itu akan menekan tombol dan menunjukkan kepada Anda sebuah kutipan baru (tanpa menyegarkan halaman tentu saja).

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

Saya tertarik bagaimana Anda dapat memperbarui konten di halaman menggunakan ajax di WordPress? Dalam situasi saya, karena sebenarnya persis seperti itu.

Maaf untuk bahasa Inggris saya yang buruk. Saya harap kamu mengerti. Terima kasih!

pengguna23769
sumber

Jawaban:

4

Pertama, ini sangat perbatasan dalam ruang lingkup WPSE, sama sekali.
Terlepas dari kode pendek untuk memicu output HTML awal, ini benar-benar hanya AJAX.

Bagaimanapun, itu dikatakan, begini caranya:

PHP

Dengan asumsi bahwa potongan PHP di atas yang Anda berikan fungsional, letakkan yang berikut dalam file php untuk panggilan 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>';
 ?>

Untuk referensi di masa mendatang dan menjadikan jawaban ini bermanfaat bagi orang lain: Catatan yang wp-load.phpharus disertakan untuk memanfaatkan fungsionalitas WordPress asli. Kasus umum yang paling mungkin menjadi kebutuhan WP_Queryatau $wpdb.

Struktur HTML

Dalam konten halaman, widget atau file templat:

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

Ini jelas dapat Anda sesuaikan dengan keinginan Anda, tetapi demi contoh ini, inilah yang akan kita lakukan.
Kami akan menghasilkan di atas melalui kode pendek nanti.

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

Menyatukannya di functions.php

Di bawah cuplikan Anda di atas (yang akan Anda temukan termasuk yang diubah di bawah), rekatkan yang berikut:

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

Opsional: Css untuk layar pemuatan

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

Sumber / Membaca

Johannes Pille
sumber
1
Adakah alasan untuk tidak menggunakan AJAX API bawaan?
fuxia
@toscho Jujur - tidak terlalu akrab dengannya. Layak dibaca?
Johannes Pille
Ya, tentu saja. :) Saya akan menambahkan alternatif.
fuxia
Sempurna! Terima kasih! <br/> Script akan berfungsi, jika Anda menetapkan argumen fungsi? Misalnya, berada di kode pendek untuk memberikan tautan ke file teks? <br/> function random_quote ($path) {      $ array = file ("$ path");<br/> ... [randomquote file = "http://exampe.com/file.txt"]<br/> Jadi, apakah akan berfungsi? Saya tidak terlalu berpengalaman dalam pemrograman.
user23769
Saya telah memperbarui jawabannya. Sekarang termasuk file pengaturan yang ditetapkan oleh kode pendek [randomquotes path="path/to/file.txt"], diturunkan ke js dan dari sana ke skrip php.
Johannes Pille
7

Anda dapat mendaftarkan skrip dalam kode pendek. Ini akan dicetak ke dalam footer, mengingat temanya berisi wp_footer().

Bagaimana itu bekerja:

  1. Daftarkan panggilan balik kode pendek dengan add_shortcode().
  2. Dalam panggilan kode singkat, daftarkan skrip, lalu kembalikan hasilnya.
  3. Di skrip tambahkan tombol pembaruan, kirim permintaan POST ke admin_url( 'admin-ajax.php' )dan ambil data baru. Masukkan data yang dikembalikan ke elemen dengan kode pendek.

Berikut ini contoh skrip yang melakukan itu. Dua file: kelas PHP dan file JavaScript. Keduanya harus duduk di direktori yang sama, misalnya 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 );
});

Hasil dalam posting blog:

masukkan deskripsi gambar di sini

fuxia
sumber
+1 & Terima kasih untuk yang di atas. Sepertinya layak dibaca. Saya pikir saya mendapatkan sebagian besar dari apa yang terjadi di atas, halaman-halaman naskah kuno ada di agenda bacaan saya dan saya mungkin akan tetap memeriksa sumbernya. Namun, izinkan saya untuk memunculkan 2 pertanyaan tindak lanjut cepat: Saya dapat melihat bahwa menggunakan API akan bermanfaat bagi saya, programmer (bersih, ringkas, terikat dengan lingkungan (yaitu WP)). 1. Bagaimana dengan kinerja? Adakah keuntungan atau kerugian dibandingkan dengan menggunakan jQuery secara langsung (saya sadar akan kesenjangan kinerja dengan straight js)? 2. Apakah fleksibel? Yaitu bisakah saya memanfaatkan panggilan balik dan argumen yang sama?
Johannes Pille
@JohannesPille Performa tidak sempurna . Di sisi lain, Anda bertindak sekarang di lingkungan yang dapat diprediksi, plugin lain dapat menggunakan kembali kode Anda (kait, fungsi), dan Anda tidak perlu tahu di mana WP diinstal (direktori plugin / URL bisa berada di server). Selain itu sama seperti solusi kustom.
fuxia
@toscho Ketika saya diaktifkan define('WP_DEBUG', true);di saya wp-config.php solusi ini dihasilkan kesalahan: 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. Apakah ini penting? Saya mengubahnya sedikit: wordpress.stackexchange.com/q/196332/25187
Iurie Malai
1
@Iurie Ya, metode itu harus dinyatakan sebagai static. Saya mengedit posting saya untuk itu. Terima kasih atas pemberitahuannya. Saya tidak akan menulis kode seperti ini lagi. :)
fuxia