Plugin wp-weather en español para el WordPress mediante algunos tweaks/hacks (weather.com)

Posted on Friday, 7 May 2010

5



Plugin utilizado wp-weather (v0.3.8).

Todo esto hubiese sido más fácil si en la petición X/SOAP, se pudiese especificar el idioma, que si figura en el retorno con el valor en_US, pero como no encontré la forma, veremos como hacer (the hard way).

Como el plugin soporta localization, mediante archivos *.PO y *.MO podemos usar el Poedit para modificar el archivo wp-weather-en_US.po cambiándole lo que se necesite, y luego salvarlo como wp-weather-es_ES.po, compilamos para obtener el archivo *.MO, ambos archivos deben estar en el mismo directorio “wp-content/plugins/wp-weather/localization“, la carga de estos archivos será automático ya que la configuración local del wordpress está en español pero con esto no logramos la traducción de los estados del clima, hasta aquí apenas modificamos algunos títulos estáticos, para más información sobre los archivos *.PO y *.MO en este enlace.

Aquí podemos ver los códigos correspondientes para los estados del clima, en está misma página podemos ver una muestra de la respuesta RSS (forecastrss), pero estaremos más interesados en la respuesta XML, que obtendremos de esta URL mediante el plugin:

http://xoap.weather.com/weather/local/[LOCATION_ID]?cc=*&dayf=[FORECAST_LENGTH]&prod=xoap&par=[PARTNER_ID]&key=[LICENSE_KEY]&link=xoap&unit=[FORECAST_UNIT]

Para obtener el partner_id y la license_key debemos estar suscritos a weather.com, podemos bajar el SDK [Download], para entender mejor los parámetros.

Ok, ahora veamos el output XML que obtenemos del X/SOAP, podemos acceder al XML directamente desde la petición X/SOAP, o accedemos al campo xml_data de la tabla llamada wp_weatherxml que es creada por el plugin, estaremos trabajando particularmente con los tags cc (current condition) y dayf (day forecast), aquí una porción de la estructura:

<cc>
 <lsup>5/6/10 10:00 AM Local Time</lsup>
 <obst>Asuncion, PARAGUAY</obst>
 <tmp>25</tmp><flik>26</flik>
 <t>Mostly Cloudy</t>
 <icon>28</icon>
 <bar><r>1011.9</r><d>steady</d></bar>
 <wind><s>14</s><gust>N/A</gust><d>30</d><t>NNE</t></wind>
 <hmid>69</hmid><vis>10.0</vis><uv><i>3</i><t>Moderate</t></uv><dewp>19</dewp>
 <moon><icon>22</icon><t>Last Quarter</t></moon>
 </cc>

Fijémonos en la linea 6, el código del tag “icono” coincide con el código que vimos en la lista, en esta oportunidad dice “Mostly Cloudy”, es el código del estado del clima que lo cambiaremos a “Muy Nublado”, por ende el tag lo utilizaremos como artificio lógico para representar los estados del clima en español, y en la linea 2, más adelante convertiremos la fecha a un formato localizado.

En el archivo plugins/wp-weather/wp-weather.php después de la función parseSimpleXml($xml, $location_id) copiaremos el siguiente código que lo obtuve de aquí:

	$mensajes = array(
		0 => 'Tornado',
		1 => 'Tormenta Tropical',
		2 => 'Huracán',
		3 => 'Tormentas El&eacute;ctricas Severas',
		4 => 'Tormentas El&eacute;ctricas',
		5 => 'Lluvia y Nieve',
		6 => 'Lluvia y Aguanieve',
		7 => 'Nieve y Aguanieve',
		8 => 'Llovizna congelada',
		9 => 'Llovizna',
		10 => 'Lluvia congelada',
		11 => 'Lluvia',
		12 => 'Lluvia',
		13 => 'R&aacute;fagas de Nieve',
		14 => 'Nevada ligera',
		15 => 'Nieve con viento',
		16 => 'Nieve',
		17 => 'Granizo',
		18 => 'Aguanieve',
		19 => 'Polvo',
		20 => 'Neblina',
		21 => 'Niebla ligera',
		22 => 'Humoso', //Mi traducción sugerida
		23 => 'Vendaval',
		24 => 'Con viento',
		25 => 'Helado',
		26 => 'Nublado',
		27 => 'Muy nublado (noche)',
		28 => 'Muy nublado (dia)',
		29 => 'Parcialmente nublado (noche)',
		30 => 'Parcialmente nublado (dia)',
		31 => 'Despejado (noche)',
		32 => 'Soleado',
		33 => 'Despejado (noche)',
		34 => 'Despejado (dia)',
		35 => 'Lluvia y Granizo',
		36 => 'Caluroso',
		37 => 'Tormentas el&eacute;ctricas aisladas',
		38 => 'Tormentas el&eacute;ctricas dispersas',
		39 => 'Tormentas el&eacute;ctricas dispersas',
		40 => 'Lluvia dispersa',
		41 => 'Nieve densa',
		42 => 'Nieve y lluvia dispersas',
		43 => 'Nieve densa',
		44 => 'Parcialmente nublado',
		45 => 'Tormentas el&eacute;ctricas',
		46 => 'Nieve',
		47 => 'Tormentas el&eacute;ctricas aisladas',
		3200 => 'No disponible',
	);

