Getting the Number of Twitter Followers Without Using the Twitter API

Twitter logo

Since Twitter upgraded the Twitter REST API to version 1.1 earlier this year, a simple HTTP query against the API no longer works. You now have to include authentication information which would require redevelopment of many programs that perform this previously simple action.

I wanted to include the number of Twitter followers on this blog using the Social Impact Widget, which was made for version 1 of the Twitter API.

Using the YQL language API from Yahoo, this information can still be retrieved by Web scraping, without resorting to using Twitter’s API. Aakash Chakravarthy’s article explains this method well.

By using this method, the PHP code in the Social Impact Widget can be modified to pull the number of Twitter followers via Web scraping.

The original PHP code for the widget that retrieves the Twitter data:

$return_Twitter = $this->_helper_curl(sprintf('https://api.twitter.com/1/users/show.json?screen_name=%1$s',
		$var_sTwitterId
	), $this->var_sUserAgent);

Remove this code and add the below, also making some changes to the try block immediately below it to change the way it stores the returned data:

$return_Twitter = $this->_helper_curl('http://query.yahooapis.com/v1/public/yql?q=SELECT%20*%20from%20html%20where%20url=%22http://twitter.com/' . $var_sTwitterId . '%22%20AND%20xpath=%22//a[@class='js-nav']/strong%22&format=json'
                    , $this->var_sUserAgent); // Opening the Query URL
	try {
		$obj_TwitterData = json_decode($return_Twitter);
		if($obj_TwitterData) {
			if(!empty($obj_TwitterData->query->results->strong[2])) {
				$this->array_Options[$this->var_sArrayOptionsKey]['twitter-count'] = intval(str_replace(',', '', $obj_TwitterData->query->results->strong[2]));
			} // END if(!empty($obj_TwitterData->query->results->strong[2]))
		} // ENDif($obj_TwitterData)
	} catch(Exception $e) {
		$this->array_Options[$this->var_sArrayOptionsKey]['twitter-count'] = (int) $var_iTwitterFollowerCount;
	}

And now, your widget will appear correctly! The caveat here is that if Twitter ever changes the layout of the site, then the line

$obj_TwitterData->query->results->strong[2]


will have to be modified accordingly.

Making the SyntaxHighlighter Evolved Plugin Work with Infinite Scroll on WordPress.org Sites

WordPress logo

SyntaxHighlighter Evolved is a great plugin to format source code on a WordPress.org blog. Also, WordPress.org blogs can now allow you to use Infinite Scroll, which uses AJAX to load posts as you scroll down the blog.

The problem is that once you begin scrolling past the first block of posts that were initially loaded, the posts loaded using Infinite Scroll no longer highlight the code.

The fix is to call the “SyntaxHighlighter.highlight()” method each time a block of posts are loaded.

I’m sure there are many ways this could be done. The way I chose was to take this block of code from the file “jetpack/modules/infinite-scroll/infinity.php”:

// If primary and fallback rendering methods fail, prevent further IS rendering attempts. Otherwise, wrap the output if requested.
if ( empty( $results['html'] ) ) {
    unset( $results['html'] );
    do_action( 'infinite_scroll_empty' );
    $results['type'] = 'empty';
} elseif ( $this->has_wrapper() ) {
    $wrapper_classes = is_string( self::get_settings()->wrapper ) ? self::get_settings()->wrapper : 'infinite-wrap';
    $wrapper_classes .= ' infinite-view-' . $page;
    $wrapper_classes = trim( $wrapper_classes );

    $results['html'] = '<div class="' . esc_attr( $wrapper_classes ) . '" id="infinite-view-' . $page . '" data-page-num="' . $page . '">' . $results['html'] . '</div>';
}

and add this one line to the block:

$results['html'] .= '<script type="text/javascript">SyntaxHighlighter.highlight();</script>';

resulting in this block:

// If primary and fallback rendering methods fail, prevent further IS rendering attempts. Otherwise, wrap the output if requested.
if ( empty( $results['html'] ) ) {
    unset( $results['html'] );
    do_action( 'infinite_scroll_empty' );
    $results['type'] = 'empty';
} elseif ( $this->has_wrapper() ) {
    $wrapper_classes = is_string( self::get_settings()->wrapper ) ? self::get_settings()->wrapper : 'infinite-wrap';
    $wrapper_classes .= ' infinite-view-' . $page;
    $wrapper_classes = trim( $wrapper_classes );

    $results['html'] = '<div class="' . esc_attr( $wrapper_classes ) . '" id="infinite-view-' . $page . '" data-page-num="' . $page . '">' . $results['html'] . '</div>';
    $results['html'] .= '<script type="text/javascript">SyntaxHighlighter.highlight();</script>';
}

