1

So I am making a shortcode and trying to integrate vue + wp_query and having difficulty in making it work when I use multiple shortcodes on the same page with different attributes. I am using the code of the plugin "Simple instant search" as a base and am still learning things.

I thought I could use uniqid() for the div id and wp_localize_script and then use it in the script file. However the id generated in the div is different from the id generated in the js -vfm_gallery.block_id.

<?php

if (!class_exists('myclass')){
    class myclass {

        /**
         * Class Constractor
         */
        function __construct() {
            //add shortcode
            add_shortcode('gallery-grid', array($this,'display_gallery_shortcode'));
            //ajax handler
            add_action( 'wp_ajax_nopriv_vfm_gallery', array($this, 'ajax_search') );
            add_action( 'wp_ajax_vfm_gallery',  array($this, 'ajax_search') );
            add_action('wp_enqueue_scripts',array($this,'add_scripts_and_styles'));

        }

        /**
         * shortcode to display search form and results Div
         * @return string - search form and results Div
         */
        public function display_gallery_shortcode(){

            return  '<div id="' . $this->gallery_block_id() . '">
                        <transition name="fade">
                            <div class="loader-overlay" v-if="loading">
                                <div class="loader"></div>
                                <h2>Fetching data</h2>
                            </div>
                        </transition>
                        <transition name="slide-fade" appear>
                            <div v-if="!loading">
                                <ul>
                                    <li v-for="post in posts">
                                        {{ post.title }}
                                    </li>
                                </ul>
                            </div>
                        </transition>
                    </div>';

        }

        /**
         * ajax search function
         * @return array() with title,content JSON
         */
        public function ajax_search(){


            $latest = new WP_Query( array (
                'post_type'       => 'gallery',
                'posts_per_page'  => '9',
                'cat'             => '',
            ));

            $posts = $latest->posts;

            // Check if any posts were found.
            if ( ! $latest->post_count ){
                echo json_encode(array());
                die();
            }


            //Create an array with the results

            $results=array();
            foreach ( $posts as $post ) {   

                $video_url = $post->post_content;

                $title = trim( strip_tags( $post->post_title ) );

                $image = get_the_post_thumbnail( $post->ID, 'thumbnail' );

                $url = get_permalink($post->ID);

                $results[] = array(
                  'title'       => $title,
                  'video_url'   => $video_url,
                  'image'       => $image,
                  'url'         => $url
                );
            }

            //using JSON to encode the array
            echo json_encode($results);
            die();
        }

        /**
         * Void function to add needed scripts and styles.
         */
        public function add_scripts_and_styles(){
            wp_enqueue_script( 'vfm-gallery', plugin_dir_url(dirname(dirname(__FILE__))) . 'js/gallery.js', array( 'jquery' ), null, true );

            wp_localize_script( 'vfm-gallery', 'vfm_gallery', array(
                'ajaxUrl'   => admin_url( 'admin-ajax.php' ),
                'nonce'     => wp_create_nonce('vfmg'),
                'block_id'  => $this->gallery_block_id()
            ));
        }

        static function gallery_block_id(){
            return 'vfm_gallery_' . uniqid();
        }


    }//end class
}//end if
new myclass();
var postsList = new Vue({
    el: "#" + vfm_gallery.block_id,
    data: {
        posts: [],
        loading: true,
    },
    created: function () {
        this.fetchData();
    },
    methods: {
        fetchData: function () {

            this.loading = true; //start loading
            axios.get(vfm_gallery.ajaxUrl, {
                    params: {
                        action: 'vfm_gallery',
                        nonce: vfm_gallery.nonce
                    }
                })
                .then((response) => {
                    this.loading = false; //stop loading
                    this.posts = response.data;
                })
                .catch((error) => {
                    this.loading = false; //stop loading
                    console.error(error)
                })

        }
    }

})

1 Answer 1

1

Inside the __construct() you can put this

global $shortcode_id;
$shortcode_id = 0;

in the display_gallery_shortcode() function you can do this

<?php 
global $shortcode_id;
$shortcode_id ++;
$settings_arr = array();//Here is your settings for each shortcode
ob_start();
?>

<script> 
if(!my_plugin_data) var my_plugin_data = {}
my_plugin_data[<?php echo $shortcode_id ?>] = <?php echo json_encode($settings_arr) ?>
</script>
<div>MY SHORTCODE CONTENT GOES HERE</div>

<?php 
return ob_get_clean();

Try to reload the page and check the variable in the javascript console.

console.log(my_plugin_data);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.