Stupid PHP snippet to always download a changing file

It is short, it is easy, it is stupid but… can save you time.

If you need to download every few minutes a remote file that changes its contents at regular intervals of time this is for you.

Save this on a stupid.php file (and change the values):

<?php
$url = 'somewhere_in_the_space';
while(true) {
	$locaFile = "some_local_file_name_".time()."_with_extension";
	file_put_contents($locaFile, file_get_contents($url));
	echo "Done... $locaFile \n";
	sleep(60*5);    // Sleep 5 minutes !!!
}
?>

and execute with:

> php -f stupid.php

Remember it will run forever until you kill the process so don’t expect to finish.

Related Posts:

The dojox.grid widgets family and the strange case of the items modification

So, you are building a web application and decided to use the great Dojo framework.  Probably, if you need to use grids, you will decide to use some of the available widgets subclass of dojox.grid.

Well, my friend, be aware with the data you use to fill the grid’s store !!!

The scenario

Start creating a piece of code to execute when the page is ready. It will use the DataGrid widget with an ItemFileWriteStore store:

require(['dojox/grid/DataGrid', 'dojo/data/ItemFileWriteStore', 'dojo/domReady!'],

function(DataGrid, ItemFileWriteStore){

Now, create a data object with a set of random items:

	// Set up data store
	var data = {
		identifier: "id",
		items: []
	};
	// Initialize with random elements.
	var rows = 10;

Note we have stores our items in a different array:

	var items = [];
	for(var i = 0; i < rows; i++){
		items.push({ id: i+1, col1: "the first column", col2: false, col3: 'A column with a long description', col4: Math.random()*50 });
	}
	data.items = items;

Now, create the store and set the grid layout:

	var store = new ItemFileWriteStore({data: data});

	// Set up layout
	var layout = [[
			{'name': 'Column ID', 'field': 'id', 'width': '100px'},
			{'name': 'Column 1', 'field': 'col1', 'width': '100px'},
			{'name': 'Column 2', 'field': 'col2', 'width': '100px'},
			{'name': 'Column 3', 'field': 'col3', 'width': 'auto'},
			{'name': 'Column 4', 'field': 'col4', 'width': '150px'}
		]];

Finally, create the grid (remember to startup it):

	// Create a new grid
	var grid = new DataGrid({
		id: 'grid',
		store: store,
		structure: layout,
		rowSelector: '20px'
	});

	// Append the new grid to the div
	grid.placeAt("gridDiv");

	// Call startup() to render the grid
	grid.startup();
});

The grid code needs we have an HTML element in our page:

<div id="gridDiv"></div>

Here is the result of the previous code:

The issue

Our idea behind having the items stored in an array is because trying:

  • to serve as input data for the grid’s store
  • to store the original array to make other operations: to be used in other stores, to make a simple iteration, … whatever we want.

The issue is the array of items used to initialize the data store are modified once the grid’s startup() method is executed.

Lets go to see it in action. Check the value of the items array before and after the grid’s startup() method is executed:

Before

 

 

After

Yes, the objects within the items array are modified for internal pourposes.

Conclusions

This simple issue can have great implications depending on your way to code.

Suppose you are getting a JSON file with information about employees and for each one the set of companies they have worked. You will store this information in JavaScript object array and may be interested on use to:

  • search the boss within employees
  • initialize a TreeGrid to show the whole list of data.

The problem is you can’t use the same object array for the two tasks because in the moment the TreeGrid will execute its startup() method the array of items will change its structure.

How to solve this? Create a new array of objects from your original one or store them in a Memory store.

References

http://dojotoolkit.org/reference-guide/1.7/dojox/grid/index.html

http://dojotoolkit.org/reference-guide/1.7/dojox/grid/DataGrid.html

http://dojotoolkit.org/reference-guide/1.7/dojo/data/ItemFileWriteStore.html

Connecting a Store to a DataGrid - http://dojotoolkit.org/documentation/tutorials/1.7/store_driven_grid/

Related Posts:

What Doesn’t Stay in Vegas?

Today, and thanks to a colleague, I found this great video about how the Las Vegas city has grown in the past years.

