Weather Underground - Version 1.0

Version Description

  • Initial launch

=

Download this release

Release Info

Developer katzwebdesign
Plugin Icon 128x128 Weather Underground
Version 1.0
Comparing to
See all releases

Version 1.0

readme.txt ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ === Weather Forecast - WP Wunderground ===
2
+ Tags: weather, weather.com, wunderground, weatherbug, forecast, widget, shortcode, Yahoo weather, Yahoo! Weather, wp-weather, wp weather, local weather, weather man, weather widget, cool weather, accuweather, get weather
3
+ Requires at least: 2.8
4
+ Tested up to: 3.0.1
5
+ Stable tag: trunk
6
+ Contributors: katzwebdesign
7
+ Donate link:https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=zackkatz%40gmail%2ecom&item_name=WP%20Wunderground%20for%20WordPress&no_shipping=0&no_note=1&tax=0&currency_code=USD&lc=US&bn=PP%2dDonationsBF&charset=UTF%2d8
8
+
9
+ Get accurate and beautiful weather forecasts powered by Wunderground.com for your content or your sidebar.
10
+
11
+ == Description ==
12
+
13
+ <h3>Wunderground is the best weather site.</h3>
14
+
15
+ __All your weather are belong to us!__ Wunderground.com has the most accurate and in-depth weather information. They're also not evil corporate giants, and are weather geeks, which is nice.
16
+
17
+ This plugin uses the Wunderground API to gather its accurate forcasts.
18
+
19
+
20
+ <h3>If you want a great-looking weather forecast, use this plugin.</h3>
21
+ __This is the best-looking weather forecast plugin for WordPress.__ It looks great on many different templates out of the box, including the default WP theme, TwentyTen.
22
+
23
+ The WP Wunderground plugin uses 10 great-looking icon sets from Wunderground.com, including:
24
+
25
+ * <a href="http://icons-ecast.wxug.com/i/c/a/clear.gif" target="_blank" rel="nofollow">Default</a>
26
+ * <a href="http://icons-ecast.wxug.com/i/c/b/clear.gif" target="_blank" rel="nofollow">Smiley</a>
27
+ * <a href="http://icons-ecast.wxug.com/i/c/c/clear.gif" target="_blank" rel="nofollow">Generic</a>
28
+ * <a href="http://icons-ecast.wxug.com/i/c/d/clear.gif" target="_blank" rel="nofollow">Old School</a>
29
+ * <a href="http://icons-ecast.wxug.com/i/c/e/clear.gif" target="_blank" rel="nofollow">Cartoon</a>
30
+ * <a href="http://icons-ecast.wxug.com/i/c/f/clear.gif" target="_blank" rel="nofollow">Mobile</a>
31
+ * <a href="http://icons-ecast.wxug.com/i/c/g/clear.gif" target="_blank" rel="nofollow">Simple</a>
32
+ * <a href="http://icons-ecast.wxug.com/i/c/h/clear.gif" target="_blank" rel="nofollow">Contemporary</a>
33
+ * <a href="http://icons-ecast.wxug.com/i/c/i/clear.gif" target="_blank" rel="nofollow">Helen</a>
34
+ * <a href="http://icons-ecast.wxug.com/i/c/k/clear.gif" target="_blank" rel="nofollow">Incredible</a>
35
+
36
+ Check out the Screenshots section for pictures.
37
+
38
+ <h3>Using the WP Wunderground Weather Plugin</h3>
39
+ The plugin can be configured in two ways:
40
+
41
+ 1. Configure the plugin in the admin's WP Wunderground settings page, then add `[forecast]` to your content where you want the forecast to appear.
42
+ 2. Go crazy with the `[forecast]` shortcode.
43
+
44
+ <h4>Using the `[forecast]` Shortcode</h4>
45
+ If you're a maniac for shortcodes, and you want all control all the time, this is a good way to use it.
46
+
47
+ `[forecast location="Tokyo, Japan" caption="Weather for Tokyo" measurement='F' todaylabel="Today" datelabel="date('m/d/Y')" highlow='%%high%%&deg;/%%low%%&deg;' numdays="3" iconset="Cartoon" class="css_table_class"]`
48
+
49
+ <strong>The shortcode supports the following settings:</strong>
50
+
51
+ * `location="Tokyo, Japan"` - Use any city/state combo or US/Canada ZIP code
52
+ * `caption="Weather for Tokyo"` - Add a caption to your table (it's like a title)
53
+ * `measurement='F'` - Choose Fahrenheit or Celsius by using "F" or "C"
54
+ * `datelabel="date('m/d/Y')"` - Format the way the days display ("9/30/2012" in this example)
55
+ * `todaylabel="Today"` - Format how today's date appears ("Today" in this example)
56
+ * `highlow='%%high%%&deg;/%%low%%&deg;'` - Format how the highs & low temps display ("85&deg;/35&deg;" in this example)
57
+ * `numdays=3` - Change the number of days displayed in the forecast. Up to 6 day forecast.
58
+ * `iconset="Cartoon"` - Choose your iconset from one of 10 great options
59
+ * `class="css_table_class"` - Change the CSS class of the generated forecast table
60
+
61
+ <h4>Learn more on the <a href="http://www.seodenver.com/wunderground/">official plugin page</a></h4>
62
+
63
+ == Installation ==
64
+
65
+ 1. Upload plugin files to your plugins folder, or install using WordPress' built-in Add New Plugin installer
66
+ 1. Activate the plugin
67
+ 1. Go to the plugin settings page (under Settings > WP Wunderground)
68
+ 1. Configure the settings on the page. (Instructions for some setting configurations are on the box to the right)
69
+ 1. Click Save Changes.
70
+ 1. When editing posts, use the `[forecast]` "shortcode" as described on this plugin's Description tab
71
+
72
+ == Screenshots ==
73
+
74
+ 1. Embedded in content in the twentyten theme
75
+ 1. Embedded in content in the twentyten theme, alternate settings
76
+ 1. In the sidebar of the Motion theme
77
+ 1. In the sidebar of the ChocoTheme theme
78
+ 1. In the sidebar of the Piano Black theme
79
+ 1. In the sidebar of the twentyten theme
80
+ 1. Plugin configuration page
81
+
82
+ == Frequently Asked Questions ==
83
+
84
+ = I want to modify the forecast output. How do I do that? =
85
+
86
+ <pre>
87
+ function replace_weather($content) {
88
+ $content = str_replace('Rain', 'RAYNNNNN!', $content);
89
+ $content = str_replace('Snow', 'SNNNOOOO!', $content);
90
+ return $content;
91
+ }
92
+ add_filter('wp_wunderground_forecast', 'replace_weather');
93
+ </pre>
94
+
95
+ = What is the plugin license? =
96
+
97
+ * This plugin is released under a GPL license.
98
+
99
+ = Do I need a Wunderground account? =
100
+ Nope, no account needed.
101
+
102
+ = This plugin slows down my site. =
103
+ It is recommended to use a caching plugin (such as WP Super Cache) with this plugin; that way the forecast isn't re-loaded every page load.
104
+
105
+ = Why would I want this plugin? =
106
+ This plugin is a perfect compliment for regional websites (about a city or town), personal websites where you want to share what the weather is like where you're blogging from, travel sites (show the weather at each stop!), <a href="http://www.denversnowremovalservice.com">snow removal</a> websites, yard services websites, and more.
107
+
108
+ == Changelog ==
109
+
110
+ = 1.0 =
111
+ * Initial launch
112
+
113
+ == Upgrade Notice ==
114
+
115
+ = 1.0 =
116
+ * Blastoff!
screenshot-1.jpg ADDED
Binary file
screenshot-2.jpg ADDED
Binary file
screenshot-3.jpg ADDED
Binary file
screenshot-4.jpg ADDED
Binary file
screenshot-5.jpg ADDED
Binary file
screenshot-6.jpg ADDED
Binary file
screenshot-7.jpg ADDED
Binary file
wunderground.php ADDED
@@ -0,0 +1,561 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ Plugin Name: WP Wunderground
4
+ Plugin URI: http://www.seodenver.com/wunderground/
5
+ Description: Get accurate and beautiful weather forecasts powered by Wunderground.com for your content or your sidebar.
6
+ Version: 1.0
7
+ Author: Katz Web Services, Inc.
8
+ Author URI: http://www.seodenver.com/
9
+ */
10
+
11
+ class wp_wunderground {
12
+ var $url = 'http://api.wunderground.com/auto/wui/geo/ForecastXML/index.xml?query=';
13
+ var $location = '90210';
14
+ var $icon_set = 'Incredible';
15
+ var $measurement = 'fahrenheit';
16
+ var $type = 'table';
17
+ var $align = 'center';
18
+ var $highlow = '%%high%%/%%low%%';
19
+ var $caption = 'Weather for Beverly Hills';
20
+ var $numdays = 6;
21
+ var $datelabel = '%%weekday%%';
22
+ var $todaylabel = 'Today';
23
+ var $showlink = 'yes';
24
+
25
+ function wp_wunderground() {
26
+
27
+ add_action('admin_menu', array(&$this, 'admin'));
28
+ add_filter('plugin_action_links', array(&$this, 'settings_link'), 10, 2 );
29
+ add_action('admin_init', array(&$this, 'settings_init') );
30
+ $this->options = get_option('wp_wunderground', array());
31
+ add_shortcode('forecast', array(&$this, 'build_forecast'));
32
+
33
+ // Set each setting...
34
+ foreach($this->options as $key=> $value) {
35
+ $this->{$key} = $value;
36
+ }
37
+
38
+ if(!is_admin()) {
39
+ add_action('wp_footer', array(&$this,'showlink'));
40
+ }
41
+ }
42
+
43
+ function settings_init() {
44
+ register_setting( 'wp_wunderground_options', 'wp_wunderground', array(&$this, 'sanitize_settings') );
45
+ }
46
+
47
+ function sanitize_settings($input) {
48
+ return $input;
49
+ }
50
+
51
+ function settings_link( $links, $file ) {
52
+ static $this_plugin;
53
+ if( ! $this_plugin ) $this_plugin = plugin_basename(__FILE__);
54
+ if ( $file == $this_plugin ) {
55
+ $settings_link = '<a href="' . admin_url( 'options-general.php?page=wp_wunderground' ) . '">' . __('Settings', 'wp_wunderground') . '</a>';
56
+ array_unshift( $links, $settings_link ); // before other links
57
+ }
58
+ return $links;
59
+ }
60
+
61
+ function admin() {
62
+ add_options_page('WP Wunderground', 'WP Wunderground', 'administrator', 'wp_wunderground', array(&$this, 'admin_page'));
63
+ }
64
+
65
+ function admin_page() {
66
+ ?>
67
+ <div class="wrap">
68
+ <h2>WP Wunderground: Weather Forecasts for WordPress</h2>
69
+ <div class="postbox-container" style="width:65%;">
70
+ <div class="metabox-holder">
71
+ <div class="meta-box-sortables">
72
+ <form action="options.php" method="post">
73
+ <?php
74
+ wp_nonce_field('update-options');
75
+ settings_fields('wp_wunderground_options');
76
+
77
+
78
+ $rows[] = array(
79
+ 'id' => 'wp_wunderground_location',
80
+ 'label' => __('Location', 'wp_wunderground'),
81
+ 'content' => "<input type='text' name='wp_wunderground[location]' id='wp_wunderground_location' value='".esc_attr($this->location)."' size='40' style='width:95%!important;' /><br /><small>The location can be entered as: ZIP code (US or Canadian); city state; city, state; city; state; country; airport code (3-letter or 4-letter); lat, long.</small>",
82
+ 'desc' => 'The location for the forcast.'
83
+ );
84
+ $rows[] = array(
85
+ 'id' => 'wp_wunderground_numdays',
86
+ 'label' => __('Days of Forecast', 'wp_wunderground'),
87
+ 'desc' => 'How many days would you like to display in the forecast? Supports up to 6.',
88
+ 'content' => $this->buildDays()
89
+ );
90
+
91
+ $rows[] = array(
92
+ 'id' => 'wp_wunderground_measurement',
93
+ 'label' => __('Degree (&deg;) Measurement', 'wp_wunderground'),
94
+ 'desc' => 'Are you metric or U.S., baby?',
95
+ 'content' => $this->buildMeasurement()
96
+ );
97
+
98
+ $rows[] = array(
99
+ 'id' => 'wp_wunderground_caption',
100
+ 'label' => __('Forecast Caption', 'wp_wunderground'),
101
+ 'content' => "<input type='text' name='wp_wunderground[caption]' id='wp_wunderground_caption' value='".esc_attr($this->caption)."' size='40' style='width:95%!important;' />",
102
+ 'desc' => 'This will display above the forecast. Think of it like a forecast title.'
103
+ );
104
+
105
+ $rows[] = array(
106
+ 'id' => 'wp_wunderground_datelabel',
107
+ 'label' => __('"All Dates" Label', 'wp_wunderground'),
108
+ 'content' => "<input type='text' name='wp_wunderground[datelabel]' id='wp_wunderground_datelabel' value='".esc_attr($this->datelabel)."' size='40' style='width:95%!important;' />",
109
+ 'desc' => 'How all dates appear by default. See instructions in the "Date Formatting" section of the box on the right &rarr;'
110
+ );
111
+
112
+ $rows[] = array(
113
+ 'id' => 'wp_wunderground_todaylabel',
114
+ 'label' => __('"Today\'s Date" Label', 'wp_wunderground'),
115
+ 'content' => "<input type='text' name='wp_wunderground[todaylabel]' id='wp_wunderground_todaylabel' value='".esc_attr($this->todaylabel)."' size='40' style='width:95%!important;' />",
116
+ 'desc' => 'How today\'s date appears (overrides All Dates format). See instructions in the "Date Formatting" section of the box on the right &rarr;'
117
+ );
118
+
119
+ $rows[] = array(
120
+ 'id' => 'wp_wunderground_highlow',
121
+ 'label' => __('"High/Low" Formatting', 'wp_wunderground'),
122
+ 'desc' => 'See instructions in the "Highs &amp; Lows Formatting" section of the box on the right &rarr;',
123
+ 'content' => "<input type='text' name='wp_wunderground[highlow]' id='wp_wunderground_highlow' value='".esc_attr($this->highlow)."' size='40' style='width:95%!important;' />"
124
+ );
125
+
126
+
127
+ $rows[] = array(
128
+ 'id' => 'wp_wunderground_icon_set',
129
+ 'label' => __('Icon Set', 'wp_wunderground'),
130
+ 'desc' => 'How do you want your weather icons to look?',
131
+ 'content' => $this->buildIconSet()
132
+ );
133
+
134
+ $checked = (empty($this->showlink) || $this->showlink == 'yes') ? ' checked="checked"' : '';
135
+
136
+ $rows[] = array(
137
+ 'id' => 'wp_wunderground_showlink',
138
+ 'label' => __('Give Thanks', 'wp_wunderground'),
139
+ 'desc' => 'Checking the box tells the world you use this free plugin by adding a link to your footer. If you don\'t like it, you can turn it off, so please enable.',
140
+ 'content' => "<p><label for='wp_wunderground_showlink'><input type='hidden' name='wp_wunderground[showlink]' value='no' /><input type='checkbox' name='wp_wunderground[showlink]' value='yes' id='wp_wunderground_showlink' $checked /> Help show the love.</label></p>"
141
+ );
142
+
143
+ $this->postbox('wp_wundergroundsettings',__('Store Settings', 'wp_wunderground'), $this->form_table($rows), false);
144
+
145
+ ?>
146
+
147
+
148
+ <input type="hidden" name="page_options" value="<?php foreach($rows as $row) { $output .= $row['id'].','; } echo substr($output, 0, -1);?>" />
149
+ <input type="hidden" name="action" value="update" />
150
+ <p class="submit">
151
+ <input type="submit" class="button-primary" name="save" value="<?php _e('Save Changes', 'wp_wunderground') ?>" />
152
+ </p>
153
+ </form>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ <div class="postbox-container" style="width:34%;">
158
+ <div class="metabox-holder">
159
+ <div class="meta-box-sortables">
160
+ <?php $this->postbox('wp_wundergroundhelp',__('Configuring This Plugin', 'wp_wunderground'), $this->configuration(), true); ?>
161
+ </div>
162
+ </div>
163
+ </div>
164
+
165
+ </div>
166
+ <?php
167
+ }
168
+
169
+ function showLink() {
170
+ if($this->showlink == 'yes') {
171
+ mt_srand(crc32($_SERVER['REQUEST_URI'])); // Keep links the same on the same page
172
+
173
+ $urls = array('http://www.seodenver.com/wunderground/?ref=foot', 'http://wordpress.org/extend/plugins/wunderground/', 'http://www.denversnowremovalservice.com/weather/');
174
+ $url = $urls[mt_rand(0, count($urls)-1)];
175
+ $names = array('WP Wunderground', 'Wordpress Weather', 'Wunderground for WordPress');
176
+ $name = $names[mt_rand(0, count($names)-1)];
177
+ $kws = array('Denver Snow Removal', 'Denver Snow Plowing', 'Denver Snow Service');
178
+ $kw = $kws[mt_rand(0, count($kws)-1)];
179
+ $links = array(
180
+ 'The forecast for '.$this->location.' by <a href="'.$url.'">'.$name.'</a>',
181
+ 'Weather forecast by WP Wunderground &amp; <a href="'.$url.'">'.$kw.'</a>',
182
+ 'Our weather forecast is from <a href="'.$url.'">'.$name.'</a>'
183
+ );
184
+ $link = '<p class="wp_wunderground" style="text-align:center;">'.trim($links[mt_rand(0, count($links)-1)]).'</p>';
185
+
186
+ echo apply_filters('wp_wunderground_showlink', $link);
187
+
188
+ mt_srand(); // Make it random again.
189
+ }
190
+ }
191
+
192
+ function buildDays() {
193
+ $c = ' selected="selected"';
194
+ $output = '<select id="wp_wunderground_numdays" name="wp_wunderground[numdays]">';
195
+ $output .= ' <option value="1"'; if($this->numdays == '1') { $output .= $c; } $output .= '>1 Day</option>';
196
+ $output .= ' <option value="2"'; if($this->numdays == '2') { $output .= $c; } $output .= '>2 Days</option>';
197
+ $output .= ' <option value="3"'; if($this->numdays == '3') { $output .= $c; } $output .= '>3 Days</option>';
198
+ $output .= ' <option value="4"'; if($this->numdays == '4') { $output .= $c; } $output .= '>4 Days</option>';
199
+ $output .= ' <option value="5"'; if($this->numdays == '5') { $output .= $c; } $output .= '>5 Days</option>';
200
+ $output .= ' <option value="6"'; if($this->numdays == '6') { $output .= $c; } $output .= '>6 Days</option>';
201
+ $output .= '</select>';
202
+ $output .= '<label for="wp_wunderground_numdays" style="padding-left:10px;"># of Days in Forecast:</label>';
203
+ return $output;
204
+ }
205
+
206
+ function buildMeasurement() {
207
+ $c = ' selected="selected"';
208
+ $output = '<select id="wp_wunderground_measurement" name="wp_wunderground[measurement]">';
209
+ $output .= ' <option value="fahrenheit"'; if($this->measurement == 'fahrenheit') { $output .= $c; } $output .= '>U.S. (&deg;F)</option>';
210
+ $output .= ' <option value="celsius"'; if($this->measurement == 'celcius') { $output .= $c; } $output .= '>Metric (&deg;C)</option>';
211
+ $output .= '</select>';
212
+ $output .= '<label for="wp_wunderground_measurement" style="padding-left:10px;">Fahrenheit or Celsius:</label>';
213
+ return $output;
214
+ }
215
+
216
+ function buildIconSet() {
217
+ $c = ' selected="selected"';
218
+ $output = '<label for="wp_wunderground_icon_set" style="padding-right:10px;">Icon Set:</label>';
219
+ $output .= '<select id="wp_wunderground_icon_set" name="wp_wunderground[icon_set]">';
220
+ $output .= ' <option value="Default"'; if($this->icon_set == 'Default') { $output .= $c; } $output .= '>Default</option>';
221
+ $output .= ' <option value="Smiley"'; if($this->icon_set == 'Smiley') { $output .= $c; } $output .= '>Smiley</option>';
222
+ $output .= ' <option value="Generic"'; if($this->icon_set == 'Generic') { $output .= $c; } $output .= '>Generic</option>';
223
+ $output .= ' <option value="Old School"'; if($this->icon_set == 'Old School') { $output .= $c; } $output .= '>Old School</option>';
224
+ $output .= ' <option value="Cartoon"'; if($this->icon_set == 'Cartoon') { $output .= $c; } $output .= '>Cartoon</option>';
225
+ $output .= ' <option value="Mobile"'; if($this->icon_set == 'Mobile') { $output .= $c; } $output .= '>Mobile</option>';
226
+ $output .= ' <option value="Simple"'; if($this->icon_set == 'Simple') { $output .= $c; } $output .= '>Simple</option>';
227
+ $output .= ' <option value="Contemporary"'; if($this->icon_set == 'Contemporary') { $output .= $c; } $output .= '>Contemporary</option>';
228
+ $output .= ' <option value="Helen"'; if($this->icon_set == 'Helen') { $output .= $c; } $output .= '>Helen</option>';
229
+ $output .= ' <option value="Incredible"'; if($this->icon_set == 'Incredible') { $output .= $c; } $output .= '>Incredible</option>';
230
+ $output .= '</select>';
231
+
232
+ $output .= '
233
+ <div style="margin-top:1em; text-align:center;">
234
+ <div style="padding-right:10px; width:100px; height:75px; float:left;"><img src="http://icons-ecast.wxug.com/i/c/a/clear.gif" width="50" height="50" /><img src="http://icons-ecast.wxug.com/i/c/a/rain.gif" width="50" height="50" /><br />Default</div>
235
+ <div style="padding-right:10px; width:100px; height:67px; float:left; padding-top:8px;"><img src="http://icons-ecast.wxug.com/i/c/b/clear.gif" width="42" height="42" /><img src="http://icons-ecast.wxug.com/i/c/b/rain.gif" width="42" height="42" /><br />Smiley</div>
236
+ <div style="padding-right:10px; width:100px; height:75px; float:left;"><img src="http://icons-ecast.wxug.com/i/c/c/clear.gif" width="50" height="50" /><img src="http://icons-ecast.wxug.com/i/c/c/rain.gif" width="50" height="50" /><br />Generic</div>
237
+ <div style="padding-right:10px; width:100px; height:67px; float:left; padding-top:8px;"><img src="http://icons-ecast.wxug.com/i/c/d/clear.gif" width="42" height="42" /><img src="http://icons-ecast.wxug.com/i/c/d/rain.gif" width="42" height="42" /><br />Old School</div>
238
+ <div style="padding-right:10px; width:100px; height:67px; float:left; padding-top:8px;"><img src="http://icons-ecast.wxug.com/i/c/e/clear.gif" width="42" height="42" /><img src="http://icons-ecast.wxug.com/i/c/e/rain.gif" width="42" height="42" /><br />Cartoon</div>
239
+ <div style="padding-right:10px; width:100px; height:67px; float:left; padding-top:8px;"><img src="http://icons-ecast.wxug.com/i/c/f/clear.gif" width="42" height="42" /><img src="http://icons-ecast.wxug.com/i/c/f/rain.gif" width="42" height="42" /><br />Mobile</div>
240
+ <div style="padding-right:10px; width:100px; height:75px; float:left;"><img src="http://icons-ecast.wxug.com/i/c/g/clear.gif" width="50" height="50" /><img src="http://icons-ecast.wxug.com/i/c/g/rain.gif" width="50" height="50" /><br />Simple</div>
241
+ <div style="padding-right:10px; width:100px; height:75px; float:left;"><img src="http://icons-ecast.wxug.com/i/c/h/clear.gif" width="50" height="50" /><img src="http://icons-ecast.wxug.com/i/c/h/rain.gif" width="50" height="50" /><br />Contemporary</div>
242
+ <div style="padding-right:10px; width:100px; height:75px; float:left;"><img src="http://icons-ecast.wxug.com/i/c/i/clear.gif" width="50" height="50" /><img src="http://icons-ecast.wxug.com/i/c/i/rain.gif" width="50" height="50" /><br />Helen</div>
243
+ <div style="padding-right:10px; width:100px; height:75px; float:left;"><img src="http://icons-ecast.wxug.com/i/c/k/clear.gif" width="50" height="50" /><img src="http://icons-ecast.wxug.com/i/c/k/rain.gif" width="50" height="50" /><br />Incredible</div>
244
+ </div>
245
+ ';
246
+
247
+ return $output;
248
+ }
249
+
250
+ function configuration() {
251
+ $date2 = date('m-d-y');
252
+ $date = date('m/d/Y');
253
+ $weekday = date('l');
254
+ $html = <<<EOD
255
+ <h4>Adding the Forecast to your Content</h4>
256
+ <p class="howto updated" style="padding:1em;">If you configure the settings to the left, all you will need to do is add <code>[forecast]</code> to your post or page content or text widget to add the forecast table.</p>
257
+ <h4>Date Formatting</h4>
258
+ <p>You can use the following tags: <code>%%weekday%%</code>, <code>%%day%%</code>, <code>%%month%%</code>, <code>%%year%%</code>, as well as using <a href="http://www.php.net/manual/en/function.date.php" target="_blank">PHP date formatting</a>.</p>
259
+ <h4>Example date options:</h4>
260
+ <ul>
261
+ <li><code>Today's Weather (%%weekday%%)</code> <em>outputs as:&nbsp;</em> <strong>Today's Weather ($weekday)</strong></li>
262
+ <li><code>%%day%%<strong>/</strong>%%month%%<strong>/</strong>%%year%% Weather</code> <em>outputs as:&nbsp;</em> <strong>$date Weather</strong></li>
263
+ <li><code>Weather on date("m/d/Y")</code> <em>outputs as:&nbsp;</em> <strong>Weather on $date</strong></li>
264
+ <li><code>date("\W\e\a\\t\h\e\\r\ \\f\o\\r\ m-d-y")</code> <em>outputs as:&nbsp;</em> <strong>Weather for $date2</strong></li>
265
+ </ul>
266
+ <hr style="padding-top:1em; outline:none; border:none; border-bottom:1px solid #ccc;"/>
267
+ <h4>Highs &amp; Lows Formatting</h4>
268
+ <p>Use the following tags to modify how low and high temps display: <code>%%high%%</code> and <code>%%low%%</code>.</p>
269
+ <ul>
270
+ <li><strong>HTML is fully supported. This allows you to color-code:</strong><br /><code>&lt;span style=&quot;color:red;&quot;&gt;%%high%%&lt;/span&gt;/&lt;span style=&quot;color:blue;&quot;&gt;%%low%%&lt;/span&gt;</code> <em>outputs as:&nbsp;</em> <span style="color:red;">85</span>/<span style="color:blue;">55</span></li>
271
+ <li><strong>Choose to only show high or low:</strong><br /><code>High of %%high%%.</code> <em>outputs as:&nbsp;</em> High of 85.</li>
272
+ <li><strong>Use CSS classes too:</strong><br /><code>&lt;div class=&quot;temp&quot;&gt;High of &lt;span class=&quot;temphigh&quot;&gt;%%high%%&lt;/span&gt;&lt;br /&gt;Low of &lt;span class=&quot;templow&quot;&gt;%%low%%&lt;/span&gt;&lt;/div&gt;</code> <em>outputs as:&nbsp;</em> <div class="temp">High of <span class="temphigh">85</span><br />Low of <span class="templow">55</span></div></li>
273
+ </ul>
274
+ <hr style="padding-top:1em; outline:none; border:none; border-bottom:1px solid #ccc;"/>
275
+
276
+ <h4>Using the <code>[forecast]</code> Shortcode</h4>
277
+
278
+ <p>If you're a maniac for shortcodes, and you want all control all the time, this is a good way to use it.</p>
279
+
280
+ <p><code>[forecast location="Tokyo, Japan" caption="Weather for Tokyo" measurement='F' todaylabel="Today" datelabel="date('m/d/Y')" highlow='%%high%%&deg;/%%low%%&deg;' numdays="3" iconset="Cartoon" class="css_table_class"]</code></p>
281
+
282
+ <p><strong>The shortcode supports the following settings:</strong></p>
283
+ <ul>
284
+ <li><code>location="Tokyo, Japan"</code> - Use any city/state combo or US/Canada ZIP code
285
+ </li><li><code>caption="Weather for Tokyo"</code> - Add a caption to your table (it's like a title)
286
+ </li><li><code>measurement='F'</code> - Choose Fahrenheit or Celsius by using "F" or "C"
287
+ </li><li><code>datelabel="date('m/d/Y')"</code> - Format the way the days display ("9/30/2012" in this example)
288
+ </li><li><code>todaylabel="Today"</code> - Format how today's date appears ("Today" in this example)
289
+ </li><li><code>highlow='%%high%%&deg;/%%low%%&deg;'</code> - Format how the highs & low temps display ("85&deg;/35&deg;" in this example)
290
+ </li><li><code>numdays=3</code> - Change the number of days displayed in the forecast. Up to 6 day forecast.
291
+ </li><li><code>iconset="Cartoon"</code> - Choose your iconset from one of 10 great options
292
+ </li><li><code>class="css_table_class"</code> - Change the CSS class of the generated forecast table
293
+ </ul>
294
+
295
+ EOD;
296
+ return $html;
297
+ }
298
+
299
+ // THANKS JOOST!
300
+ function form_table($rows) {
301
+ $content = '<table class="form-table" width="100%">';
302
+ foreach ($rows as $row) {
303
+ $content .= '<tr><th valign="top" scope="row" style="width:50%">';
304
+ if (isset($row['id']) && $row['id'] != '')
305
+ $content .= '<label for="'.$row['id'].'" style="font-weight:bold;">'.$row['label'].':</label>';
306
+ else
307
+ $content .= $row['label'];
308
+ if (isset($row['desc']) && $row['desc'] != '')
309
+ $content .= '<br/><small>'.$row['desc'].'</small>';
310
+ $content .= '</th><td valign="top">';
311
+ $content .= $row['content'];
312
+ $content .= '</td></tr>';
313
+ }
314
+ $content .= '</table>';
315
+ return $content;
316
+ }
317
+
318
+ function postbox($id, $title, $content, $padding=false) {
319
+ ?>
320
+ <div id="<?php echo $id; ?>" class="postbox">
321
+ <div class="handlediv" title="Click to toggle"><br /></div>
322
+ <h3 class="hndle"><span><?php echo $title; ?></span></h3>
323
+ <div class="inside" <?php if($padding) { echo 'style="padding:10px; padding-top:0;"'; } ?>>
324
+ <?php echo $content; ?>
325
+ </div>
326
+ </div>
327
+ <?php
328
+ }
329
+
330
+ function r($content, $kill = false) {
331
+ echo '<pre>'.print_r($content,true).'</pre>';
332
+ if($kill) { die(); }
333
+ }
334
+
335
+ function build_forecast($atts, $content=null) {
336
+ extract( shortcode_atts( array(
337
+ 'location' => $this->location,
338
+ 'measurement' => $this->measurement,
339
+ 'highlow' => $this->highlow,
340
+ 'iconset' => $this->icon_set,
341
+ 'align' => $this->align,
342
+ 'numdays' => $this->numdays,
343
+ 'caption' => $this->caption,
344
+ 'datelabel' => $this->datelabel,
345
+ 'todaylabel' => $this->todaylabel,
346
+ 'class' => 'wp_wunderground'
347
+ ), $atts ) );
348
+
349
+ // They're hard to spell and long, man!
350
+ $measurement = strtolower($measurement);
351
+ if($measurement == 'c') { $measurement = 'celsius'; }
352
+ if($measurement == 'f') { $measurement = 'fahrenheit'; }
353
+
354
+ if(!$xml=simplexml_load_file($this->url.$location)){
355
+ trigger_error('Error reading XML file',E_USER_ERROR);
356
+ return '<!-- WP Wunderground Error : Error reading XML file at '.$this->url.$this->location.' -->'.$content;
357
+ } else if(!empty($xml->simpleforecast->forecastday)) {
358
+
359
+ # $this->r($xml->simpleforecast); // For debug...
360
+
361
+ $i = 0;
362
+
363
+ foreach($xml->simpleforecast->forecastday as $day) {
364
+ # $this->r($day); // For debug...
365
+ if($i < $numdays) {
366
+ $day = simpleXMLToArray($day);
367
+ extract($day);
368
+ $icon_url = $this->get_icon_path($icons, $iconset).$icon.'.gif';
369
+ $icon_size = $this->get_icon_size($iconset);
370
+ $icon_size = " width=\"$icon_size\" height=\"$icon_size\"";
371
+ $high = $high[$measurement];
372
+ $low = $low[$measurement];
373
+ $icon = '<img src="'.$icon_url.'"'.$icon_size.' alt="It is forcast to be '.$conditions.' at '.$date['pretty'].'" style="display:block;" />';
374
+ $width = 100/$this->numdays;
375
+
376
+ $temp = str_replace('%%high%%', $high, $highlow);
377
+ $temp = str_replace('%%low%%', $low, $temp);
378
+ $label = $this->format_date($date, $todaylabel, $datelabel);
379
+
380
+ $tablehead .= "\n\t\t\t\t\t\t\t".'<th scope="col" width="'.$width.'%" align="'.$align.'">'.$label.'</th>';
381
+
382
+ $tablebody .=
383
+ "\n\t\t\t\t\t\t\t".'<td align="'.$align.'">'.$icon.'<div class="wp_wund_conditions">'.$conditions.'</div>'.$temp.'</td>';
384
+ }
385
+ $i++;
386
+ }
387
+ if(!empty($caption)) {
388
+ $caption = "\n\t\t\t\t\t<caption>{$caption}</caption>";
389
+ }
390
+ $table = '
391
+ <table cellpadding="0" cellspacing="0" border="0" width="100%" class="'.esc_attr($class).'">'.$caption.'
392
+ <thead>
393
+ <tr>'.$tablehead.'
394
+ </tr>
395
+ </thead>
396
+ <tbody>
397
+ <tr>'.$tablebody.'
398
+ </tr>
399
+ </tbody>
400
+ </table>';
401
+ return apply_filters('wp_wunderground_forecast', $table);
402
+ } else {
403
+ return '<!-- WP Wunderground Error : Weather feed was empty from '.$this->url.$this->location.' -->'.$content;
404
+ }
405
+ }
406
+
407
+ function format_date($date, $todaylabel = false, $datelabel = false) {
408
+ if(!$todaylabel) { $todaylabel = $this->todaylabel; }
409
+ if(!$datelabel) { $datelabel = $this->datelabel; }
410
+ extract($date);
411
+
412
+ try {
413
+ $dt = new DateTime("$year-$month-$day", new DateTimeZone($tz_long));
414
+ $dt->setTime($hour,$min,$sec);
415
+ $tt = new DateTime('', new DateTimeZone($tz_long));
416
+ if($tt->format('Y-m-d') == $dt->format('Y-m-d')) { $label = $todaylabel; } else { $label = $datelabel; }
417
+ } catch(Exception $e) {
418
+
419
+ }
420
+
421
+ // First we do these easy date replacements
422
+ $label = str_replace('%%weekday%%', $weekday, $label);
423
+ $label = str_replace('%%day%%', $day, $label);
424
+ $label = str_replace('%%month%%', $month, $label);
425
+ $label = str_replace('%%year%%', $year, $label);
426
+
427
+ // Then we look for the php date() function
428
+ preg_match('/(.*?)date\([\'"]{0,1}(.*?)[\'"]{0,1}\)(.*?)/xism', $label, $matches);
429
+ if(!empty($matches)) {
430
+ try {
431
+ // If we find date(), we format the date
432
+ // and add the before text and after text back in
433
+ $label = $matches[1].$dt->format($matches[2]).$matches[3];
434
+ } catch(Exception $e) {
435
+
436
+ }
437
+ }
438
+ return $label;
439
+ }
440
+
441
+ function get_icon_path($icons, $icon_set = false) {
442
+ if(!$icon_set) { $icon_set = $this->icon_set; }
443
+ // This may be slightly faster; let's try this first.
444
+ switch($icon_set) {
445
+ case 'Default': return 'http://icons-ecast.wxug.com/i/c/a/'; break;
446
+ case 'Smiley': return 'http://icons-ecast.wxug.com/i/c/b/'; break;
447
+ case 'Generic': return 'http://icons-ecast.wxug.com/i/c/c/'; break;
448
+ case 'Old School': return 'http://icons-ecast.wxug.com/i/c/d/'; break;
449
+ case 'Cartoon': return 'http://icons-ecast.wxug.com/i/c/e/'; break;
450
+ case 'Mobile': return 'http://icons-ecast.wxug.com/i/c/f/'; break;
451
+ case 'Simple': return 'http://icons-ecast.wxug.com/i/c/g/'; break;
452
+ case 'Contemporary': return 'http://icons-ecast.wxug.com/i/c/h/'; break;
453
+ case 'Helen': return 'http://icons-ecast.wxug.com/i/c/i/'; break;
454
+ case 'Incredible': return 'http://icons-ecast.wxug.com/i/c/k/'; break;
455
+ }
456
+ // If this doesn't work, use the other method
457
+ $this->get_icon_url($icons, $icon_set);
458
+ }
459
+
460
+ function get_icon_size($icon_set = false) {
461
+ if(!$icon_set) { $icon_set = $this->icon_set; }
462
+ switch($this->icon_set) {
463
+
464
+ case 'Default':
465
+ case 'Helen':
466
+ case 'Generic':
467
+ case 'Simple':
468
+ case 'Contemporary':
469
+ case 'Incredible':
470
+ return 50;
471
+ break;
472
+ case 'Smiley':
473
+ case 'Old School':
474
+ case 'Cartoon':
475
+ case 'Mobile':
476
+ default:
477
+ return 42;
478
+ break;
479
+
480
+ }
481
+ }
482
+
483
+ function get_icon_url($icons) {
484
+ foreach($icons['icon_set'] as $icon) {
485
+ if(strtolower(trim($icon['name'])) == strtolower(trim($this->icon_set))) {
486
+ return $icon['icon_url'];
487
+ }
488
+ }
489
+ return false;
490
+ }
491
+
492
+ }
493
+
494
+
495
+ function simpleXMLToArray($xml,
496
+ $flattenValues=true,
497
+ $flattenAttributes = true,
498
+ $flattenChildren=true,
499
+ $valueKey='@value',
500
+ $attributesKey='@attributes',
501
+ $childrenKey='@children'){
502
+
503
+ $return = array();
504
+ if(!($xml instanceof SimpleXMLElement)){return $return;}
505
+ $name = $xml->getName();
506
+ $_value = trim((string)$xml);
507
+ if(strlen($_value)==0){$_value = null;};
508
+
509
+ if($_value!==null){
510
+ if(!$flattenValues){$return[$valueKey] = $_value;}
511
+ else{$return = $_value;}
512
+ }
513
+
514
+ $children = array();
515
+ $first = true;
516
+ foreach($xml->children() as $elementName => $child){
517
+ $value = simpleXMLToArray($child, $flattenValues, $flattenAttributes, $flattenChildren, $valueKey, $attributesKey, $childrenKey);
518
+ if(isset($children[$elementName])){
519
+ if($first){
520
+ $temp = $children[$elementName];
521
+ unset($children[$elementName]);
522
+ $children[$elementName][] = $temp;
523
+ $first=false;
524
+ }
525
+ $children[$elementName][] = $value;
526
+ }
527
+ else{
528
+ $children[$elementName] = $value;
529
+ }
530
+ }
531
+ if(count($children)>0){
532
+ if(!$flattenChildren){$return[$childrenKey] = $children;}
533
+ else{$return = array_merge($return,$children);}
534
+ }
535
+
536
+ $attributes = array();
537
+ foreach($xml->attributes() as $name=>$value){
538
+ $attributes[$name] = trim($value);
539
+ }
540
+ if(count($attributes)>0){
541
+ if(!$flattenAttributes){$return[$attributesKey] = $attributes;}
542
+ else{$return = array_merge($return, $attributes);}
543
+ }
544
+
545
+ return $return;
546
+ }
547
+
548
+ function init_wp_wunderground() {
549
+ if(method_exists('wp_wunderground', 'wp_wunderground')) {
550
+ $wunder = new wp_wunderground;
551
+ }
552
+ }
553
+
554
+ add_action('plugins_loaded', 'init_wp_wunderground');
555
+
556
+ // If you want to use shortcodes in your widgets, you should!
557
+ add_filter('widget_text', 'do_shortcode');
558
+ add_filter('wp_footer', 'do_shortcode');
559
+
560
+
561
+ ?>