Australia's Leading Digital Marketing Experts. T. 1300 235 433  |  Aggregation Enquires Welcome

Weather Forecasts with OpenWeatherMap in WordPress or PHP

Weather Forecasts with OpenWeatherMap in WordPress or PHP

OpenWeatherMap is an online service that provides weather data, including current weather data, forecasts, and historical data to the developers of web services and mobile applications. For data sources, it utilizes meteorological broadcast services, raw data from airport weather stations, raw data from radar stations, and raw data from other official weather stations. What was once a very open service is slowly becoming more and more commercial with access to formerly free forecasts now incurring a fee. That said, they provide an enormous amount of data via an API that has only a few limitations. It is a brilliant service and ideal alternative services such as WeatherUnderground.

This post will show you how to include a basic day forecast in WordPress or with PHP. The previous version of this code (when published on Internoetics) dealt with a weekly forecast; that API enpoint is now relegated to the paid section so isn't available unless you pay a monthly subscription.

The Result

The result rendered below is just an example (if you need something specific please let us know). The result is built with dodgy inline CSS and doesn't really do much other than display 5 columns of daily data. Shortcode used is [bmowm_forecast location="sydney,au"]. The code also supports location by city ID ([bmowm_forecast location="2147714"]). Result is returned for Sydney, Australia.


26th 8:00am
Temp : 12.8°C
QNH : 1026hPa
RH : 64%
light rain
Wind: S 13kt

26th 11:00am
Temp : 14.1°C
QNH : 1027hPa
RH : 52%
light rain
Wind: SbE 14kt

26th 2:00pm
Temp : 14.5°C
QNH : 1026hPa
RH : 52%
overcast clouds
Wind: SbE 12kt

26th 5:00pm
Temp : 14.7°C
QNH : 1026hPa
RH : 50%
broken clouds
Wind: SSE 10kt

26th 8:00pm
Temp : 12.7°C
QNH : 1027hPa
RH : 62%
light rain
Wind: SEbS 8kt

Weather supplied by OpenWeatherMap.org

We cache results with Simple Cache for two hours (data is updated only every three hours). Usage of Simple Cache is required, and it's used an alternative to the WP transient functions simply so we can retrieve older (cached) data if the API is unresponsive.

WordPress Shortcode

Copy and paste the WordPress function into your theme's functions.php file or, if you sensibly have one installed, your custom functions plugin.

1
<?php 
2
/*
3
 Embed Weather Underground Forecasts with WordPress Shortcode or PHP
4
 http://www.beliefmedia.com/weather-underground-forecasts
5
*/
6
 
7
8
 
9
  $atts = shortcode_atts(array(
10
    'apikey' => 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
11
    'location' => 'Sydney,AU',
12
    'offset' => '11',
13
    'icons' => 0,
14
    'version' => '2.5',
15
 
16
    'cache' => 3600 * 2
17
  ), $atts);
18
 
19
 $transient = 'bmowmd_' . md5(serialize($atts));
20
 $cached =  beliefmedia_get_transient($transient, $atts['cache']);
21
 