When Landsat 5 launched on March 1, 1972, Las Vegas was a smaller city. This image series, done in honor of the satellite’s 28th birthday, shows the desert city’s massive growth spurt since 1972. The outward expansion of the city is shown in a false-color time lapse of data from all the Landsat satellites.

In addition to the video, what takes special attention to me was the two most rated comments:

  • Humans are like a virus on this planet…
  • Remove the tumor

Are we going on the right way?

Related Posts:

Scale-adaptative Projection

Take a look to this awesome exercise from the Oregon State University:

Related Posts:

Dojo + OpenLayers = New Challenges

Recently, the new Dojo 1.7 was released with many improvements and important changes.

As a developer, I’m pleased to work with Dojo on RIA application because simple reasons:

  • It offers almost all I need: module organization, an extensive set of widgets to create interfaces, manipulation of DOM elements, AJAX communications, etc.
  • It is relatively easy to use and learn. Here I found the declarative way to work really useful because helps developers and designers work together but on different things.
  • Creating custom widgets, after some relatively easy learning curve, brings you more power and flexibility.

Yes, Dojo is a great project, but as I mentioned at the beginning I like it for RIA projects, that is, for big or complex CRUD applications. For small things, like nice web pages, I prefer jQuery plus some plugins.

Looking at the new features of Dojo 1.7 I found a new module dojox.geo.openlayers which acts as a wrapper around OpenLayers GIS library and extends with some Dojo capabilities.

Now, add Dojo GFX shapes or Dojo widgets on top OpenLayers is possible, opining new possibilities. With this merge we can do things like add pie charts to our maps to show to statistics information. It is awesome !!!

A very short introdutcion to dojox.geo.openlayers package

Before making a little demo playing with all this new things, we need a short description.

The main class in the package is dojox.geo.openlayers.Map which acts as a kind of wrapper around the OpenLayers.Map class. You can access at any time to the OpenLayers underline object with the getOLMap() method.

Next, there is the dojox.geo.openlayers.Layer class which is a wrapper around the OpenLayers.Layer class. It allows to attach to the map any Dojo element.

The dojox.geo.openlayers.GfxLayer is a subclass of the previous class specially designed to work with GFX shapes and render them on top of OpenLayers map.

The dojox.geo.openlayers.Feature class represents the features we can attach to a dojox.geo.openlayers.Layer. The subclass dojox.geo.openlayers.GeometryFeature is designed to render LineString, Points and Collections of geometries.

Because GeometryFeature works with dojox.gfx package to render the geometries you need to add it always to a dojox.geo.openlayers.GfxLayer layer.

Hands on code

We are going to create a map with three features:

  • a dojox.gfx shape feature, with an animation attached to it to change it fill color,
  • a pie chart and
  • a stacked area chart.

You can see the demo in action here, and it should looks something like:

Dojo + OpenLayers

Lets go. Start creating new HTML page and paste the next code, which correspond to the skeleton of our demo:

<!DOCTYPE HTML>
<html>
    <head>
		<title>Dojo + OpenLayers = New Challenge</title>
        <style>
            html, body {
                width: 100%;
                height: 100%;
            }
        </style>
        <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js"></script>
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/claro.css"/>
        <link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dijit/themes/claro/document.css"/>
        <script type="text/javascript" src="http://openlayers.org/api/2.10/OpenLayers.js"></script>
        <script type="text/javascript">
            require([
                "dojo/ready",
                "dojo/parser",
                "dojo/dom-construct",
                "dojox/geo/openlayers/Map",
                "dojox/geo/openlayers/GfxLayer",
                "dojox/geo/openlayers/GeometryFeature",
                "dojox/geo/openlayers/WidgetFeature",
                "dojox/gfx/fx",
                "dojox/charting/widget/Chart2D",
                "dojox/charting/themes/PlotKit/blue"
            ], function(ready) {

                ready(function(){
                    console.log(dojo.version.major + "." + dojo.version.minor + "." + dojo.version.patch);

					// Here put the magic !!!
                })
            });
        </script>
    </head>

    <body class="claro">
        <div id="map" style="width: 100%; height: 100%;"></div>
    </body>
</html>

I’m using Dojo 1.7 and the new way to work using require. As you can see I’m referencing the modules my code requires from dojo and dojox packages

