Статьи

Создать плагин погодных условий с помощью Yahoo и SimpleXML

В этом руководстве вы узнаете, как создать простой плагин, который использует встроенную в PHP библиотеку SimpleXML для доступа к Yahoo! Метеослужба . Текущие погодные условия будут отображаться с помощью шорткода или шаблона тега.


Yahoo! предоставляет бесплатный канал погоды RSS / XML, который возвращает данные о текущих условиях (и прогнозе) для заданного местоположения. Вот URL фида для Лондона, ГБ:

Yahoo! Погода

Вы увидите что-то вроде этого:

Посмотрите на источник этой страницы, и вы найдете золотую жилу данных о погоде в формате XML. Мы можем анализировать эти данные с помощью библиотеки PHP SimpleXML, извлекать то, что нам нужно, и отображать их в наших постах, страницах и файлах шаблонов WordPress.

Yahoo! использует WOEID для уникальной идентификации географических объектов, таких как города, а также конкретных достопримечательностей, таких как Диснейленд и Эйфелева башня. Опрос Yahoo! Метеорологическая служба, использующая WOEID, является чрезвычайно точной, поскольку каждое местоположение имеет уникальный WOEID. Например, в мире есть 36 мест под названием Париж, но у каждого есть уникальный WOEID.

Вы можете использовать эту службу поиска WOEID, чтобы найти точное соответствие местоположения.

В приведенном выше URL используются два параметра: w для WOEID и u для температурной шкалы (по Цельсию или по Фаренгейту). Мы будем использовать оба из них в нашем плагине.


Папка плагинов WordPress находится в папке установки WordPress по адресу wp-content/plugins . Создайте папку внутри папки плагинов. Давайте назовем это get-current-weather . Теперь создайте сам файл плагина. Давайте назовем его get_current_weather.php Теперь путь к файлу вашего плагина должен быть следующим: wp-content/plugins/get-current-weather/get_current_weather.php

Каждый плагин WordPress нуждается в некоторой информации заголовка, чтобы WordPress мог идентифицировать ее и сделать ее доступной на странице плагина панели инструментов. Поместите этот код вверху файла плагина и сохраните его.

01
02
03
04
05
06
07
08
09
10
<?php
/*
Plugin Name: Get Current Weather
Plugin URI: http://woeid.rosselliot.co.nz
Description: Gets current weather data (temperature, weather icon, conditions) from Yahoo weather API.
Version: 1.0
License: GPLv2
Author: Ross Elliot
Author URI: http://woeid.rosselliot.co.nz
*/

Вы можете редактировать эту информацию в соответствии с вашими требованиями .

Теперь перейдите на панель инструментов WordPress и выберите меню плагинов. Вы увидите плагин в списке так:

Пока не активируйте его.


Шорткоды WordPress позволяют размещать вывод плагинов в ваших сообщениях и страницах. Теги шаблонов позволяют размещать выходные данные плагина в ваших файлах шаблонов (заголовок, нижний колонтитул, боковая панель и т. Д.) Нам нужно определить две функции в нашем плагине, одну для шорткода и одну для тега шаблона. Оба вернут одинаковые данные о погоде.

Тег шаблона будет использоваться следующим образом: get_current_weather_template_tag(woeid, tempscale) , где woeid — это WOEID для местоположения, а tempscale — требуемая шкала температуры, Цельсий или Фаренгейт. Таким образом, чтобы получить данные о погоде для Лондона, ГБ в градусах Цельсия, мы должны использовать шаблонный тег get_current_weather_template_tag('44418', 'c') .

Поместите следующий код в ваш файл плагина:

1
2
3
4
5
function get_current_weather_template_tag($woeid = », $tempscale = ‘c’){
 
  echo get_current_weather_display($woeid, $tempscale);
 
}

