How to make a rich movie search interface with instant trailers

Today a quick post to show you a new feature I rolled out last week on sharemovi.es: #nw or Now Watching. Go check it out here. In this post some printscreens and a what technologies I used

rich autocomplete

More on the technology behind it

New here? You might want to subscribe to my blog by email or RSS.

When you start to type a movie name it queries themoviedb.org API for movie info. The API seems quite complete and the response it fast. I thought name, poster, year, rating and short summary extract would be most relevant ... and ... the trailer. You see the red youtube button? Well ... when you hover with your mouse over the whole row, the trailer loads in the white box. All thanks to some jQuery - see the JS code; in order to not make too many calls to themoviedb.org API, I use YQL to dynamically look up the trailer. You can also use Gdata/ Youtube.

featured image

I use an autocomplete box from the jQuery UI, it comes with some nice styles incorporated. I rolled my own loader gif, but the real workhorses are PHP and jQuery, a powerful duo.

The 'autocomplete' function polls the API via search.php upon detected key strokes. I had to play a bit with 'renderItem' to show a rich result (poster, etc). Upon 'select' of a title, comment.php is called to generate a customized form with message and share buttons. The field is readonly (not editable), but clicking on the pencil, jQuery takes the readonly attribute off (removeAttr) so you can edit it.

I didn't include Twitter / Facebook APIs, just a link to the corresponding page with the right URL parameters. With FB dialogs you can give quite some options and it does not require authorization because the user has to submit the info anyway. The links get created in the .submit .. 'click' function (note the encodeURIComponent). A richer experience is using one of the APIs. As sharemovi.es has the FB API setup already, I will definitely build this in. I will also integrate this richer experience into sharemovi.es as a whole. I'd like movies to be added to sharemovi.es this way, manual or automagically.

Note the live function in the jQuery code: when you add new content without page refresh (Ajax), your JS needs to be made aware that that content is there, this is what 'live' is for.

Now the trailer bit: 'mouseenter' and 'mouseleave' are the functions responsible for loading/ hiding the trailer for each title. You see another $.post, but now to youtube.php which as said uses YQL to find the corresponding movie trailer. And it returns an iframe that fits nicely in the white mini-canvas.

So step-by-step:

1. Go to sharemovi.es/nw/ (or at the homepage click on "Now Watching" to use the embedded version).

2. Start to type a movie, you should see titles approximating what you type:

trailer autocomplete

3. When you hover over the row, you should see a trailer starting to play:

trailer playing

4. When you click on one of the movies, a share box slides down with a proposed text.

share box

5. Example of clicking Facebook button (I put the text "want to see this one" in as addition)
fb button

6. Same for twitter, however I clicked the pencil which made the field editable:
edit button clicked

7. And the result shown on Twitter before posting. Again with APIs this can all be slicker but I wanted an easy standalone example:
share on twitter

Update 18.01.2012

The complete source code is posted here. Enjoy ... and please leave me a comment if you use it somewhere ...

Comments are back on my blog: Disqus is the best!

I had some changes in blog comments last months. I tried URLs to Twitter and Facebook. Last week I added the Facebook comment box. Today however I will go back to Disqus, a service that guarantees easy and rich blog engagement.