Once Dojo is loaded the ready is executed showing the Dojo version in the console and executing the code shown next, which really creates the map and the features.

In the “here put the magic” section we can place the code that creates a new dojox.geo.openlayers.Map instance:

//
// Define some Map options.
//
// openLayersMapOptions: Options for the underlaying OpenLayers.Map instance
// baseLayerName: Name of the base layer for the map
// baseLayerType: Type of the base layer. See 'dojox.geo.openlayers.BaseLayerType'
// baseLayerUrl: Necessary, for example, for WMS.
// accessible: Adds a OpenLayers.Control.KeyboardDefaults control to the map
//     to move it using keyboard.
// touchHandler: Touch support for the map.
//
var options = {
    baseLayerName : "OSM",
    baseLayerType : dojox.geo.openlayers.BaseLayerType.OSM,
    touchHandler : true,
    accessible : true
};

// Create a map instance
var map = new dojox.geo.openlayers.Map('map');
map.fitTo([-10,30,40,62]);

Next create a GFX layer. On it we can attach geometry features or any other Dojo widget feature.

Remember you only can attach geometry features to a GFX layer.

// Create a GFX layer
var gfxLayer = new dojox.geo.openlayers.GfxLayer();
map.addLayer(gfxLayer);

Now create a geometry feature, defined by a LineString with some points, and add it to the layer:

// Create a geometry feature
var line = new dojox.geo.openlayers.LineString([{x:0, y:45},{x:0, y:55},{x:20, y:55},{x:20, y:50},{x:0, y:45}]);
var feature = new dojox.geo.openlayers.GeometryFeature(line);
feature.setStroke({color: "#666", width: 2});
feature.setFill("#999");

// Add to the GFX layer
gfxLayer.addFeature(feature);
gfxLayer.redraw();

We want to animate the fill color of the geometry feature so we need to create a couple of animation. The first one will change the fill color from the original color to transparent, while the second will change from transparent to the original color again.

The trick is once the first animation ends we start the second animation (using the ‘onEnd‘ method) and the same for the second animation. This way we create an infinite animation effect.

// Add an animation to change the color of the feature
var animA = dojox.gfx.fx.animateFill({
    shape : feature,
    duration : 700,
    color : {
        start: "#999",
        end: "transparent"
    },
    onAnimate: function() {
        // Required to update the layer while feature change it fill color
        gfxLayer.redraw();
    },
    onEnd: function() {
        animB.play();
    }
});
var animB = dojox.gfx.fx.animateFill({
    shape : feature,
    duration : 700,
    color : {
        start: "transparent",
        end: "#999"
    },
    onAnimate: function() {
        // Required to update the layer while feature change it fill color
        gfxLayer.redraw();
    },
    onEnd: function() {
        animA.play();
    }
});
animA.play();

Now, we are going to create a pie chart widget feature. We are going to use the dojox.geo.openlayers.WidgetFeature class which required an object in the constructor defining the widget to create, the lat/lon where to place the widget and some more parameters. You can find all the available parameters in the source code documentation:

//	* _createWidget_: Function for widget creation. Must return a `dijit._Widget`.
//	* _dojoType_: The class of a widget to create;
//	* _dijitId_: The digitId of an existing widget.
//	* _widget_: An already created widget.
//	* _width_: The width of the widget.
//	* _height_: The height of the widget.
//	* _longitude_: The longitude, in decimal degrees where to place the widget.
//	* _latitude_: The latitude, in decimal degrees where to place the widget.

The pie chart widget have a 100×100 size and will we located at (lon,lat)=(5, 40). The createWidget property must point to a function responsible to create the appropriate widget:

// Add a widget feature
var chartSize1 = 100;
var co1 = [5,40];
var descr1 = {
    // location of the widget
    longitude : co1[0],
    latitude : co1[1],
    // the function which creates the widget
    createWidget : function(){
        var div = dojo.create("div", {}, dojo.body());
        var chart = new dojox.charting.widget.Chart({
            margins : {
                l : 0,
                r : 0,
                t : 0,
                b : 0
            }
        }, div);
        var c = chart.chart;
        c.addPlot("default", {
            type : "Pie",
            radius : chartSize1 / 2,
            labelOffset : chartSize1,
            fontColor : "black"
        });

        var ser = [2, 8, 12, 43, 56, 23, 43, 1, 33];
        c.addSeries("Series", ser);
        c.setTheme(dojox.charting.themes.PlotKit.blue);
        c.render();
        c.theme.plotarea.fill = undefined;  // Transparent background
        return chart;
    },
    width : chartSize1,
    height : chartSize1
};
var graphFeature1 = new dojox.geo.openlayers.WidgetFeature(descr1);
gfxLayer.addFeature(graphFeature1);

