Make your own Twitter ticker using PHP, CSS3, and JavaScript

I made a little Twitter ticker for work the other day, which will fetch posts with a particular hashtag and then animate them marquee style across the screen, I thought I may as well share it here. This version will fetch the last 100 tweets to the #rstats hashtag, remove the retweeets, and then show up to 50 animated across the screen.

All of the Twitter authentication PHP magic is stolen from here.

I’m afraid the usual health warnings apply, I have no special talents in HTML, CSS, JavaScript, or PHP, I am learning all three, so this code merely works- it is not necessarily the best way of doing it.

In the first chunk of HTML we pull in the jQuery library and include a JavaScript function.


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
<title>Invest to lead</title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta name="generator" content="Geany 1.23.1" />
  <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<script type="text/javascript">

The JavaScript function ensures that the animation runs at a constant speed regardless of how long the text is. Because the CSS3 animation takes a number of seconds as a parameter for how long the animation should run for, and because we have no way of knowing how long the text will be in advance, the JavaScript looks at the text at runtime and then scales the number of seconds the animation runs for by the length of the text. I then use jQuery to add it to the CSS instruction in the head of the html.

Much of the code is borrowed from here, I’ve fiddled with it slightly to make it do something slightly different.

The last instruction just tells the browser to reload when the animation finishes, which will restart the animation of course but also fetch new tweets.

		
function getStringWidth(str) {

  var span = document.createElement("span"); 
  span.innerText = str;
  span.style.visibility = "hidden";

  var body = document.getElementsByTagName("body")[0];
  body.appendChild(span);
  var textWidth = span.offsetWidth;
  body.removeChild(span);

  return textWidth;
}

$(document).ready(function(){
  var ele = document.getElementById("thisone").innerHTML.length;
	
  $('head').append("<style>.marquee p {-moz-animation: marquee " + (ele / 5) + "s linear;}</style>")
  $('head').append("<style>.marquee p {-ms-animation: marquee " + (ele / 5) + "s linear;}</style>")
  $('head').append("<style>.marquee p {-webkit-animation: marquee " + (ele / 5) + "s linear;}</style>")
  $('head').append("<style>.marquee p {animation: marquee " + (ele / 5) + "s linear;}</style>")
	
var myBox = $('#thep');
	
myBox.one('webkitAnimationEnd oanimationend msAnimationEnd animationend',   
  function(e) {
    
    location.reload();

  });
	
}) 

</script>
<style>

The next part is the non-dynamic CSS, not much to say about this, again stolen from here

.marquee {
    white-space: nowrap;
	overflow: hidden;
}

.marquee p {
  position: absolute;
  bottom: 50px;
  font-size: 72px;

  -moz-transform:translateX(2%);
  -webkit-transform:translateX(2%);
  -ms-transform:translateX(2%);
  transform:translateX(2%);
	
}

  /* Make it move */
	
  @-moz-keyframes marquee {
    0%   { -moz-transform:translateX(2%) }
    100% { -moz-transform:translateX(-100%) }
  }
	
  @-ms-keyframes marquee {
    0%   { -ms-transform:translateX(2%) }
    100% { -ms-transform:translateX(-100%) }
  }
	
  @-webkit-keyframes marquee {
    0%   { -webkit-transform:translateX(2%) }
    100% { -webkit-transform:translateX(-100%) }
  }
	
  @keyframes marquee {
    0%   { transform:translateX(2%) }
    100% { transform:translateX(-100%) }
  }

I’ve included the next couple of lines of HTML for completeness.

	
</style>

</head>

<body>
	
<div id = "thisone" class="marquee">

This next part is the bit that fetches the tweets using PHP. It’s pretty simple if you follow the guide I link to at the top of the post. The only difficulty I had was parsing what comes back from the API, you can convert from JSON (as below) and you will end up with loads of nested associative arrays. It’s just a case of picking your way through by using print_r().

As you can see in my code below most of the interesting stuff lives in $response_data[“statuses”] (or maybe it all does, I never quite got to the bottom of it to be honest) and I check to see if the array key ‘retweeted_status’ exists within that array and (if it doesn’t, i.e. it’s not a retweet) then I print $response_data[“statuses”][“user”][“name”] and $response_data[“statuses”][“text”]

	
<?php
 
require 'app_tokens.php';
require 'tmhOAuth.php';

$connection = new tmhOAuth(array(
  'consumer_key'    => $consumer_key,
  'consumer_secret' => $consumer_secret,
  'user_token'      => $user_token,
  'user_secret'     => $user_secret
));

// Get tweets
$connection->request('GET', $connection->url('1.1/search/tweets.json'), array(
  'q' => '#rstats',
  'count' => 100
));

// Get the HTTP response code for the API request
$response_code = $connection->response['code'];

// Convert the JSON response into an array
$response_data = json_decode($connection->response['response'],true);

// A response code of 200 is a success
if ($response_code <> 200) {
  print "Error: $response_code\n";
}

$counttweets = 0;

echo "<p id = 'thep'>";

foreach ($response_data["statuses"] as $result) {
	
	if (!array_key_exists('retweeted_status', $result))
	{
		echo $result["user"]["name"] . ": ";
		echo $result["text"]." *** ";
		if($counttweets++ > 50) break;
	}
}
echo "This twitter feed brought to you by Chris Beeley enterprises</p>";

?>

Last chunk of HTML for completeness.


</div>

</body>

</html>

And that’s it! It occurs to me that it would be very easy to add a GET function and allow searching of any hashtag by placing it in the URL. If I ever need to do this or get bored and decide to have a go I’ll add it to this post. There’s a demo of the feed here.

Book review: Learning PHP, MySQL, JavaScript, and CSS, 2nd Edition

Full disclosure: I received this ebook free under the O’Reilly Reader Review Programme.

This is a review of Learning PHP, MySQL, JavaScript, and CSS, 2nd Edition by Robin Nixon.

As you can tell by the title this is a big book that covers a lot of material. There is a decent treatment of PHP, MySQL, JavaScript, and CSS within this book. When I came to it I knew nothing about PHP, a little MySQL, a smidgen of JavaScript, and a little bit of CSS and could follow each of the sections without too much difficulty.

The book starts off by looking at the fundamentals of programming (loops, functions, classes etc.) using PHP. To my mind it’s doubtful that anybody who came to this book without these basic concepts would be able to follow the book throughout its entirety without having recourse to other resources- in particular, I don’t think programming with objects can be learned from such humble beginnings. There’s nothing intrinsically wrong with that, but it does make one question whether the rudiments might have been better explained at the level of an amateur (as opposed to novice) programmer just to get the material moving a bit. In my view PHP is not an obvious place to start learning to program because it is very sloppy and quirky but of course all languages have pros and cons for beginners (my first language was R, which is probably an even worse choice of first language).

The first couple of chapters also cover setting up a development environment (a WAMP/ MAMP/ LAMP stack, essentially), there is a slight focus on WAMP/ MAMP (by the book’s own admission) which doesn’t fit my own Linux-based prejudices but you may well be glad of it.

I read this book with a very specific goal in mind, to design and build a database and web frontend for a project at work and this book has been very valuable in that goal. The chapters build nicely, teaching the fundamentals of PHP and MySQL and then exploring how to integrate them, and then looking at enhancing web content using JavaScript, Ajax, and CSS. It does feel a little bit like you are just scratching the surface with CSS because it is such an enormous topic on its own and although I learned a lot of techniques I was left a little unsure as to how to put it all together.

The book also covers important security and login features, such as using cookies to track logged in users, the difference between GET and POST requests, and there is a commendable emphasis on how to avoid SQL/ JavaScript injection, including a couple of functions to help prevent this kind of activity.

The final chapter covers an entire application which uses all of the material from previous chapters (building a rudimentary social networking site) and it was very heartening as a beginner to appreciate just how much can be achieved with a comparatively small amount of code.

This book certainly did what it says on the tin for me and I am using PHP/ MySQL for work as a consequence of having read and used it.

There is one big caveat which is that although it is quite a new book, it does include some deprecated functions. How you feel about this will depend on what you are using the book for and your pre-existing familiarity with PHP/ MySQL and associated technologies. For my part I used the book to get the basic idea of the code, how it fitted together, how to communicate between PHP/ MySQL/ HTML and so on. The inclusion of a few deprecated functions, while not ideal, does not detract from the book for me and I will no doubt come back to my code and update it once I have everything working and having better skills writing and debugging this type of code. If you are quite experienced and want a reference to industry standard programming that you can blast through and put up on a production server the inclusion of deprecated code will be of more concern to you (if you’re this far on the spectrum the book is probably too simple for you anyway, but it illustrates my point about what you’re using the book for).

Overall I would say this book teaches the ecosystem of PHP/ MySQL/ HTML very well and if you wish to learn that ecosystem from a reasonably novice grasp of programming it will serve you well. Absolute beginners and more expert users may wish to look elsewhere.