Save the file and reload your blog. All code blocks should now be highlighted as you scroll!

Using the PHP explode() Function to Get Text Between Slashes of a URL

PHP logo

In the About.Me widget that I currently have on the right sidebar of this blog, there are quite a few HTML image tags used for the different social networks linked below the photo and bio.  None of these img tags had alt tags, which are used by Web crawlers when indexing websites.  Many SEO experts suggest having alt tags on most image tags, so I decided to fill these with the name of the service and my name.  The original PHP code that generates these icons, which is found in the “aboutme-widget/aboutme-widget.php” file on my WordPress.org site, is here:

foreach ( $data['app_icons'] as $v ) {
echo '<a href="' . esc_url( $v['url'] ) . '" target="_blank" class="am_service_icon" rel="me"><img src="' . esc_url( $v['icon'] ) . '" ></a>';
 }

Emitted HTML:

<a href="http://www.twitter.com/DeepInTheCode" target="_blank" class="am_service_icon" rel="me"><img src="http://dcbdluf1ahqio.cloudfront.net/twitter/32x32.png"></a>
<a href="http://www.linkedin.com/in/deepinthecode" target="_blank" class="am_service_icon" rel="me"><img src="http://dcbdluf1ahqio.cloudfront.net/linkedin/32x32.png"></a>
<a href="http://plus.google.com/101089969483487596905/" target="_blank" class="am_service_icon" rel="me"><img src="http://dcbdluf1ahqio.cloudfront.net/googleplus/32x32.png"></a>

As you can see, the source of the image is stored in the array element “$v[‘icon’]”, and has the format “http://(apparently random string).cloudfront.com/(service name)/32×32.png”.  I wanted to get the service name from each URL.  At first blush, this sounds like a regular expression problem.  However, while it is sometimes necessary, regex is often not the most elegant solution.

The PHP explode() function is perfect for this problem.  Essentially, I needed to build an array of strings from the URL and select the second from the last element of the array.  Since I didn’t need to keep this array intact, I treated it like a stack and used array_pop() to pop off the last two elements.  The code below was inserted into the foreach loop before the echo statement:

$iconarray = explode('/',$v['icon']);
 array_pop($iconarray);
 $servicename = array_pop($iconarray);

For each iteration of the loop, the $servicename variable will now hold the string that is before the last slash in the URL stored in $v[‘icon’].  I also wanted to capitalize the first character in the service name, and add ” profile for David Young” after each service name.  Since my name is stored in the array elements $data[‘first_name’]  and $data[‘last_name’], I used those in modifying the echo statement to make this code reusable by others — or by About.Me, should they decide to incorporate it into future versions of their code.

The complete loop now looks like this:

foreach ( $data['app_icons'] as $v ) {
$iconarray = explode('/',$v['icon']);
array_pop($iconarray);
$servicename = array_pop($iconarray);
echo '<a href="' . esc_url( $v['url'] ) . '" target="_blank" class="am_service_icon" rel="me"><img src="' . esc_url( $v['icon'] ) . '" alt="' . ucfirst($servicename) . ' profile for ' . esc_attr( $data['first_name'] ) . ' ' . esc_attr( $data['last_name'] ) . '"></a>';
 }

Emitted HTML:

<a href="http://www.twitter.com/DeepInTheCode" target="_blank" class="am_service_icon" rel="me"><img src="http://dcbdluf1ahqio.cloudfront.net/twitter/32x32.png" alt="Twitter profile for David Young"></a>
<a href="http://www.linkedin.com/in/deepinthecode" target="_blank" class="am_service_icon" rel="me"><img src="http://dcbdluf1ahqio.cloudfront.net/linkedin/32x32.png" alt="Linkedin profile for David Young"></a>
<a href="http://plus.google.com/101089969483487596905/" target="_blank" class="am_service_icon" rel="me"><img src="http://dcbdluf1ahqio.cloudfront.net/googleplus/32x32.png" alt="Googleplus profile for David Young"></a>