Loading Hasty Logo
Blog
Create a Instagram feed widget for your WordPress site
Tutorials
12. December 2017
timelapseEstimated reading time:

Create a Instagram feed widget for your WordPress site

How to show the latest posts from a Instagram channel on your WordPress site with a widget

Instagram Widget Tutorial

In this WordPress Tutorial we will create a easy-to-use Instagram feed widget. The Instagram widget automatically show the latest posts from a Instagram channel of your choice including the image and caption of the post. The posts will be linked to the Instagram profile.

  • Step 1: Creating the widget
  • Step 2: Get the data from instagram
  • Step 3: Style the widget

Step 1: Creating the widget

First of all we’re going to create a widget with the widget generator from Hasty. In this widget we need two fields, one for typing in the username of the instgram channel, which we are going to display. And in the second one we can choose how many posts we want to show in the Instgram widget.

Copy the following or your own created code and paste it at the end of your functions.php or in some other file, which will be loaded by your WordPress Theme.

/**
* Adds Instagram Feed widget
*/
class Instagramfeed_Widget extends WP_Widget {

	/**
	* Register widget with WordPress
	*/
	function __construct() {
		parent::__construct(
			'instagramfeed_widget', // Base ID
			esc_html__( 'Instagram Feed', 'textdomain' ), // Name
			array( 'description' => esc_html__( 'Displays the latest Instgram posts', 'textdomain' ), ) // Args
		);
	}

	/**
	* Widget Fields
	*/
	private $widget_fields = array(
		array(
			'label' => 'Instgram Username',
			'id' => 'insta_username',
			'type' => 'text',
		),
		array(
			'label' => 'How many posts to display?',
			'id' => 'insta_posts',
			'type' => 'number',
		),
	);

	/**
	* Front-end display of widget
	*/
	public function widget( $args, $instance ) {
		echo $args['before_widget'];

		// Output widget title
		if ( ! empty( $instance['title'] ) ) {
			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
		}

		// Output generated fields
		echo '<p>'.$instance['insta_username'].'</p>';
		echo '<p>'.$instance['insta_posts'].'</p>';
		
		echo $args['after_widget'];
	}

	/**
	* Back-end widget fields
	*/
	public function field_generator( $instance ) {
		$output = '';
		foreach ( $this->widget_fields as $widget_field ) {
			$widget_value = ! empty( $instance[$widget_field['id']] ) ? $instance[$widget_field['id']] : esc_html__( $widget_field['default'], 'textdomain' );
			switch ( $widget_field['type'] ) {
				default:
					$output .= '<p>';
					$output .= '<label for="'.esc_attr( $this->get_field_id( $widget_field['id'] ) ).'">'.esc_attr( $widget_field['label'], 'textdomain' ).':</label> ';
					$output .= '<input class="widefat" id="'.esc_attr( $this->get_field_id( $widget_field['id'] ) ).'" name="'.esc_attr( $this->get_field_name( $widget_field['id'] ) ).'" type="'.$widget_field['type'].'" value="'.esc_attr( $widget_value ).'">';
					$output .= '</p>';
			}
		}
		echo $output;
	}

	public function form( $instance ) {
		$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( '', 'textdomain' );
		?>
		<p>
		<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'textdomain' ); ?></label>
		<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>
		<?php
		$this->field_generator( $instance );
	}

	/**
	* Sanitize widget form values as they are saved
	*/
	public function update( $new_instance, $old_instance ) {
		$instance = array();
		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
		foreach ( $this->widget_fields as $widget_field ) {
			switch ( $widget_field['type'] ) {
				case 'checkbox':
					$instance[$widget_field['id']] = $_POST[$this->get_field_id( $widget_field['id'] )];
					break;
				default:
					$instance[$widget_field['id']] = ( ! empty( $new_instance[$widget_field['id']] ) ) ? strip_tags( $new_instance[$widget_field['id']] ) : '';
			}
		}
		return $instance;
	}
} // class Instagramfeed_Widget

// register Instagram Feed widget
function register_instagramfeed_widget() {
	register_widget( 'Instagramfeed_Widget' );
}
add_action( 'widgets_init', 'register_instagramfeed_widget' );
Copy to clipboard
Class for our own Instagram Widget

Step 2: Get the data from instagram

The widget you created in step 1 is now available in your WordPress Backend. Put it in a sidebar of your choice and fill out the fields with some sample data.

Instagram Feed Widget for WordPress with sample data

Fill out some sample data: The Instagram username and the number of posts

Now go back to your new created widget class to the section ‘Front-end display of widget’. Remove the 2 lines after ‘// Output generated fields’

And add the following line:

$instaResult = json_decode(file_get_contents('https://www.instagram.com/'.$instance['insta_username'].'/?__a=1'), true);
Copy to clipboard

With this technique we can fetch data from any public Instagram account by just creating a url with the given username. With the function ‘file_get_contents’ we are retrieving a json-string, which we decode and convert it to an array with the function ‘json_decode’.

Your code should look like this:

/**
	* Front-end display of widget
	*/
	public function widget( $args, $instance ) {
		echo $args['before_widget'];

		// Output widget title
		if ( ! empty( $instance['title'] ) ) {
			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
		}

		// Output generated fields
		$instaResult = json_decode(file_get_contents('https://www.instagram.com/'.$instance['insta_username'].'/?__a=1'), true);
		
		echo $args['after_widget'];
	}
Copy to clipboard

