ใช้ AJAX ในรหัสย่อ


9

ฉันมีรหัสต่อไปนี้เพื่อย่อเพื่อแสดงคำพูดแบบสุ่ม คำถาม: วิธีการทำปุ่มแสดงคำพูดแบบสุ่มใหม่? ฉันหมายความว่ามันจะกดปุ่มและแสดงคำพูดใหม่ (โดยไม่ต้องรีเฟรชหน้าแน่นอน)

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

ฉันสนใจวิธีที่คุณสามารถอัปเดตเนื้อหาบนหน้าเว็บโดยใช้ Ajax ใน WordPress? ในสถานการณ์ของฉันเพราะในความเป็นจริงเป็นสิ่งที่แน่นอน

ขอโทษด้วยสำหรับภาษาอังกฤษที่ไม่ดีของฉัน ฉันหวังว่าคุณจะเข้าใจฉัน. ขอบคุณ!

คำตอบ:


4

ก่อนอื่นนี่เป็นเส้นเขตแดนภายในขอบเขตของ WPSE เลย
นอกเหนือจากรหัสย่อเพื่อเรียกใช้เอาต์พุต HTML เริ่มต้นนี่เป็นเพียง AJAX

อย่างไรก็ตามที่ถูกกล่าวว่านี่คือวิธีที่มันทำ:

PHP

สมมติว่าตัวอย่างข้อมูล PHP ข้างต้นที่คุณให้มานั้นใช้งานได้ให้วางสิ่งต่อไปนี้ในไฟล์ php สำหรับการโทร 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>';
 ?>

สำหรับการอ้างอิงในอนาคตและเพื่อให้คำตอบนี้มีประโยชน์ต่อผู้อื่น: โปรดทราบว่าwp-load.phpจะต้องรวมไว้เพื่อใช้ประโยชน์จากฟังก์ชัน WordPress ดั้งเดิม กรณี commom ส่วนใหญ่มีแนวโน้มถูกทั้งความจำเป็นในการหรือWP_Query$wpdb

โครงสร้าง 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;
});

วางไว้ด้วยกันในfunction.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' );

ทางเลือก: css สำหรับหน้าจอการโหลด

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

ทรัพยากร / การอ่าน


1
มีเหตุผลใดที่จะไม่ใช้ AJAX API ในตัว?
fuxia

@toscho สุจริต - ไม่คุ้นเคยกับมันมาก ควรค่าแก่การอ่านไหม
Johannes Pille

ใช่แล้ว :) ฉันจะเพิ่มทางเลือก
fuxia

ที่สมบูรณ์แบบ! ขอบคุณ <br/> สคริปต์จะใช้งานได้หากคุณตั้งค่าอาร์กิวเมนต์ของฟังก์ชัน ตัวอย่างเช่นจะอยู่ในรหัสย่อเพื่อให้ลิงก์ไปยังไฟล์ข้อความหรือไม่ <br/> function random_quote ($path) {      $ array = file ("$ path");<br/> ... [randomquote file = "http://exampe.com/file.txt"]<br/> มันจะทำงานได้อย่างไร ฉันไม่เชี่ยวชาญในการเขียนโปรแกรมมากเกินไป
user23769

ฉันได้อัพเดตคำตอบแล้ว ตอนนี้มันรวมไฟล์พา ธ ที่ถูกตั้งค่าโดยรหัสย่อ[randomquotes path="path/to/file.txt"]ส่งผ่านไปยัง js และจากที่นั่นไปยังสคริปต์ php
Johannes Pille

7

คุณสามารถลงทะเบียนสคริปต์ในรหัสย่อ wp_footer()มันจะถูกพิมพ์ลงในส่วนท้ายที่ได้รับรูปแบบที่มี

มันทำงานอย่างไร:

  1. add_shortcode()ลงทะเบียนโทรกลับด้วยรหัสผู้ใช้
  2. ในการโทรกลับ shortcode ลงทะเบียนสคริปต์จากนั้นส่งคืนผลลัพธ์
  3. ในสคริปต์เพิ่มปุ่มอัปเดตส่งคำขอ POST ไปยังadmin_url( 'admin-ajax.php' )และดึงข้อมูลใหม่ แทรกข้อมูลที่ส่งคืนลงในองค์ประกอบด้วยรหัสย่อ

นี่คือตัวอย่างสคริปต์ที่ทำเช่นนั้น สองไฟล์: คลาส PHP และไฟล์ JavaScript 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 );
});

ผลลัพธ์ในบล็อกโพสต์:

ป้อนคำอธิบายรูปภาพที่นี่


+1 & ขอบคุณสำหรับข้างต้น ดูน่าอ่านอย่างแน่นอน ฉันคิดว่าฉันได้รับสิ่งที่เกิดขึ้นส่วนใหญ่หน้า codex อยู่ในวาระการอ่านของฉันและฉันอาจจะตรวจสอบแหล่งที่มาต่อไป ยังอนุญาตให้ฉันเริ่มคำถามติดตามด่วน 2 คำถาม: ฉันเห็นว่าการใช้ API จะเป็นประโยชน์กับฉันโปรแกรมเมอร์ (สะอาดกระชับรัดกุมผูกติดอยู่กับสภาพแวดล้อม (เช่น WP)) 1. แล้วประสิทธิภาพล่ะ? มีข้อได้เปรียบหรือเสียเปรียบใด ๆ เมื่อเทียบกับการใช้ jQuery โดยตรง 2. มีความยืดหยุ่นหรือไม่? คือฉันสามารถใช้ประโยชน์จากการเรียกกลับและข้อโต้แย้งเดียวกันได้หรือไม่?
Johannes Pille

@JohannesPille ประสิทธิภาพการทำงานไม่สมบูรณ์ ในอีกทางหนึ่งคุณดำเนินการในสภาพแวดล้อมที่คาดเดาได้ปลั๊กอินอื่น ๆ สามารถใช้รหัสของคุณอีกครั้ง (hooks, ฟังก์ชั่น) และคุณไม่จำเป็นต้องรู้ว่าติดตั้ง WP ไว้ที่ใด (ไดเรกทอรีปลั๊กอิน / URL อาจแตกต่างกัน เซิร์ฟเวอร์) นอกจากนั้นมันก็เหมือนกับโซลูชันที่กำหนดเอง
fuxia

@toscho เมื่อฉันเปิดใช้งานdefine('WP_DEBUG', true);ใน WP-config.php 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ของฉันแก้ปัญหานี้สร้างข้อผิดพลาด: สิ่งนี้สำคัญหรือไม่ ฉันเปลี่ยนมันเล็กน้อย: wordpress.stackexchange.com/q/196332/25187
Iurie Malai

1
@Iurie staticใช่วิธีการที่จะต้องมีการประกาศให้เป็น ฉันทำการแก้ไขโพสต์ของฉันสำหรับสิ่งนั้น ขอบคุณสำหรับการแจ้งเตือน ฉันจะไม่เขียนโค้ดแบบนี้อีกต่อไป :)
fuxia
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.