22
 if ($cached !== false ) {
23
  return $cached;
24
 
25
  } else {
26
 
27
  /* May request by free text, ID, lat/lng, or ZIP. Two provided for example */
28
  $request = (is_numeric($location)) ? 'http://api.openweathermap.org/data/' . $atts['version'] . '/weather?id=' . $atts['location'] . '&appid=' . $atts['apikey'] : 'http://api.openweathermap.org/data/' . $atts['version'] . '/forecast?q=' . $atts['location'] . '&appid=' . $atts['apikey'];
29
 
30
  /* Get current weather */
31
  $weather = @file_get_contents($request);
32
  if ($weather === false) return beliefmedia_get_transient_data($transient);
33
  $weather = json_decode($weather, true);
34
 
35
  /* The portion of the weather array you're displaying */
36
  $weather = array_slice($weather['list'], 6, 5);
37
 
38
  /* Generate HTML */
39
  foreach ($weather AS $day) {
40
 
41
    $result .= '<div class="bm-owm-col">
42
      <span class="bm-owm-img"><img src="http://openweathermap.org/img/w/' . $day['weather']['0']['icon'] . '.png"></span>
43
<p style="clear: both; margin-top: 0.2em; margin-bottom: 0em;"><p>      ' . date('jS g:ia', strtotime($day['dt_txt']) + $atts['offset'] * 3600) . '
44
      Temp : ' . round($day['main']['temp_max'] - 273.15, 1) . '°C
45
      QNH : ' . round($day['main']['sea_level']) . 'hPa
46
      RH : ' . $day['main']['humidity'] . '%
47
      ' . ucfirst($day['weather']['0']['description']) . '
48
      Wind: ' . beliefmedia_compass_cardinal($day['wind']['deg']) . ' ' . round($day['wind']['speed'] * 1.94384617179) . 'kt
49
   </div>';
50
 
51
  }
52
 
53
  $style = '
54
<style scoped>
55
  html {
56
    box-sizing: border-box;
57
  }
58
 
59
  *, *:before, *:after {
60
    box-sizing: inherit;
61
  }
62
 
63
  .bm-owm-row {
64
    display: flex;
65
    flex-wrap: wrap;
66
    align-items: center;
67
  }
68
 
69
  .bm-owm-col {
70
    flex: 1 1 20%;
71
    // background: #ffffff;
72
    min-width: 90px;
73
    font-size: 0.9em;
74
    color: black;
75
    padding: 0px 10px 5px 10px;
76
    align-items: center;
77
    justify-content: center;
78
  }
79
 
80
  .bm-owm-img {
81
    min-width: 90px;
82
    text-align: center;
83
  }
84
 
85
  .bm-owm-col img {
86
    margin: 0 auto;
87
    width: 50px;
88
    height: 50px;
89
    text-align: center;
90
    padding: 1px;
91
  }</style>
92
 
93
';
94
 
95
  /* Container & Style */
96
  $return = '<div>' . $style . '<div class="bm-owm-row">';
97
 
98
  /* Weather */
99
  $return .= $result;
100
  $return .= '
101
<p style="font-size: 0.8em;">Weather supplied by OpenWeatherMap.org';
102
 
103
  /* Container */
104
  $return .= '</p></div>
105
</div>';
106
 
107
  /* Cache result */
108
  beliefmedia_set_transient($transient, $return);
109
 
110
  return $return;
111
 }
112
}
113
add_shortcode('bmowm_forecast', 'beliefmedia_openweathermap_forecast_day');

If you require shortcode to work in a sidebar widget, you'll have to enable the functionality with a filter. If you're using our custom functions plugin, you'll have that feature enabled by default.

The OpenWeatherMap API documentation describes the use of various parameters to alter returned data (for example, returning data in imperial or metric units). We've used the default JSON response and corrected temperatures (from Kelvin).

Rather than provide wind direction in degrees we've applied another function (below) to return the intercardinal compass abbreviation (described in more detail here). The function is reproduced below.

1
<?php 
2
/*
3
 Return Compass Ordinal Abbreviation From A Direction
4
 http://www.beliefmedia.com/code/compass-cardinal-direction
5
 http://www.beliefmedia.com/openweathermap-forecasts
6
*/
7
 