Aquí se encuentra una porción del código fuente original (v0.3.8) que sufrirá modificaciones:

		$day_forecast = $xml->dayf;

		$htmlstring = '';
		$htmlstring .= '<div class="weather_info">';
		$htmlstring .= '<p><a href="http://www.weather.com/weather/local/' . $xml->loc[id] .'" title="';
		$htmlstring .= __('Forecast for ', 'wp-weather').$day_forecast->day[t] . ', ' . $day_forecast->day[dt].'">';
		$htmlstring .= $day_forecast->day[t] . ", " . $day_forecast->day[dt];
		$htmlstring .= '</a>';
		$htmlstring .= '<br />'.$xml->cc->t.'<br/>';
		$htmlstring .= __('Currently: ', 'wp-weather').'<strong>';
		$htmlstring .= $xml->cc->tmp.'˚'.$xml->head->ut.'</strong><br/>';
		$htmlstring .= __('Feels Like: ', 'wp-weather').$xml->cc->flik.'˚ '.$xml->head->ut.'<br/>';
		$htmlstring .= '<strong>'.__('Hi: ', 'wp-weather') . $day_forecast->day[0]->hi . '˚, ';
		$htmlstring .= __('Lo: ', 'wp-weather') . $day_forecast->day[0]->low . '˚</strong><br/>';

		if ( (bool) $this->settings['show_wind']) {
			$htmlstring .= __('Wind: ', 'wp-weather'). $xml->cc->wind->s.', '.__('Gust: ', 'wp-weather');
			$htmlstring .= $xml->cc->wind->gust.' MPH <br/>';
			$htmlstring .= __('Wind Direction: ', 'wp-weather').$xml->cc->wind->t;
			$htmlstring .= ' ('.$xml->cc->wind->d.') <br/>';
		}

		$htmlstring .= '<img border="0" src="'. get_bloginfo(wpurl).'/wp-content/plugins/wp-weather/images/'.$image_dimensions.'/'.$xml->cc->icon.'.png" alt="'.$xml->cc->t.'" /></p>';

		if ((bool)$this->settings['show_tonight']) {
			$htmlstring .= '<p>'.__('Tonight: ', 'wp-weather').$day_forecast->day[0]->low.'˚<br/>';
			$htmlstring .= __('Sunset: ', 'wp-weather'). $day_forecast->day[0]->suns.'<br/>';
			$htmlstring .= __('Moon Phase: ', 'wp-weather'). $xml->cc->moon->t.'<br/>';
			$htmlstring .= '<img border="0" src="'. get_bloginfo(wpurl).'/wp-content/plugins/wp-weather/images/'.$image_dimensions.'/'.$day_forecast->day[0]->part[1]->icon.'.png" alt="'.$day_forecast->day[0]->part[1]->t.'" /><br/>';
			$htmlstring .= '</p>';
		}

		if (sizeof($day_forecast->day) > 1) {
			foreach($day_forecast->day as $day)	{
				if ($day[d] == "0")
					continue;
				$htmlstring .= '<p>';
				$htmlstring .= '<i>'.$day[t] . ', ' . $day[dt].'</i><br/>';
				$htmlstring .= '<strong>'.__('Hi: ', 'wp-weather') . $day->hi . '˚, ';
				$htmlstring .= __('Lo: ', 'wp-weather') . $day->low . '˚</strong><br/>';
				if ( (bool) $this->settings['show_wind']) {
					$htmlstring .= __('Wind: ', 'wp-weather'). $day->part[0]->wind->s.', '.__('Gust: ', 'wp-weather');
					$htmlstring .= $day->part[0]->wind->gust.' MPH <br/>';
					$htmlstring .= __('Wind Direction: ', 'wp-weather').$day->part[0]->wind->t;
					$htmlstring .= ' ('.$day->part[0]->wind->d.') <br/>';
				}
				$htmlstring .= '<img border="0" src="'. get_bloginfo(wpurl).'/wp-content/plugins/wp-weather/images/'.$image_dimensions.'/'.$day->part[0]->icon.'.png" alt="'.$day->part[0]->t.'" />';
				$htmlstring .= '</p>';
			}
		}

		$htmlstring .= '<p class="weather_info">'.__('weather feed courtesy of ', 'wp-weather').'<a href="http://www.weather.com/?prod=xoap&amp;par=' . $this->settings['partner_id'] . '" title="weather.com">weather.com</a> - '.__('thanks', 'wp-weather').'!</p>';
		$htmlstring .= '</div>';
		return $htmlstring;

El cambio consiste específicamente en sustituir las lineas de código con acceso directo de la estructura XML:

$htmlstring .= __('Forecast for ', 'wp-weather').$day_forecast->day[t] . ', ' . $day_forecast->day[dt].'">';

por la siguiente linea:

$htmlstring .= __('Forecast for ', 'wp-weather'). date_i18n('l, j F', strtotime($day_forecast->lsup)) .'">';