With the new created array we can output our Instagram posts with a foreach loop. In this loop where outputting the image and the caption of each post. Additionally we are linking it to the Instagram Channel. I’m not going to deep on this.

Your final PHP code should look something like this:

/**
* Adds Instagram Feed widget
*/
class Instagramfeed_Widget extends WP_Widget {

	/**
	* Register widget with WordPress
	*/
	function __construct() {
		parent::__construct(
			'instagramfeed_widget', // Base ID
			esc_html__( 'Instagram Feed', 'textdomain' ), // Name
			array( 'description' => esc_html__( 'Displays the latest Instgram posts', 'textdomain' ), ) // Args
		);
	}

	/**
	* Widget Fields
	*/
	private $widget_fields = array(
		array(
			'label' => 'Instgram Username',
			'id' => 'insta_username',
			'type' => 'text',
		),
		array(
			'label' => 'How many posts to display?',
			'id' => 'insta_posts',
			'type' => 'number',
		),
	);

	/**
	* Front-end display of widget
	*/
	public function widget( $args, $instance ) {
		echo $args['before_widget'];

		// Output widget title
		if ( ! empty( $instance['title'] ) ) {
			echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
		}

		// Output generated fields
		$instaResult = json_decode(file_get_contents('https://www.instagram.com/'.$instance['insta_username'].'/?__a=1'), true);
		
		$i = 0;
		foreach( $instaResult['user']['media']['nodes'] as $image ) {
            if ($i < $instance['insta_posts']) {             
                echo '<div class="instapost-wrapper">';
				echo '<a target="_blank" title="To Instagram" href="https://www.instagram.com/'.$instance['insta_username'].'/">';
				echo '<div class="instapost">';
				echo '<img src="'.$image['thumbnail_src'].'" />';
				echo '<div class="caption">'.$image['caption'].'</div>';
				echo '</div>';
				echo '</a>';
                echo '</div>';
            } else {
                break;
            }
            $i++;
        };
		
		echo $args['after_widget'];
	}

	/**
	* Back-end widget fields
	*/
	public function field_generator( $instance ) {
		$output = '';
		foreach ( $this->widget_fields as $widget_field ) {
			$widget_value = ! empty( $instance[$widget_field['id']] ) ? $instance[$widget_field['id']] : esc_html__( $widget_field['default'], 'textdomain' );
			switch ( $widget_field['type'] ) {
				default:
					$output .= '<p>';
					$output .= '<label for="'.esc_attr( $this->get_field_id( $widget_field['id'] ) ).'">'.esc_attr( $widget_field['label'], 'textdomain' ).':</label> ';
					$output .= '<input class="widefat" id="'.esc_attr( $this->get_field_id( $widget_field['id'] ) ).'" name="'.esc_attr( $this->get_field_name( $widget_field['id'] ) ).'" type="'.$widget_field['type'].'" value="'.esc_attr( $widget_value ).'">';
					$output .= '</p>';
			}
		}
		echo $output;
	}

	public function form( $instance ) {
		$title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( '', 'textdomain' );
		?>
		<p>
		<label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'textdomain' ); ?></label>
		<input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
		</p>
		<?php
		$this->field_generator( $instance );
	}

	/**
	* Sanitize widget form values as they are saved
	*/
	public function update( $new_instance, $old_instance ) {
		$instance = array();
		$instance['title'] = ( ! empty( $new_instance['title'] ) ) ? strip_tags( $new_instance['title'] ) : '';
		foreach ( $this->widget_fields as $widget_field ) {
			switch ( $widget_field['type'] ) {
				case 'checkbox':
					$instance[$widget_field['id']] = $_POST[$this->get_field_id( $widget_field['id'] )];
					break;
				default:
					$instance[$widget_field['id']] = ( ! empty( $new_instance[$widget_field['id']] ) ) ? strip_tags( $new_instance[$widget_field['id']] ) : '';
			}
		}
		return $instance;
	}
} // class Instagramfeed_Widget

// register Instagram Feed widget
function register_instagramfeed_widget() {
	register_widget( 'Instagramfeed_Widget' );
}
add_action( 'widgets_init', 'register_instagramfeed_widget' );
Copy to clipboard
Final PHP-Code: Append it to your functions.php
Instagram Feed Widget Front-End unstyled

In the frontend of your site you should now see some Instagram-Posts

Step 3: Styling the output

In step 3 we are doing some simple styling with CSS and creating a lovely hover-effect, which shows us the caption and hashtags only on hovering the Instagram post.

/*--------------------------------------------------------------
Instagram Widget
--------------------------------------------------------------*/
.instapost-wrapper {
	position: relative;
	display: inline-block;
	width: 50%;
	vertical-align: top;
	overflow: hidden;
}

.instapost-wrapper a .instapost img {
	display: block;
	margin: 0;
	padding: 0;
	width: 100%;
	box-shadow: none; 
}

.instapost-wrapper a .instapost .caption {
	position: absolute;
	top: 0;
	left: 100%;
	width: 100%;
	height: 100%;
	padding: 10px;
	color: #fff;
	background: rgba(0,0,0,.7);
	font-size: 13px;
	opacity: 0;
	transition: .2s all ease-in-out;
	-webkit-transition: .3s all ease-in-out;
}

.instapost-wrapper:hover a .instapost .caption { 
	opacity: 1;
	left: 0;
}
Copy to clipboard
Optimized for the theme: Twenty Seventeen

The final Instagram feed should look something like this. With some basic CSS you can fit it to your needs.