Эта функция принимает WOEID и временную шкалу. Вы заметите, что у tempscale есть параметр по умолчанию c, на случай, если он не определен и для удобства. Функция повторяет вызов другой функции get_current_weather_display которая предоставит нам отформатированные данные о погоде.

Шорткод вернет те же отформатированные данные о погоде, что и тег шаблона, с небольшой дополнительной работой. Шорткод WordPress будет использоваться в таких сообщениях и на таких страницах: [get_current weather woeid = '' tempscale = ''] . Итак, чтобы получить данные о погоде для Лондона, ГБ в градусах Цельсия, мы использовали бы [get_current_weather woeid = '44418' tempscale = 'c') . Поскольку мы используем шорткод, нам нужно сообщить об этом WordPress. Для этого мы используем функцию WordPress add_shortcode .

Поместите следующий код в ваш файл плагина:

1
add_shortcode(‘get_current_weather’, ‘get_current_weather_shortcode’);

Первый параметр get_current_weather определяет имя шорткода, который мы будем использовать в наших постах и ​​страницах. Второй параметр get_current_weather_shortcode — это имя функции, которая вызывается шорткодом.

Вот функция, вызываемая get_current_weather . Поместите следующий код в ваш файл плагина:

1
2
3
4
5
6
7
8
9
function get_current_weather_shortcode($atts){
 
  $args = shortcode_atts(array(‘woeid’ => », ‘tempscale’ => ‘c’), $atts );
      
  $args[‘tempscale’] = ($args[‘tempscale’]==’c’) ?
   
  return get_current_weather_display($args[‘woeid’], $args[‘tempscale’]);
 
}

Наша функция get_current_weather_shortcode принимает атрибуты get_current_weather_shortcode содержащиеся в массиве $atts . Эти атрибуты должны быть нашим WOEID и временным масштабом. Но что, если они не? API шорткода предоставляет нам способ предоставить значения по умолчанию для этих ожидаемых атрибутов, функцию shortcode_atts .

Shortcode_atts принимает два аргумента. Первый — это массив пар имя => значение. Имя — это ожидаемый атрибут шорткода, а значение — его значение по умолчанию. Если имя отсутствует в $ atts, оно создается со значением по умолчанию. Это позволяет нам убедиться, что наша функция имеет правильные атрибуты со значениями по умолчанию.

Но что, если вместо c или f было передано другое значение для временной шкалы? Вот где в игру вступает следующее утверждение.

1
$args[‘tempscale’] = ($args[‘tempscale’] == ‘c’) ?

Это утверждение является нашей гарантией того, что c или f используется для временной шкалы. Он использует троичный оператор PHP и функционально эквивалентен:

1
2
3
4
5
6
7
8
9
if($args[‘tempscale’] == ‘c’){
 
  $args[‘tempscale’] = ‘c’;
 
}else{
 
  $args[‘tempscale’] = ‘f’;
 
}

Вы можете использовать любой из них, но троичный оператор более элегантен для этой цели.

Наконец, аргументы передаются в функцию get_current_weather_display .


Вот функция get_current_weather_display которая вызывается как шорткодом, так и тегом шаблона.

Поместите следующий код в ваш файл плагина:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
function get_current_weather_display($woeid, $tempscale){
 
  $weather_panel = ‘<div class = «gcw_weather_panel»>’;
     
  if($weather = get_current_weather_data($woeid, $tempscale)){
   
    $weather_panel .= ‘<span>’ .
    $weather_panel .= ‘<span>’ .
    $weather_panel .= ‘<img src = «‘ . $weather[‘icon_url’] . ‘» />’;
    $weather_panel .= ‘<span>’ .
 
  }else{//no weather data
   
    $weather_panel .= ‘<span>No weather data!
     
  }
 
  $weather_panel .= ‘</div>’;
       
  return $weather_panel;
    
}

Эта функция действительно предназначена только для форматирования данных о погоде, возвращаемых из get_current_weather_data (шаг 4). Если данные о погоде не возвращаются, «Нет данных о погоде!» сообщение возвращается.