Similarly, we create a second widget feature with a stacked area chart with different dimensions and location:

// Add a second plot feature
var chartSize2 = [300,200];
var co2 = [15,45];
var descr2 = {
    // location of the widget
    longitude : co2[0],
    latitude : co2[1],
    // the function which creates the widget
    createWidget : function(){
        var div = dojo.create("div", {}, dojo.body());
        var chart = new dojox.charting.widget.Chart({
            margins : {
                l : 0,
                r : 0,
                t : 0,
                b : 0
            }
        }, div);
        var c = chart.chart;

        c.addPlot("default", {type: "StackedAreas", tension:3})
        .addAxis("x", {fixLower: "major", fixUpper: "major"})
        .addAxis("y", {vertical: true, fixLower: "major", fixUpper: "major", min: 0})
        .addSeries("Series A", [1, 2, 0.5, 1.5, 1, 2.8, 0.4])
        .addSeries("Series B", [2.6, 1.8, 2, 1, 1.4, 0.7, 2])
        .addSeries("Series C", [6.3, 1.8, 3, 0.5, 4.4, 2.7, 2])
        .setTheme(dojox.charting.themes.PlotKit.blue);
        c.render();
        return chart;
    },
    width : chartSize2[0],
    height : chartSize2[1]
};
var graphFeature2 = new dojox.geo.openlayers.WidgetFeature(descr2);
gfxLayer.addFeature(graphFeature2);

Once we have all the features in the layer, it is a good idea to refresh it:

gfxLayer.redraw();

Conclusions

I think the fusion of Dojo with OpenLayers opens new possibilities to create rich content and behavior mapping applications. We can create dojo features and make them really amazing using effects, animation and events (like this).

I usually work with OpenLayers and, because Dojo simply acts as a wrapper on some OpenLayers classes, we can access them and work directly adding data from WFS server, GML files, etc

Is it a perfect solution? As always it depends on your needs but for all of us which work in complex RIA applications that needs some GIS features the dojox.geo.openlayers package offers a new spot light :)

Related Posts:

Presentation tools in the browser

With the arrival of HTML5+C33 the browsers are getting more attention because the new possibilities.

One example of the possibilities are the proliferation of frameworks, tools and libraries to create HTML presentations to run in the browser. No need to transform your presentation from PowerPoint or Keynote to any portable format, the content is plain HTML.

First contact

The first tool of this kind I listened was the html5slides project. You can see it in action here.

Some time later, I read a new about a new tool called deck.js. I think it is awesome, extensible and… see for yourself at the Getting Started section.

Some weeks ago I read a tweet talking about impress.js. For the moment it is only compatible with Chrome and Safari (both uses the WebKit engine) but is looks really impressive.

Many more

Knowing the previous projects I start looking for other alternatives I found a great range of projects: Landslide, html5-slideshow (see a demo here), pow (see in action here) or DZSlides, a one-page-template to build your presentation in HTML5 and CSS3.

Within this maremagnum of possibilities the confusion is assured: which tool is better? which is easy to use? which has more effects? which one is more flexible and/or extensible? which want has more followers and/or supporters? which one will survive in the future?

 The future

Currently, all these tools are great but they all are oriented to a web developer user with strong knowledge on HTML and CSS.

The next step is clear, adapt to plain users (a user without web technologies knowledge). The tools needs an editor to help in the creation of the slides, like PowerPoint or Keynote.

There are projects working on this direction, like the 280Slides. It is implemented in Cappuccino framework and brings the user a Keynote like editor to visually create the slides.

More history

If you want to know a bit more about the evolution of the presentation tools, I encourage you to read this great article from Luigi Montanez.

Related Posts:

Filling Flexigrid with JSON/XML data

