最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

How to pass data to javascript in custom widget class

programmeradmin1浏览0评论

I have a custom widget where the user can insert an username in an <input> field. It's working fine, but I need to get the inserted value from php and pass it to the javascript file that is enqueued with my widget plugin. I'm testing with wp_localize_script but it will not work and I'm unable to access the passed data if i do console.log. How I can fix this, is it possible to access data from php to plugin js file?

class InstagramFeedWidget extends WP_Widget {

  public $url;

  public function __construct()
  {
    parent::__construct(
      'instagram-widget',
      'Instagram feed',
      array(
        'description' => ''
      )
    );
    add_action( 'widgets_init', array($this, 'init') );
    add_action( 'wp_enqueue_scripts', array($this, 'initScripts' ) );
  }

  public function init()
  {
    register_sidebar(
      array(
        'name'        =>  'Instagram feed',
        'id'          =>  'ig-feed',
        'description' =>  'Instagram feed widget',
      )
    );
    register_widget( 'InstagramFeedWidget' );
  }

  public function widget( $args, $instance )
  {
    $this->url = '/'.$instance['username'].'?__a=1';


    // $ch = curl_init();
    // curl_setopt( $ch, CURLOPT_URL, $url );
    // curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Accept: application/json') );
    // curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    // curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
    // $feed = curl_exec($ch);
    // curl_close($ch);
    // $data = json_decode( $feed , true);
    // ob_start();
    ?>
    <!-- <div class="jumbotron jumbotron-fluid ig-feed">
      <div class="container">
        <div class="row">
          <div class="col-sm-12 col-md-12 col-lg-12"> -->
            <div class="swiper-container swiper-feed" id="ig-feed">
              <div class="swiper-wrapper">
                <img class="swiper-slide feed-img" src="">
            <?php
              // foreach( $data['graphql']['user']['edge_owner_to_timeline_media']['edges'] as $node ){
              //   foreach( $node as $img ){
              //     echo '<div class="swiper-slide feed-img" style="background-image:url('.$img['display_url'].');"></div>';
              //   }
              // }
            ?>
              </div>
            <div class="swiper-button-prev "></div>
            <div class="swiper-button-next"></div>
            </div>
          <!-- </div> -->
        <!-- </div>
      </div>
    </div> -->
    <?php
    echo ob_get_clean();
  }

  public function form( $instance )
  {
    $username = isset( $instance['username'] ) ? esc_attr( $instance['username'] ) : '';
    ?>
    <p>
    <label for="<?php esc_attr( $this->get_field_id('username') ); ?>"><?php _e('Username'); ?></label>
    <input type="text" class="widefat" id="<?php echo esc_attr( $this->get_field_id('username') ); ?>" name="<?php echo esc_attr( $this->get_field_name('username') ); ?>" value="<?php echo esc_attr($username); ?>">
    </p>
    <?php
  }

  public function update( $new_instance, $old_instance )
  {
    $instance = $old_instance;

    $instance['username'] = esc_attr($new_instance['username']);

    return $instance;
  }

  public function initScripts()
  {

    wp_enqueue_style('instagram-widget', plugins_url( 'instagram-widget.min.css', __FILE__), array('swiper'), null);
    wp_enqueue_script('instagram-widget-js', plugins_url( 'instagram-widget.js', __FILE__), array('swiper'), null);
    wp_localize_script( 'instagram-widjet-js', 'igfeed', array( 'profile_url' => $this->url )  );
  }

}

new InstagramFeedWidget;

// instagram-widjet.js file
(function($){
  $(document).ready(function(){
    let igfeed = igfeed.profile_url;
    console.log(igfeed);

    const igFeed = new Vue({
      el: '#ig-feed',
      data: {
        feedImg: []
      },
      mounted: function(){
        axios.get(igfeed.profile_url).then( (response) => {
          console.log(response);
        });
      },
      methods: {

      }
    });

    const feedSwiper = new Swiper('.swiper-feed', {
      slidesPerView: 4,
      spaceBetween: 50,
      slidesPerGroup: 4,
      loop: true,
      autoplay: {
        delay: 5000
      },
      //loopFillGroupWithBlank: true,
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      },
    });


  });
}(jQuery));

I have a custom widget where the user can insert an username in an <input> field. It's working fine, but I need to get the inserted value from php and pass it to the javascript file that is enqueued with my widget plugin. I'm testing with wp_localize_script but it will not work and I'm unable to access the passed data if i do console.log. How I can fix this, is it possible to access data from php to plugin js file?

class InstagramFeedWidget extends WP_Widget {

  public $url;