Reasons I got back to Disqus:

  • URLs to Twitter and Facebook was very limited. Why only these two networks? Why linking out of the site? One of the ideas behind blogging is interaction by sharing and discussing content, I wanted this to be brought back to this blog. Disqus is ideal meeting this purpose.
  • Disqus has a good spam filter
  • Notifications and replies via email, dashboard and wide set of features (follow users, liking, etc.)
  • Login with Facebook, Google, Yahoo etc, you can also post from within the comment to Twitter or Facebook.
  • New here? You might want to subscribe to my blog by email or RSS.

  • Ability to be more anonymous than Facebook (which only put more personal data in their new comment box release). It turns out that this is favorable as FB identity can hold people back to post comments that indeed are valuable for deepening the subject and building relationships.
  • No SEO problem, content gets indexed now , for example :
  • my comment indexed on google

  • Facebook has its pros and cons (see tech crunch or my blog post : in spite of the "cool feats", I am having several issues with this plugin. In v1 of the plugin comments are getting lost when using the v2 (even with "migrated=1" flag), messages are not showing up in the Moderator's panel, all together pretty annoying. I still use the plugin on other sites and it is definitely neat if conversations go back and forth between the post and FB walls of the commenters. However, Disqus has turned out to be a much more reliable service for me.
  • featured image

  • CSS: Disqus fits in seamlessly. Facebook's comment box has still a FB feel which I generally like (see other plugins on this site), but for others it is a deal-breaker. The look and feel of Disqus integrate very well into my blog!
  • I had some legacy comments which I could not easily fit into any new solution; re-opening Disqus makes the design feel more consistent now, and users can still reply on old comments (according to the stats, even 9 months old posts are still read daily!)

The Disqus Wordpress plugin is available here

Talking about comments, what is your favorite blog comment service?

SELECT * FROM Internet: examples of YQL, a powerful API crawler

YQL (Yahoo! Query Language) is not new, however the concept of a Web Service that accesses Internet data with SQL-like commands, is really cool so should be mentioned on this blog!

featured image

The Yahoo! Query Language is an expressive SQL-like language that lets you query, filter, and join data across Web services. YQL hides the complexity of Web service APIs by presenting data as simple tables, rows, and columns.

In this post I work out some examples using YQL to find data of different sources. A good intro article is: Building web applications with YQL and PHP, Part 1, another very useful resource is Using YQL Sensibly - YUIConf 2010 (Christian Heilmann)

The YQL console lets you quickly test commands. Note if you click the blue button (table name) at the right you can get help building your queries, or use DESC to describe the table structure:

help query building

From here on some examples, some easy, others a bit more advanced. Of course a lot more is possible, I still need to experiment more ...

All tweets with my domain in it (or handle)

select * from twitter.search where q='bobbelderbos.com'

Note that I use a standard php script to parse the results. You can get it from here. Alternatively you can use curl

   <?php
   $yql = "select * from twitter.search where q='bobbelderbos.com'";  
   // or handle bbelderbos
   $query = "http://query.yahooapis.com/v1/public/yql?q=";
   $query .= urlencode($yql);
   $query .= "&format=json&env=store://datatables.org/alltableswithkeys";
   $info = file_get_contents($query, true);
   $info = json_decode($info); // echo "<pre>"; print_r($info ); 
   	echo "</pre>"; exit; 
   
   foreach($info->query->results->results as $item) { 
  		// query->results->results might differ
   	//process results
   }
   ?>

Get the latest posts from my blog feed

select title, link from rss where url="http://bobbelderbos.com/feed/rss/"

Grabbing html from a page

See an example here how this is done. It shows you how you can get the XPath from firebug, see the screenshot below (corresponding to the 3rd example below):

copy xpath from firebug

Examples of web scraping:

Original MTV movie site:

movie mashup mtv

After getting data with YQL, and styling a bit:

movie mashup result

Open data tables

With the addition of Open Data Tables, developers from anywhere can contribute YQL Tables to describe any data source on the Web, making YQL easily extensible. Today, there are more than thousand community contributed tables! You can easily build your own data tables - the source code of already committed tables is on github

yql tables

Get youtube videos for instant trailers

select * from youtube.search where query='scarface trailer' limit 5

youtube response

Get movie reviews from NY times movie API

SELECT * FROM nyt.movies.reviews WHERE apikey="---" and query="inception" (again, could be interesting to add to to sharemovi.es ...)

ny times movie reviews

Get book info from google books API

This example poors the YQL parsed results in a juery/php autocomplete

SELECT * FROM google.books WHERE q='javascript' AND maxResults=10 AND startIndex=2

google books autocomplete

Links and resources

Again, you can go much further, YQL is very powerful: embedded queries, create/import your own tables, a lot more APIs (some require keys like Amazon, Facebook, Twitter and Lastfm). Below some extra resources:

Are you using YQL?

I hope you enjoyed this post. Feel free to comment below what your experience is with YQL and/or what you would get out of this service ...

Facebook API: how to post TO a page and AS the page

Today I will show you how you can post to Facebook pages with the identity of those pages. One of my readers came up with this question and truth is it is useful if you have various pages to administer.

How does it work?

  • As usual you need to first install a copy of the Facebook PHP SDK to authenticate user/app/permissions.
  • Then you need to make sure you have the manage_pages permission
  •    // Login or logout url will be needed depending on current user state.
       if ($user) {
        $logoutUrl = $facebook->getLogoutUrl();
       } else {
        $loginUrl = $facebook->getLoginUrl(
      			array('scope'=>'manage_pages,publish_stream')
        );
       }
    
  • Note that once you have the manage_pages permission each page requires its own access code, which you can see below:
  •    ..
       		<select name="page_to">
       			<?php
       			$result = $facebook->api("/me/accounts");
       			foreach($result["data"] as $page) { 
       				if($page["category"] == "Application") {
       					continue; // app pages dont work for this exercise
       				}
       				echo '<option value="'.$page["id"].'" ';
       				if ($page["id"] == $page_to) {
       					echo ' selected="selected"';
       				}
       				echo '>'. $page["name"] . '</option>' ;
       			}   
       			?>
       		</select>
       ..
    

Try it yourself

Go to this page and log in with FB, you will be asked to grant the "manage_pages" permission. Then the page shows a list of all your Facebook pages with an option to post to each one of them.

So this is a quick and easy way to administer all your pages. You can see this in action in the video demo below:

Code

The code can be downloaded here - after putting it on your domain, you need to add your URL your FB App configuration page. Then you need to update "your app id" and "your app secret" with the App codes.

Yii 1.1 Application Development Cookbook

Disclaimer: I received a copy of this book from Packt to review

Yii 1.1 Application Development Cookbook, released by Packt Publishing, covers over 80 recipes about a wide variety of common Yii challenges. Written by Alexander Makarov, one of the core developers of the framework, the book is full of medium to advanced solutions.

Structure of the book

    featured image

  • The first two chapters offer a reference to core framework functionality (controller/ model/ view, URL routing and Yii features like autoloading and widgets).
  • Chapter 3 deals with AJAX by means of the jQuery JS library, which is well integrated into Yii.
  • Chapter 4 offer form gems: validation, uploading files and some nice CAPTCHA tricks.
  • In chapter 5, Testing, you install PHPUnit, Selenium server and Xdebugs to write unit and functional tests.
  • Chapter 6 is all databases and Active Record. You learn to connect to multiple Databases and other tricks, like implementing single table inheritance
  • Using grids and lists with the Yii-bundled Zii library, is what you will learn in chapter 7.
  • The recipes of chapter 8 all focus on making Yii extensible. It shows you how to create widgets (with Google API), CLI commands, a wiki module and more.
  • Chapter 9 shows the ins- and outs of log review, analyzing exception stack traces, and implementing error handlers.
  • Chapter 10 - Security: recipes to prevent common vulnerabilities: XSS, SQL injection, CSRF, at last a recipe about RBAC
  • Chapter 11 - Performance: how to speed up sessions, general best practices, caching and profiling (looking for bottlenecks in the Yii blog demo app).
  • New here? You might want to subscribe to my blog by email or RSS.

  • Chapter 12 shows how to use external code (Zend, Kohana, PEAR) in Yii.
  • At last, chapter 13, has recipes about deploying your app to your server.

Style

The writing style is clear. I liked the format used throughout the book: from preparation "Getting ready", to coding "How to do it ...", to explanation "How it works ...", to more info "There is more ...", to similar recipes "See also".

Like most cookbooks you can randomly jump in, each recipe is standalone. Basic to intermediate knowledge is required to fully grasp the recipes. To learn about Yii and develop an app A-Z, I recommend to first read Packt's first Yii title and the definite guide

Conclusion

This cookbook should be on your desk when you have to get your hands dirty with Yii. It is about practical problem solving with focus on the 'how-to', not the 'why'. Sometimes the 'why' could have been given a bit more thought, but again, a cookbook is pragmatic, problem + solution, and compared to other cookbooks this one does the job pretty well!

I think this is one of the few resources on Yii development. I am still a Yii newbie, but this book did convince me that Yii is an important ingredient for any PHP Web Developer's toolbox. Conceptionally it is a high quality and efficient framework. And it might make you happier: the recipes might save you time. So I think, after managing the basics, and getting some experience coding in Yii, this book can make you proficient.

Links

Your own movie database in 5 minutes with IMDb API and Perl

Update 23.02.2016: I rewrote/improved this script in Python, dropping the database bit, focussing on getting a nice movie page of a list of movies. Cleaner code, better performance (< 1 minute)

In this post I will show you how you can easily import IMDb data for your movies and process the XML to get SQL for database import. From there you can start to build your movie site.

IMDb API

In this post I use a small DVD collection. The movie data (director, actors, year published, etc.) are from IMDb and thanks to IMDb API (Brian Fritz), you get the data easily via curl. At the end of this post you can see a 5 min video demo of the whole process.

How it works

  • First I create a database and insert the movie collection table: table.sql - all code is here
  • getMovieData.pl serves to import the movie data from the API with curl and converts the XML to SQL. The escapeSingleQuote function allows the output to contain single quotes.
  • batch.pl is a little wrapper to run the getMovieData.pl on each title of the movie list you provide as input file. So for the movielist.txt example file you get 41 INSERT statements.

Conclusion

In 3 simple steps you get a complete set of data for each movie title, in a standardized format. Importing this data in a database allows for easy app development. You can quickly lookup what movies you have of your favorite actor or director, what movies were released in 2009, which movies were highest rated or had the most votes, etc. Having the data in a database, makes life easier :)