Flexigrid is one of the most useful and powerful grid plugins for jQuery. Unfortunately, as the author explains in the project page, there is no much documentation so you must learn how to use it looking at existing code.

If anytime you need to fill a Flexigrid with JSON or XML content and you are a little buggy to look at example code, here is the great summary:

Remember XML/JSON data must follow the next rules: total, page, rows. And for every row specify and id and a cell structure.

Next steps show you how to make it run step by step.

  • Sample data for both types are:
{
	page: 1,
	total: 2,
	rows: [
		{id: 'reg1',    cell: ['reg1-cell1','reg1-cell2']},
		{id: 'reg2',    cell: ['reg2-cell1','reg2-cell2']}
	]
}
<rows>
	<page>1</page>
	<total>2</total>
	<row id="reg1">
		<cell>reg1-cell1</cell>
		<cell>reg1-cell2</cell>
	</row>
	<row id="reg2">
		<cell>reg2-cell1</cell>
		<cell>reg2-cell2</cell>
	</row>
</rows>
  • Put some element on your HTML document:
<p id="yourId"></p>
  • Convert that element into a flexigrid with:
$("#yourId").flexigrid({
	url: 'your_file_name.json_or_xml',
	dataType: 'json',
	...
}

Now you know how to build a gorgeous grid from XML or JSON data.

Related Posts:

Greedy and Nongreedy Matching in a Regular Expression

This questions has come to me many times so it is time to write a post that acts as a reminder.

Currently I have a string like

ftp://user:password@server/dirA/dirB/file

and what i want is parse it to get the user, password, server and path to the file (/dirA/dirB/file). My first try was:

ftp://(\S+):(\S+)@(\S+)(/\S+)

but that returns me server=server/dirA/dirB, which isn’t what I want. The idea is that the group after the @ would make a non gready match. This is achieved using the ? char. So the final and right regular expression will becomes:

ftp://(\S+):(\S+)@(\S+?)(/\S+)

which returns server=server and file=/dirA/dirB/file.

Related Posts:

Open alternatives to Google Maps

Lately there was a not much surprising news about Google products and services. Among other things Google has changed the Google Maps API use policy and will charge to those users that exceed some download limits.

It is well known that Google Maps is one of the most (or the most) famous mapping service used around the net and it starts the web GIS revolution some years ago but hopefully it is not the only API we can use. Bing and the discontinued Yahoo Maps, are great competitors but this post is related to open source alternatives you can find to create your web mapping applications.

Please, don’t confuse the API with the imagery you are using. Google will charge you by the imagery usage so if you use an alternative API but continues consuming Google tiles you are in a similar situacion.

OpenLayers

OpenLayers is probably the most famous open source web mapping project. I want to think so because two factors: first it is the older project presented on this post and second because it is the most complete and, because this, the most complex.

OpenLayers is close to OGC standards, it separates between geometries, features and styles. You can load raster tiles layers from Google, Bing, OpenStreetMaps, etc or vector data from GML, KML or GeoJSON formats.

OpenLayers is not only restricted to spherical mercator, you can use almost any projection you know (plus many others), you can load data from WMS or WFS servers and most important, you are not limited to visualise data, you can create and edit new features sending them to the WFS server.

Polymaps

Polymaps is a project born from SimpleGeo and Stamen association. The main reason behind Polymaps is the use of vector-tiled layers.

What we mean by vector-tiled data? Since GoogleMaps everybody knows about raster-tiled layers, where each zoom level contains more tiles with more resolution.

A vector-tiles layer is similar, in the sense every zoom level has more resolution, but the data of every tile is not an image but vector data is rendered using SVG. This means you need a SVG compliant browser to use Polymaps.

Leaflet

Leaflet is a lightweight library specially oriented to make tile-based maps for desktop and mobile web browser.

It is really easy to use and offers the basic things everybody needs for a typical web mapping application: access to tile-based imagery, markers, popups, polygons, points, etc. Believe me, put an eye on this project, it has many more to say.

As a note, I would like to say Leaflet is a project from CloudMade and it is close to their Web Map API (http://cloudmade.com/products/web-maps-api).

And what about imagery?

Google Maps is not the unique imagery provider and there are other alternatives like Bing or Yahoo imagery, but the question is: where can I found real open imagery I can use for commercial applications and not limited by their usage?

I think the most famous open source alternative is OpenStreetMap. Their data is maintained by the community, anybody can add data or improve it. It demonstrates its quality and usefulness in the Haiti disaster because their information was more accurate than any other provider.

In addition, some time ago there was a similar project called OpenAerialMap, currently discontinued, that tries to create something similar than OpenStreetMap but with aerial images. The problem in this case is that obtain aerial data isn’t as easy as get vector data with a GPS. If you have a plane and a good camera and want to share your imagery then contact with OpenAerialMap author.

Finally, I would like to mention one more service provider. Yes it is not completely open source, but it is close. CloudMade (yes the creators of Leaflet and other free tools) is a company based on OpenStreetMap data. Among other great tools they allow to configure the style of the tiles you can later add to your map in a similar way Google Style Maps doesn but they do some year before Google.

 

Related Posts:

Using YouTube API to embed videos dinamically on your web site

It is easy to embed a given YouTube video on a web site, simply use the wizard to get code required code, but what about to do the some automatically using JavaScript? Yes, suppose you have a preferred user you follow all his videos and would like to put his/her latest video in your web site.

Every YouTube video has a unique identifier so the challenge is how to get the id if the latest uploaded (or updated if you prefer) video.

Searching for videos

YouTube has a very rich API and you have lot of parameters available to use, but, probably most important are the ways to search. Mainly you have two options to search videos for a given user:

  • Search video feeds:
    http://gdata.youtube.com/feeds/api/videos?author=SOME_USER&more_parameters
  • Search videos uploaded for specific user:
    https://gdata.youtube.com/feeds/api/users/USERNAME/uploads?more_parameters

First way is more flexible than second, because you can use lot of parameters to chose and author, limit results number, order by, etc, while the second is like setting the author parameter in the first one.

IMPORTANT !!! Read careful the YouTube API documentacion, concretely the sentence:

Requests using other parameters, such as orderby, will return cached results.

That makes me (on other folks) spent lot of time trying to find way searched doesn’t get really updated results.

The requests

What will be our test request? Yeah !!! We are going to check for the lastest video of the user… ironmaiden !!!

We want to get maximum one videos from ironmaiden user and ordered by date of publication. In addition, we want the response be in JSON format (not in XML) so we use the ‘alt‘ parameter too:

http://gdata.youtube.com/feeds/api/videos?author=ironmaiden&max-results=1&orderby=published&v=2&alt=jsonc

https://gdata.youtube.com/feeds/api/users/ironmaiden/uploads?max-results=1&orderby=published&v=2&alt=jsonc

The response

By default, the returning data is specified in XML format (see here) but with the help of alt=jsonc parameter it is returned in JSON notation (see here). For the previous first request the response is:

{
    "apiVersion":"2.1",
    "data":{
        "updated":"2011-10-31T19:24:09.441Z",
        "totalItems":14,
        "startIndex":1,
        "itemsPerPage":1,
        "items":[{
            "id":"O9f1bBeYpqA",
            "uploaded":"2011-10-19T13:07:28.000Z",
            "updated":"2011-10-31T16:57:34.000Z",
            "uploader":"ironmaiden",
            "category":"Music",
            "title":"IMTV London",
            "description":"A quick IMTV from the O2. The full IMTV UK episode will be available to fanclub members soon!",
            "tags":["iron","maiden","imtv","on","board","flight","666","Iron Maiden","United Kingdom","Metal"],
            "thumbnail":{
                "sqDefault":"http://i.ytimg.com/vi/O9f1bBeYpqA/default.jpg",
                "hqDefault":"http://i.ytimg.com/vi/O9f1bBeYpqA/hqdefault.jpg"
            },
            "player":{
                "default":"http://www.youtube.com/watch?v=O9f1bBeYpqA&feature=youtube_gdata_player",
                "mobile":"http://m.youtube.com/details?v=O9f1bBeYpqA"
            },
            "content":{
                "5":"http://www.youtube.com/v/O9f1bBeYpqA?version=3&f=videos&app=youtube_gdata",
                "1":"rtsp://v3.cache5.c.youtube.com/CiILENy73wIaGQmgppgXbPXXOxMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp",
                "6":"rtsp://v2.cache8.c.youtube.com/CiILENy73wIaGQmgppgXbPXXOxMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp"
            },
            "duration":316,
            "aspectRatio":"widescreen",
            "rating":4.9898734,
            "likeCount":"394",
            "ratingCount":395,
            "viewCount":47086,
            "favoriteCount":110,
            "commentCount":105,
            "accessControl":{
                "comment":"allowed",
                "commentVote":"allowed",
                "videoRespond":"moderated",
                "rate":"allowed",
                "embed":"allowed",
                "list":"allowed",
                "autoPlay":"allowed",
                "syndicate":"allowed"
            }
        }]
    }

As you can see the ID of the video is at:

data.items[0].id

Embeding a video

Embeding a video by hand is easy, you simply click on “share” button, then on “embed”, copy and paste the code and that’s all:

But hey !!! We are bad boys, worst if it is possible, we are programmers and we live to programming, so we are going to do the same than any other mortal but programming, so program once run forever !!! (mmm… that slogan sounds me like a island name programming language).

The intention is to make the code necessary to get the latest video identifier and inject the code to embed video on page, like this:

<iframe width="420" height="315" src="http://www.youtube.com/embed/PieS0zG228A"
frameborder="0" allowfullscreen></iframe>

Automatically embedding the latest video

Finally arrive to the most interesting section. As you can imagine we can do it in the AJAX way, making an asynchronous request and injecting the code but in addition I will put a more “static” way to do, thanks to the callback parameter in the request.

The AJAX way

First, create div elements to contain the video frame and a button to start the loading process:

<div id="ajax_video"></div>
<button id="ajaxbutton">AJAX way</button>

In the head section of the document Ihave added the required JavaScript code (I’m using jQuery to do it):

<script type="text/javascript">
    $(document).ready(function(){
        $('#ajaxbutton').click(function(event){
            $.get('https://gdata.youtube.com/feeds/api/users/ironmaiden/uploads?max-results=1&orderby=published&v=2&alt=jsonc',
            function(response) {
                if(response.data && response.data.items) {
                    var items = response.data.items;
                    if(items.length>0) {
                        var item = items[0];
                        var videoid = "http://www.youtube.com/embed/"+item.id;
                        console.log("Latest ID: '"+videoid+"'");
                        var video = "<iframe width='420' height='315' src='"+videoid+"' frameborder='0' allowfullscreen></iframe>";
                        $('#ajax_video').html(video);
                    }
                }
            });
        });
    });
</script>

As we mention, the request get the latest video from ironmaiden user, creates an iframe element containing it and add it to the previously created div element.

Using callback parameter

This version differs from previous one because the request is made when page is loaded. What I’m saying? Exactly this, the request is made including JavaScript code:

<script type="text/javascript" src="https://gdata.youtube.com/feeds/api/users/ironmaiden/uploads?max-results=1&orderby=published&v=2&alt=jsonc&callback=showVideo"></script>

The url includes the callback parameter which is responsible to call the specified function once the code is loaded.

Putting it all together, in the same way that previous case you need a div element that contains the video iframe and a JavaScript code to add the iframe from the response:

<div id="static_video"></div>
<script type="text/javascript">
    function showVideo(response) {
        if(response.data && response.data.items) {
            var items = response.data.items;
            if(items.length>0) {
                var item = items[0];
                var videoid = "http://www.youtube.com/embed/"+item.id;
                console.log("Latest ID: '"+videoid+"'");
                var video = "<iframe width='420' height='315' src='"+videoid+"' frameborder='0' allowfullscreen></iframe>";
                $('#static_video').html(video);
            }
        }
    }
</script>
<script type="text/javascript" src="https://gdata.youtube.com/feeds/api/users/ironmaiden/uploads?max-results=1&orderby=published&v=2&alt=jsonc&callback=showVideo"></script>

The browser load the elements in the order it encounters, so it is important to put the code in the right place so browser finds first the ‘showVideo’ function before loading the YouTube code request.

Demo

You can see a demo working here.

References

http://code.google.com/apis/youtube/2.0/reference.html#Searching_for_videos

http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html#Retrieving_and_searching_for_videos

http://code.google.com/apis/youtube/2.0/developers_guide_json.html

Related Posts: