Wie verwende ich AJAX in einem WordPress Shortcode?


72

Ich habe einen Code, um ein zufälliges Zitat anzuzeigen. Eine Person hat eine Funktion geschrieben, um all dies zu implementieren. Aber die Update-Daten über AJAX funktionieren aus irgendeinem Grund nicht. Wenn Sie die Taste "Neues Angebot" drücken, passiert nichts. Vielleicht weiß jemand warum? Was muss im folgenden Code behoben werden, damit beim Klicken auf "Neues Angebot" ein neues Angebot geladen wird?

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

Die HTML-Struktur

In einem Seiteninhalt, einem Widget oder einer Vorlagendatei:

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

Dies können Sie natürlich nach Ihren Wünschen anpassen, aber für dieses Beispiel gehen wir so vor.
Wir werden das oben genannte später über einen Shortcode generieren.

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

Wie können Sie den Inhalt der Seite mit AJAX in WordPress aktualisieren?

Antworten:


63

Gute Frage!

Da Ihr Code jedoch mit einer schlechten Praxis beginnt require_once('wp-load.php');, habe ich mich entschlossen, eines meiner Arbeitsausschnitte auszuwählen und anzupassen.

Beobachtungen :

  • Anders als bei Ihrem Code wird kein externes quotes.txtElement abgerufen. Hier postwird in der Methode ein Beitragstyp als Quelle ( ) verwendetget_random_post
  • Es kann nur eine Instanz des Shortcodes auf einer bestimmten Seite geben, da diese auf bestimmten Element-IDs ( #newpost-shortcodeund #randomposts) basiert.
  • Wie immer ist es besser, dafür ein Plugin zu erstellen . Folgen Sie den Code-Kommentaren.

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

Hey, ich weiß, dass dies ein alter Beitrag ist, aber ich brauche Hilfe. Wenn Sie die ajaxUrl hinzufügen, an die Sie den Benutzer senden admin-ajax.php, wird diese Datei oben jedoch nicht angezeigt . Wie gehen Sie vor, um das Nonce auf dieser Seite zu überprüfen ?
Martyn Ball

1
admin-ajax.phpist eine Kern-WP-Datei, das müssen wir nicht anfassen. wp_localize_scriptteilt JS die Parameter mit, die es benötigt, und das Nonce wird check_ajax_refererinnerhalb der von Ajax aufgerufenen PHP-Funktion überprüft .
Brasofilo

5

Hier Beispiel-Plugin als Antwort auf die Frage. Mit Ajaxurl am Frontend.

so-random-quote.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');
    });
});

0

Wordpress-Shortcode wie Funktion, bei der Sie Parameter angeben,

Zum Erstellen einer Ajax-Anfrage können Sie jQuery.ajax oder xmlhttp in Ihrem Header oder Ihrer Funktionsdatei mit add_action wp_headHook verwenden.

Sie sollten ajax.php in Ihrem Themenordner erstellen und oben in der Datei wp-load.php einfügen. und platzieren Sie alle Ihre Ajax-Funktionen in der richtigen Weise.


0

Der im Trigger verwendete Selektor stimmt nicht mit der Tasten-ID überein.

Wechseln Sie jQuery('#newquotes')zujQuery('#newquote')


@ Доктор-Скальпинг Hilft das?
Dedering

-1

Fügen Sie diese Funktion in function.php hinzu:

    <?php
    add_action('wp_head','ajaxurl');
    function ajaxurl()
    {
    ?>
        <script type="text/javascript">
        var ajaxurl = '<?php echo admin_url('admin-ajax.php'); ?>';
        </script>
    <?php
    }?>
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.