Вот функция get_current_weather_data которая get_current_ weather_display функцией get_current_ weather_display на шаге 3

Поместите следующий код в ваш файл плагина:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function get_current_weather_data($woeid, $tempscale){
 
  $query_url = ‘http://weather.yahooapis.com/forecastrss?w=’ .
   
  if($xml = simplexml_load_file($query_url)){
       
    $error = strpos(strtolower($xml->channel->description), ‘error’);//server response but no weather data for woeid
     
  }else{
     
    $error = TRUE;//no response from weather server
     
  }
   
  if(!$error){
   
    $weather[‘city’] = $xml->channel->children(‘yweather’, TRUE)->location->attributes()->city;
    $weather[‘temp’] = $xml->channel->item->children(‘yweather’, TRUE)->condition->attributes()->temp;
    $weather[‘conditions’] = $xml->channel->item->children(‘yweather’, TRUE)->condition->attributes()->text;
   
    $description = $xml->channel->item->description;
     
    $imgpattern = ‘/src=»(.*?)»/i’;
    preg_match($imgpattern, $description, $matches);
 
    $weather[‘icon_url’]= $matches[1];
     
    return $weather;
     
  }
   
  return 0;
 
}

Функция get_current_weather_data использует SimpleXML для запроса Yahoo! метеослужба с использованием заданного WOEID и шкалы времени. Если есть ошибка, мы возвращаем 0.

SimpleXML позволяет нам получать доступ к элементам xml объектно-ориентированным способом. Первое, что нам нужно сделать, это проверить, есть ли в нашем ответе ошибка.

1
2
3
4
5
6
7
8
9
if($xml = simplexml_load_file($query_url)){
     
  $error = strpos(strtolower($xml->channel->description), ‘error’);//server response but no weather data for woeid
   
}else{
   
  $error = TRUE;//no response from weather server
   
}

Этот блок if-else пытается загрузить ответ из $ query_url в $ xml, используя метод simplexml_load_file .

Если мы получим ответ, мы проверяем поле channel->description возвращаемого xml на строку «error». Например, попробуйте следующий URL, который вернет ошибку. Просмотрите источник, чтобы увидеть поле channel->description которое содержит строку «error».

Yahoo! Погода — Страница ошибок

Если мы не получим ответ (иначе), это означает, что должна быть проблема с достижением Yahoo! служба и $error установлены в TRUE. Это учитывает обе возможные ошибки: неверные данные или плохое соединение.

Если ошибок не найдено, мы можем извлечь соответствующие данные о погоде из XML.

Сначала давайте вернемся к тому, как выглядят хорошие данные ответов:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version=»1.0″ encoding=»UTF-8″ standalone=»yes» ?>
<rss version=»2.0″ xmlns:yweather=»http://xml.weather.yahoo.com/ns/rss/1.0″ xmlns:geo=»http://www.w3.org/2003/01/geo/wgs84_pos#»>
  <channel>
    <title>Yahoo!
    <yweather:location city=»London» region=»» country=»United Kingdom»/>
    <yweather:units temperature=»C» distance=»km» pressure=»mb» speed=»km/h»/>
    <yweather:wind chill=»15″ direction=»210″ speed=»9.66″ />
    <yweather:atmosphere humidity=»88″ visibility=»9.99″ pressure=»1015.92″ rising=»0″ />
    <yweather:astronomy sunrise=»5:48 am» sunset=»8:23 pm»/>
    <item>
      <title>Conditions for London, GB at 3:49 am BST</title>
      <geo:lat>51.51</geo:lat>
      <geo:long>-0.13</geo:long>
      <link>http://us.rd.yahoo.com/dailynews/rss/weather/London__GB/*http://weather.yahoo.com/forecast/UKXX0085_c.html</link>
      <pubDate>Tue, 16 Aug 2011 3:49 am BST</pubDate>
      <yweather:condition text=»Fair» code=»33″ temp=»15″ date=»Tue, 16 Aug 2011 3:49 am BST» />
       
      <description>
        <![CDATA[
        <img src=»http://l.yimg.com/a/i/us/we/52/33.gif»/><br />
        <b>Current Conditions:</b><br />
        Fair, 15 C<BR />
        <BR /><b>Forecast:</b><BR />
        Tue — Partly Cloudy.
        Wed — Partly Cloudy.
        <br />
        <a href=»http://us.rd.yahoo.com/dailynews/rss/weather/London__GB/*http://weather.yahoo.com/forecast/UKXX0085_c.html»>Full Forecast at Yahoo!
        (provided by <a href=»http://www.weather.com» >The Weather Channel</a>)<br/>
        ]]>
      </description>
    </item>
  </channel>
</rss>

Давайте channel->yweather:location->city значение города (Лондон), которое хранится в channel->yweather:location->city .

Обратите внимание, что заголовок RSS для ответа xml определяет два пространства имен: yweather и geo . Чтобы получить атрибут city, нам нужно получить доступ к пространству имен yweather как к дочернему yweather channel . ИСТИННЫЙ аргумент для детей сообщает SimpleXML, что yweather является префиксом элемента, как в yweather:location .

1
$weather[‘city’] = $xml->channel->children(‘yweather’, TRUE)->location->attributes()->city;

Используя ту же технику, мы можем получить значения для текущей температуры и условий (текст):

1
2
$weather[‘temp’] = $xml->channel->item->children(‘yweather’, TRUE)->condition->attributes()->temp;
$weather[‘conditions’] = $xml->channel->item->children(‘yweather’, TRUE)->condition->attributes()->text;

Элемент channel->item->description содержит HTML- channel->item->description заключенный в теги CDATA . Мы не можем получить доступ к тегам и атрибутам HTML напрямую, используя SimpleXML, поэтому сначала мы получаем данные описания:

1
$description = $xml->channel->item->description;

Затем мы используем preg_match и регулярное выражение для извлечения всего между src=" и " из тега img.

1
2
3
4
$imgpattern = ‘/src=»(.*?)»/i’;
preg_match($imgpattern, $description, $matches);
 
$weather[‘icon_url’]= $matches[1];

У нас есть все данные о погоде, к которым мы пришли, поэтому мы можем вернуть их в функцию get_current_weather_display для форматирования согласно шагу 3.


Активируйте плагин в вашей панели управления WordPress. Создайте новый пост или страницу и вставьте [get_current_weather woeid = '44418' tempscale = 'c'] в область содержимого. Просмотрите сообщение или страницу, и вы должны увидеть погодные условия для Лондона.

Теперь мы проверим тег шаблона. Откройте файл footer.php в папке темы вашего сайта. Добавьте тег шаблона get_current_weather_template_tag('44418', 'c') сразу после <div id="footer"> . Обновите свою страницу, и вы увидите погодные условия для Лондона в нижнем колонтитуле.


Давайте добавим немного CSS в файл style.css в папке вашей темы.

01
02
03
04
05
06
07
08
09
10
11
.gcw_weather_panel {
  background-color: #B1E7FB;
  border: 1px solid #4BCBFA;
  padding: 10px;
  width: 180px;
}
.gcw_weather_panel * {
  margin: 0 auto;
  text-align: center;
  display: block;
}

Ваш прогноз погоды должен выглядеть следующим образом:

Поскольку каждый шорткод или тег шаблона выводит дискретные данные, вы можете иметь столько разных выходных данных о погоде, сколько хотите, и все на одной странице.

Если вы посмотрите на XML, полученный от Yahoo !, вы заметите, что мы использовали очень мало доступных данных. Есть много других полей и атрибутов, включая данные прогноза. Одним из немедленных улучшений будет показ региона и страны отображаемого вами города. Вы также можете показать влажность, скорость ветра и многое другое.

Веселиться!