An example in PHP

example_movieCollection_site
- code -

Video Demo

Feedback

Update 22.11.2011

Comments and suggestions regarding this post on hacker news. There are some improved versions of the perl script, for example here. I appreciate your feedback to improve my Perl skills. What the IMDB TOS is concerned: this is for personal use only.

How to create a customized Google+ Share button

A quick post about something I was looking for some time, a way to share links to Google+ from outside their service. There are two interesting options available now.

featured image

Since I did a complete remake of my site, I like all components to fit in as I want. I went with different share buttons solutions in the past but I found them too cluttered. Hence the small black buttons for Twitter and Facebook at the top and bottom. I also wanted Google+ to join the game, but the +1 button did not present you with options for sharing (message box, your circles). Most important was that the +1 button did not fit my web design. It seemed that there was not an easy way to share URLs from outside Google+.

I did a new search today and I was pleasantly surprised that solutions are available now:

  • This first solution from Alex Moss uses the URL from the Google+ mobile site to present a popup with the current URLs content. It is pretty neat stuff.
  • I went on reading some of the comments of that solution and I found a Simple Google+ Bookmarklet by AJ Batac. Clicking the first link I was surprised to see a popup with the same look and feel as Google+. I was slightly confused with the "..You publicly +1..as .." message (which does not mean you +1-ed or posted anything yet). However, when I clicked in the textfield below this message, I saw the rich URL info with the circles to share with, just as if I was inside Google+ :
  • view of popup