8
function beliefmedia_compass_cardinal($dir) {
9
 
10
  $dir = abs($dir);
11
 
12
  switch ($dir) {
13
     case ($dir >= 354 && $dir < 6):
14
        $cardinal = 'N';
15
        break;
16
     case ($dir >= 6 && $dir < 17):
17
        $cardinal = 'NbE';
18
        break;
19
     case ($dir >= 17 && $dir < 28):
20
        $cardinal = 'NNE';
21
        break;
22
     case ($dir >= 28 && $dir < 39):
23
        $cardinal = 'NEbN';
24
        break;
25
     case ($dir >= 39 && $dir < 51):
26
        $cardinal = 'NE';
27
        break;
28
     case ($dir >= 51 && $dir < 62):
29
        $cardinal = 'NEbE';
30
        break;
31
     case ($dir >= 62 && $dir < 73):
32
        $cardinal = 'ENE';
33
        break;
34
     case ($dir >= 73 && $dir < 84):
35
        $cardinal = 'EbN';
36
        break;
37
     case ($dir >= 84 && $dir < 96):
38
        $cardinal = 'E';
39
        break;
40
     case ($dir >= 96 && $dir < 107):
41
        $cardinal = 'EbS';
42
        break;
43
     case ($dir >= 107 && $dir < 118):
44
        $cardinal = 'ESE';
45
        break;
46
     case ($dir >= 118 && $dir < 129):
47
        $cardinal = 'SEbE';
48
        break;
49
     case ($dir >= 129 && $dir < 141):
50
        $cardinal = 'SE';
51
        break;
52
     case ($dir >= 141 && $dir < 152):
53
        $cardinal = 'SEbS';
54
        break;
55
     case ($dir >= 152 && $dir < 163):
56
        $cardinal = 'SSE';
57
        break;
58
     case ($dir >= 163 && $dir < 174):
59
        $cardinal = 'SbE';
60
        break;
61
     case ($dir >= 174 && $dir < 186):
62
        $cardinal = 'S';
63
        break;
64
     case ($dir >= 186 && $dir < 197):
65
        $cardinal = 'SbW';
66
        break;
67
     case ($dir >= 197 && $dir < 208):
68
        $cardinal = 'SSW';
69
        break;
70
     case ($dir >= 208 && $dir < 219):
71
        $cardinal = 'SWbS';
72
        break;
73
     case ($dir >= 219 && $dir < 231):
74
        $cardinal = 'SW';
75
        break;
76
     case ($dir >= 231 && $dir < 242):
77
        $cardinal = 'SWbW';
78
        break;
79
     case ($dir >= 242 && $dir < 253):
80
        $cardinal = 'WSW';
81
        break;
82
     case ($dir >= 253 && $dir < 264):
83
        $cardinal = 'WbS';
84
        break;
85
     case ($dir >= 264 && $dir < 276):
86
        $cardinal = 'W';
87
        break;
88
     case ($dir >= 276 && $dir < 287):
89
        $cardinal = 'WbN';
90
        break;
91
     case ($dir >= 287 && $dir < 298):
92
        $cardinal = 'WNW';
93
        break;
94
     case ($dir >= 298 && $dir < 309):
95
        $cardinal = 'NWbW';
96
        break;
97
     case ($dir >= 309 && $dir < 321):
98
        $cardinal = 'NW';
99
        break;
100
     case ($dir >= 321 && $dir < 332):
101
        $cardinal = 'NWbN';
102
        break;
103
     case ($dir >= 332 && $dir < 343):
104
        $cardinal = 'NNW';
105
        break;
106
     case ($dir >= 343 && $dir < 354):
107
        $cardinal = 'NbW';
108
        break;
109
  }
110
 
111
 return $cardinal;
112
}

Shortcode Attributes

The following attributes are available for use in your shortcode.

apikey

The API is required and may be obtained for free from the OWM website.

location

The shortcode accepts either a city/country combination (often just the city), or city ID. The API also accepts latitude and longitude or zipcode - neither of which was included in the shortcode simply for the sake of simplicity. If you're using our locations plugin, the latitude and longitude combination works well for an addition to the location landing page.

If you're using a city/country pair, ensure you use ISO country codes and don't use spaces.

offset

This if the GMT offset for the defined location (assuming you're not returning the time as UTC).

version

The API version.

cache

The cache period. Again, Simple Cache is required.

PHP Function

Used outside of WordPress, the following function may be used.

1
<?php 
2
include('../simple-cache/cache.inc.php');
3
 
4
/*
5
 Embed Weather Underground Forecasts with WordPress Shortcode or PHP
6
 http://www.beliefmedia.com/weather-underground-forecasts
7
*/
8
 
9
function beliefmedia_openweathermap_current($location, $version = '2.5', $apikey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx', $cache = '7200') {
10
 
11
  $transient = 'bm_owm_' . md5(serialize(func_get_args()));
12
  $cachedresult =  beliefmedia_get_transient($transient, $cache);
13
  if ($cachedresult !== false) return $cachedresult;
14
 
15
  /* May request by free text, ID, lat/lng, or ZIP. Two provided for example */
16
  $request = (is_numeric($location)) ? 'http://api.openweathermap.org/data/' . $version . '/weather?id=' . $location . '&appid=' . $apikey : 'http://api.openweathermap.org/data/' . $version . '/forecast?q=' . $location . '&appid=' . $apikey;
17
 
18
  /* Get current weather */
19
  $weather = @file_get_contents($request);
20
  if ($weather === false) return beliefmedia_get_transient_data($transient);
21
  $weather = json_decode($weather, true);
22
 
23
  /* The portion of the weather array you're displaying */
24
  $weather = array_slice($weather['list'], 6, 5);
25
 
26
  /* Generate HTML */
27
  foreach ($weather AS $day) {
28
 
29
    $result .= '<div class="bm-owm-col">
30
      <span class="bm-owm-img"><img src="http://openweathermap.org/img/w/' . $day['weather']['0']['icon'] . '.png"></span>
31
<p style="clear: both; margin-top: 0.2em; margin-bottom: 0em;"><p>      ' . date('jS g:ia', strtotime($day['dt_txt'])) . '
32
      Temp : ' . round($day['main']['temp_max'] - 273.15, 1) . '°C
33
      QNH : ' . round($day['main']['sea_level']) . 'hPa
34
      RH : ' . $day['main']['humidity'] . '%
35
      ' . $day['weather']['0']['description'] . '
36
      Wind: ' . beliefmedia_compass_cardinal($day['wind']['deg']) . ' ' . round($day['wind']['speed'] * 1.94384617179) . 'kt
37
   </div>';
38
 
39
  }
40
 
41
  $style = '
42
<style scoped>
43
  html {
44
    box-sizing: border-box;
45
  }
46
 
47
  *, *:before, *:after {
48
    box-sizing: inherit;
49
  }
50
 
51
  .bm-owm-row {
52
    display: flex;
53
    flex-wrap: wrap;
54
    align-items: center;
55
  }
56
 
57
  .bm-owm-col {
58
    flex: 1 1 20%;
59
    min-width: 90px;
60
    font-size: 0.9em;
61
    color: black;
62
    padding: 0px 10px 5px 10px;
63
    align-items: center;
64
    justify-content: center;
65
  }
66
 
67
  .bm-owm-img {
68
    min-width: 90px;
69
    text-align: center;
70
  }
71
 
72
  .bm-owm-col img {
73
    margin: 0 auto;
74
    width: 50px;
75
    height: 50px;
76
    text-align: center;
77
    padding: 1px;
78
  }</style>
79
 
80
';
81
 
82
  /* Container & Style */
83
  $return = '<div>' . $style . '<div class="bm-owm-row">';
84
 
85
  /* Weather */
86
  $return .= $result;
87
  $return .= '
88
<p style="font-size: 0.8em;">Weather supplied by OpenWeatherMap.org';
89
 
90
  /* Container */
91
  $return .= '</p></div>
92
</div>';
93
 
94
  /* Cache result */
95
  beliefmedia_set_transient($transient, $return);
96
 
97
 return $return;
98
}
99
 
100
/* Usage */
101
echo beliefmedia_openweathermap_current('sydney,au');

Simple Cache and the beliefmedia_compass_cardinal() function are required.

Considerations

  • API information is available here . An API key is required.
  • Since data is obtained partially from an array of user weather stations, the information isn't as reliable as information sourced from the Australian Bureau of Meteorology or the US National Weather Service.
  • Weather conditions and weather icons are listed here . While OWM permits hotlinking of their images, it's not a bad idea to host them locally. Additional icon sets are floating around the web.
  • A full list of city codes (for use when referencing a city by location ID) is available here .
  • There are plenty of good OWM PHP libraries on the web. OWM lists this one hosted on Github.
  • We've used array_slice($weather['list'], 6, 5); on line 36 of the shortcode function. This extracts part of the array; in this case, starting at the 6th element with an offset of 5. You may alter this as required. If you return any more than 5 elements they'll be rendered on a new row.
  • We have converted the default Kelvin temperature to Celsius on line 45. Alter as required for any other unit.
  • You may iterate over the returned weather array and return a multi-day forecast. This will likely be the subject of the next post relating to OWM.
  • If you were to use this code you will want to make a number of modification... starting with moving the styling to your custom functions CSS file.
  • The code is very basic and is provided only as an example. It needs work before it's website-ready.

Download


Title: Open Weather Map (Day Forecast), WordPress Shortcode
Description: Weather Forecasts with OpenWeatherMap in WordPress or PHP.
  Download • Version 0.1, 1.9K, zip, Category: WordPress Shortcodes
PHP Code & Snippets, (1.8K)    

Download our 650-page guide on Finance Marketing. We'll show you exactly how we generate Billions in volume for our clients.

  AUS Eastern Standard Time (Connecticut)

  Want to have a chat?
 

Like this article?

Share on facebook
Share on Facebook
Share on twitter
Share on Twitter
Share on linkedin
Share on Linkdin
Share on pinterest
Share on Pinterest

Leave a comment