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 = 'https://instagram.com/'.$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));

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.

| improve this answer | |
  • I've solved using get_settings() method of WP_widget and then used wp_localize_script to pass the data – sialfa Apr 5 at 19:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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