So big thanks to Alex Moss and AJ Batac for developing this!

Implementation

I choose the 2nd solution for now and as you see I have my own small Plus button above and below this article :)

JS will dynamically grab the active URL and title, and Google+ finds the metainfo (similar to Facebook Like which does this somewhat better to my taste)

I added spaces for clarity :

<div class="bookmarklet">
<a href="
	javascript:(
	  function(){
		var w=480;var h=380;
		var x=Number((window.screen.width-w)/2);
		var y=Number((window.screen.height-h)/2);
		window.open('https://plusone.google.com/_/+1/confirm?hl=en&url='+encodeURIComponent(location.href)+'
			&title='+encodeURIComponent(document.title),'','width='+w+',height='+h+',left='+x+',top='+y+',
			scrollbars=no');
  	  })();">
	Share to Google+</a>
</div>

By the way, this is an interesting article about bookmarklets

Update 28.09.2012

The above code doesn't seem to work anymore so I tweaked it based on this entry on Stackoverflow, see code below. There is a share link now that works well, plus a bit of JS to have it in a popup. If you want to test it, you can click the black plus button (after the Facebook one) at the top and bottom of this article.


# HTML

<!-- on homepage -->
<a title="share on google+" href="#" onclick="return googleplusbtn('http://bobbelderbos.com')"><img src="http://bobbelderbos.com/wp-content/themes/bamboo/i/plus-icon.png" alt="Share on Google+" /></a> 

<!-- per article -->
..
$postmeta .= '<a title="share on google+" href="#" onclick="return googleplusbtn(''.$permalink.'')"><img src="http://bobbelderbos.com/wp-content/themes/bamboo/i/plus-icon.png" alt="Share on Google+" /></a>';  
..

# JS
<script>
function googleplusbtn(url) {
  sharelink = "https://plus.google.com/share?url="+url;
  newwindow=window.open(sharelink,'name','height=400,width=600');
  if (window.focus) {newwindow.focus()}                                                                                                                                
  return false;
}   
</script>

Create your QR code with Google Chart API

Creating a Quick Response code for your website is quite easy with the Google Chart API. I found a nice and easy code example here.

Create your own

You can create your own with this simple form (using a POST request)

Example

For bobbelderbos.com it yields:

Now you can get a smartphone app to scan this QR code and it redirects directly to your site:
Photo

This is quite cool for a visit card like about.me is doing for their service.

Update

I was traveling last week and at the airport I saw more and more QR codes on advertisements billboards, so it is worth considering getting one on any print media, to leverage the potential of the large amount of smart phones out there.

How to scrape a webpage with Perl

I wanted to have a book category list for a potential feature in My Reading List. I found this page. Then I wondered how I could parse the html to reuse the categories. It turned out to be pretty easy in Perl :)

You can download the script here. It does the following:

  • 1. Usage: perl -w parseCategories.pl -j -s, where -j = json, -s = sql, -t = text 
    Sql would be to import the data into a table for re-use (e.g. autocomplete)
  • 2. it uses LWP::Simple to import the content of the mentioned website into a variable
  • 3. it splits the content in an array and loops over the lines, checking for the patterns:
    a. category (font.*<ul>),
    b. subcategory (<li><a href...)
    - it puts those in a hash
  • 4. depending the cli option, it provides the output

Perl's motto is TMTOWTDI (There's more than one way to do it), so I would be happy to hear any suggestions to improve this script.
At least it got the job done. It was just a quick test. Ideally you would want to make it re-usable:
1. receive URL from cli as well
2. put parsing in functions and let user define those as well.
- with this in place it could be extended to be a generic/simple URL/content parser. 





How to import an autocomplete list

This is a trick I learned in need of a specific list. You can check in the firebug console what URL and get variable is running in the background to reproduce the result list.

The example loops over the results letter by letter and storing each unique value in an array. You probably need several nested foreach statements.

Below you see just one, which got me 200 items, going with a 2nd loop (so testing aa through zz) got me 2400 results, and I think there were even more. 

The json_decode function is quite useful when dealing with data APIs which often return JSON

autocomplete example code