Using Weather Data to Change Your Website’s Appearance through PHP and CSS

Published by Guest Author

This article is co-authored by David Walsh of
The David Walsh Blog :: PHP, CSS, MooTools, and Everything Else

UPDATE: This post was updated on April 30th, 2008 to account for a minor change in how Yahoo! was serving up data UPDATED DOWNLOAD

Inspiration for this idea came from a comment by Andreas.

Using a little magic and trickery (read: PHP and CSS), we can change the appearance of a website automatically based on the weather outside, in real time! In the example site we have created, the header graphic will change to one of four different styles based on Sunny, Rain, Snow, and Cloudy.

Step 1: Designing your weather graphics

Our example site changes header graphics as as well as an icon in the sidebar to describe the weather. For the sake of example, we only created four different weather scenarios, defaulting to sunny.

headerexample-partlycloudy.jpg

headerexample-rain.jpg

headerexample-snow.jpg

headerexample-sunny.jpg

Step 2: Retrieving the weather information

Yahoo! has an API for weather information. We can tap into this very easily using an URL formatted like so:

http://weather.yahooapis.com/forecastrss?p=97211&u=f

The 5-digit number is your Zip Code and the "f" stands for "Fahrenheit" (change to "c" for "Celsius"). The information comes in XML format and it's up to you how you want to parse the data. Since the only bit of information we care about is the "yweather:condition" element's "text" attribute, We're going to avoid creating an XML parsing object and use a short regular expression.

Once the regular expression returns the yweather element's text, we'll use str_replace() and strtolower to format the string into a representative CSS class.

Step 3: Turning the weather information into an CSS class

Here is the PHP code:

<?php
	
	/* get xml, find match */
	
	/* get the weather from Yahoo */
	$data = get_data("http://weather.yahooapis.com/forecastrss?p=97211&u=f");
	
	$weather_class = format_result(get_match('/<yweather:condition  text="(.*)"/isU',$data));
	
	/* debug to see what we got back */
	//echo '<pre style="background:#fff;font-size:12px;">['; print_r($weather); echo ']</pre>';
	
	/* format the result */
	function format_result($input)
	{
		return strtolower(str_replace(array(' ', '(', ')'), array('-', '-', ''), $input));
	}
	
	/* helper:  does regex */  
	function get_match($regex,$content)  
	{  
		preg_match($regex,$content,$matches);  
		return $matches[1];  
	}
	
	/* gets the xml data from Alexa */
	function get_data($url)
	{
		$ch = curl_init();
		$timeout = 5;
		curl_setopt($ch,CURLOPT_URL,$url);
		curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
		curl_setopt($ch,CURLOPT_CONNECTTIMEOUT,$timeout);
		$xml = curl_exec($ch);
		curl_close($ch);
		return $xml;
	}
	
?>

Now we have a variable we can echo out that is representative of the current weather at the zip code we provided:

<div class="header header-<?php echo $weather_class; ?>">
	<!-- Change the class above to change the header graphic -->
</div>

Step 4: Code your CSS for each of the classes

.header {
	width: 782px; height: 150px;
	/* DEFAULTS TO SUNNY */
	background: url(images/header-sunny.png) no-repeat center center black;
	}
	.header-rain {
		background: url(images/header-rain.png) no-repeat center center black;
	}
	header-snow {
		background: url(images/header-snow.png) no-repeat center center black;
	}
	.header-sunny, .header-fair {
		background: url(images/header-sunny.png) no-repeat center center black;
	}
	.header-partly-cloudy, .header-cloudy, .header-mostly-cloudy {
		background: url(images/header-partlycloudy.png) no-repeat center center black;
}

Step 5: Extending the idea

Notice that we use the "partlycloudy" graphic for the weather conditions of "partly-cloudy", "cloudy", and "mostly-cloudy". It's up to you how specific you want to get. Here is a full list of the possible weather conditions from Yahoo!:

0  	tornado
1 	tropical storm
2 	hurricane
3 	severe thunderstorms
4 	thunderstorms
5 	mixed rain and snow
6 	mixed rain and sleet
7 	mixed snow and sleet
8 	freezing drizzle
9 	drizzle
10 	freezing rain
11 	showers
12 	showers
13 	snow flurries
14 	light snow showers
15 	blowing snow
16 	snow
17 	hail
18 	sleet
19 	dust
20 	foggy
21 	haze
22 	smoky
23 	blustery
24 	windy
25 	cold
26 	cloudy
27 	mostly cloudy (night)
28 	mostly cloudy (day)
29 	partly cloudy (night)
30 	partly cloudy (day)
31 	clear (night)
32 	sunny
33 	fair (night)
34 	fair (day)
35 	mixed rain and hail
36 	hot
37 	isolated thunderstorms
38 	scattered thunderstorms
39 	scattered thunderstorms
40 	scattered showers
41 	heavy snow
42 	scattered snow showers
43 	heavy snow
44 	partly cloudy
45 	thundershowers
46 	snow showers
47 	isolated thundershowers

For this example, you'll notice we also used a hard-coded zip code that must be changed in the PHP in order to change where the website will be basing it's weather appearance on. But wouldn't it be cool if the website knew the zip code of your visitors and would change the appearance of the site based on their weather instead of your weather? That kind of coding requires services and expertise beyond the scope of this tutorial, but a quick Google search brings up some services that could probably make this happen like IP2Location.

Have fun! - and let me know if anyone actually uses this, I'd love to see what you did with it.

weather-switcher.jpg