En donde la función date_i18n, desempeña su protagonismo recuperando la fecha en formato localizado, en base al TimeStamp, es decir, convierte “Thursday, May 6” a “Jueves, 6 Mayo”.

Y lo más importante el estado del clima:

$htmlstring .= '<br />'.$xml->cc->t.'<br/>';

Lo cambiamos por:

$htmlstring .= '<br />'.$mensajes[(int)$xml->cc->icon].'<br/>';

Se realiza un Cast al valor “icon”, para que se comporte como indice del vector $mensajes.

Código fuente final modificado:

$day_forecast = $xml->dayf;

		$htmlstring = '';

		$htmlstring .= '<div class="weather_info">';
		$htmlstring .= '<p><a href="http://www.weather.com/weather/local/' . $xml->loc[id] .'" title="';
		$htmlstring .= __('Forecast for ', 'wp-weather'). date_i18n('l, j F', strtotime($day_forecast->lsup)) .'">';
		$htmlstring .= date_i18n('l, j F', strtotime($day_forecast->lsup));
		$htmlstring .= '</a>';
		$htmlstring .= '<br />'.$mensajes[(int)$xml->cc->icon].'<br/>';
		$htmlstring .= __('Currently: ', 'wp-weather').'<strong>';
		$htmlstring .= $xml->cc->tmp.'˚'.$xml->head->ut.'</strong><br/>';
		$htmlstring .= __('Feels Like: ', 'wp-weather').$xml->cc->flik.'˚ '.$xml->head->ut.'<br/>';
		$htmlstring .= '<strong>'.__('Hi: ', 'wp-weather') . $day_forecast->day[0]->hi . '˚, ';
		$htmlstring .= __('Lo: ', 'wp-weather') . $day_forecast->day[0]->low . '˚</strong><br/>';
		if ( (bool) $this->settings['show_wind']) {
			$htmlstring .= __('Wind: ', 'wp-weather'). $xml->cc->wind->s.', '.__('Gust: ', 'wp-weather');
			$htmlstring .= $xml->cc->wind->gust.' MPH <br/>';
			$htmlstring .= __('Wind Direction: ', 'wp-weather').$xml->cc->wind->t;
			$htmlstring .= ' ('.$xml->cc->wind->d.') <br/>';
		}

		$htmlstring .= '<img border="0" src="'. get_bloginfo(wpurl).'/wp-content/plugins/wp-weather/images/'.$image_dimensions.'/'.$xml->cc->icon.'.png" alt="'.$xml->cc->t.'" /></p>';

		if ((bool)$this->settings['show_tonight']) {
			$htmlstring .= '<p>'.__('Tonight: ', 'wp-weather').$day_forecast->day[0]->low.'˚<br/>';
			$htmlstring .= __('Sunset: ', 'wp-weather'). $day_forecast->day[0]->suns.'<br/>';
			$htmlstring .= __('Moon Phase: ', 'wp-weather'). $xml->cc->moon->t.'<br/>';
			$htmlstring .= '<img border="0" src="'. get_bloginfo(wpurl).'/wp-content/plugins/wp-weather/images/'.$image_dimensions.'/'.$day_forecast->day[0]->part[1]->icon.'.png" alt="'.$day_forecast->day[0]->part[1]->t.'" /><br/>';
			$htmlstring .= '</p>';
		}

		if (sizeof($day_forecast->day) > 1) {
			foreach($day_forecast->day as $day)	{
				if ($day[d] == "0")
					continue;
				$htmlstring .= '<p>';
				$htmlstring .= '<i>'. date_i18n('l', strtotime($day[t])) . ', ' . date_i18n('j F', strtotime($day[dt])) . '</i><br/>';
				$htmlstring .= '<strong>'.__('Hi: ', 'wp-weather') . $day->hi . '˚, ';
				$htmlstring .= __('Lo: ', 'wp-weather') . $day->low . '˚</strong><br/>';

				if ( (bool) $this->settings['show_wind']) {
					$htmlstring .= __('Wind: ', 'wp-weather'). $day->part[0]->wind->s.', '.__('Gust: ', 'wp-weather');
					$htmlstring .= $day->part[0]->wind->gust.' MPH <br/>';
					$htmlstring .= __('Wind Direction: ', 'wp-weather').$day->part[0]->wind->t;
					$htmlstring .= ' ('.$day->part[0]->wind->d.') <br/>';
				}
				$htmlstring .= '<img border="0" src="'. get_bloginfo(wpurl).'/wp-content/plugins/wp-weather/images/'.$image_dimensions.'/'.$day->part[0]->icon.'.png" alt="'.$day->part[0]->t.'" />';
				$htmlstring .= '</p>';
			}
		}

		$htmlstring .= '<p class="weather_info">'.__('weather feed courtesy of ', 'wp-weather').'<a href="http://www.weather.com/?prod=xoap&amp;par=' . $this->settings['partner_id'] . '" title="weather.com">weather.com</a> - '.__('thanks', 'wp-weather').'!</p>';
		$htmlstring .= '</div>';
		return $htmlstring;

Screenshot:

Posted in: PHP, Wordpress