  public function __construct()
  {
    parent::__construct(
      'instagram-widget',
      'Instagram feed',
      array(
        'description' => ''
      )
    );
    add_action( 'widgets_init', array($this, 'init') );
    add_action( 'wp_enqueue_scripts', array($this, 'initScripts' ) );
  }

  public function init()
  {
    register_sidebar(
      array(
        'name'        =>  'Instagram feed',
        'id'          =>  'ig-feed',
        'description' =>  'Instagram feed widget',
      )
    );
    register_widget( 'InstagramFeedWidget' );
  }

  public function widget( $args, $instance )
  {
    $this->url = 'https://instagram/'.$instance['username'].'?__a=1';


    // $ch = curl_init();
    // curl_setopt( $ch, CURLOPT_URL, $url );
    // curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Accept: application/json') );
    // curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
    // curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
    // $feed = curl_exec($ch);
    // curl_close($ch);
    // $data = json_decode( $feed , true);
    // ob_start();
    ?>
    <!-- <div class="jumbotron jumbotron-fluid ig-feed">
      <div class="container">
        <div class="row">
          <div class="col-sm-12 col-md-12 col-lg-12"> -->
            <div class="swiper-container swiper-feed" id="ig-feed">
              <div class="swiper-wrapper">
                <img class="swiper-slide feed-img" src="">
            <?php
              // foreach( $data['graphql']['user']['edge_owner_to_timeline_media']['edges'] as $node ){
              //   foreach( $node as $img ){
              //     echo '<div class="swiper-slide feed-img" style="background-image:url('.$img['display_url'].');"></div>';
              //   }
              // }
            ?>
              </div>
            <div class="swiper-button-prev "></div>
            <div class="swiper-button-next"></div>
            </div>
          <!-- </div> -->
        <!-- </div>
      </div>
    </div> -->
    <?php
    echo ob_get_clean();
  }

  public function form( $instance )
  {
    $username = isset( $instance['username'] ) ? esc_attr( $instance['username'] ) : '';
    ?>
    <p>
    <label for="<?php esc_attr( $this->get_field_id('username') ); ?>"><?php _e('Username'); ?></label>
    <input type="text" class="widefat" id="<?php echo esc_attr( $this->get_field_id('username') ); ?>" name="<?php echo esc_attr( $this->get_field_name('username') ); ?>" value="<?php echo esc_attr($username); ?>">
    </p>
    <?php
  }

  public function update( $new_instance, $old_instance )
  {
    $instance = $old_instance;

    $instance['username'] = esc_attr($new_instance['username']);

    return $instance;
  }

  public function initScripts()
  {

    wp_enqueue_style('instagram-widget', plugins_url( 'instagram-widget.min.css', __FILE__), array('swiper'), null);
    wp_enqueue_script('instagram-widget-js', plugins_url( 'instagram-widget.js', __FILE__), array('swiper'), null);
    wp_localize_script( 'instagram-widjet-js', 'igfeed', array( 'profile_url' => $this->url )  );
  }

}

new InstagramFeedWidget;

// instagram-widjet.js file
(function($){
  $(document).ready(function(){
    let igfeed = igfeed.profile_url;
    console.log(igfeed);

    const igFeed = new Vue({
      el: '#ig-feed',
      data: {
        feedImg: []
      },
      mounted: function(){
        axios.get(igfeed.profile_url).then( (response) => {
          console.log(response);
        });
      },
      methods: {

      }
    });

    const feedSwiper = new Swiper('.swiper-feed', {
      slidesPerView: 4,
      spaceBetween: 50,
      slidesPerGroup: 4,
      loop: true,
      autoplay: {
        delay: 5000
      },
      //loopFillGroupWithBlank: true,
      navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
      },
    });


  });
}(jQuery));

Share Improve this question edited Apr 5, 2020 at 16:30 cjbj 15k16 gold badges42 silver badges89 bronze badges asked Apr 5, 2020 at 15:42 sialfasialfa 32910 silver badges29 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 0

This is a timing issue, as you can see from the hook order. By the time you get to the dynamic_sidebar function that executes your widget code on the front end, you are already past the widgets_init and wp_enqueue_scripts hooks (the dynamic_sidebar hook is inside the function with that same name). You cannot enqueue scripts from a widget.

There are two ways to get around this:

  1. Write a function that accesses the widget data directly from the database (it's a multidimensional array which you can find with get_option(sidebars_widgets). You can bind this function to the wp_enqueue_scripts hook.
  2. In stead of properly enqueuing the script, just print it in the footer by using the wp_footer hook, which is still available when the widget code is executed.

By the way, wp_localize_script will work anywhere, as it just prints the variables the moment it is called.

发布评论

评论列表(0)

  1. 暂无评论