weather, everywhere · drupal 8 is object oriented and drupal 7 is primarily procedural. this means...

28
Weather, Weather, Everywhere Adding a Weather Forecast to your pages By Bradley Roberts EM: [email protected] TW: @BE55Roberts

Upload: others

Post on 30-Sep-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Weather,

Weather,

EverywhereAdding a Weather Forecast to your pages

By Bradley Roberts

EM: [email protected]

TW: @BE55Roberts

Page 2: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Awesome Hiking Experience

www.awesomehikingexperience.com

Page 3: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

The ChallengeHow to encourage readers to go on trail hikes?

One Solution: Report the current weather forecast

Page 4: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Existing Modules for Weather

or Create My Own?

Drupal 8

Weather (only 7.x-2.14)

Weather Block (2014)

Wunderground (8.x-1.2)

Custom

Use GeoLocation

(lat,lng)

Support multiple places

Support trails

Page 5: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Basic Strategy: Add a Filter

Filter Content for Tag:

Page 6: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Drupal 8 is object oriented and Drupal 7 is

primarily procedural. This means that a lot of

your code will now be in classes rather than

simple functions. This is going to be

overwhelming for many, but will certainly

make module development more flexible and

you will upgrade your skills to modern

programming practice in the process.

By Blair Wadman at www.befused.com

Taking the Drupal 8 module approach will make your

custom module better in the long run.

Page 7: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

/modules/custom/hiking_weather

Directory Structure

/images

/src

/src/Controller

/src/Plugin

Under Hiking Weather:

Page 8: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

name: Hiking Weather

description: Shows the current weather on the hiking trail

package: Custom

type: module

core: 8.x

hiking_weather_info.yml

Page 9: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

/**

* FILE: HikingWeatherController.php

* GOAL: To support Awesome Hiking

* AUTHOR: Bradley Roberts

* EMAIL: [email protected]

* DATE: 8/28/2017

*/

namespace Drupal\hiking_weather\Controller;

// Add Controller Base

use Drupal\Core\Controller\ControllerBase;

/**

* Class Hiking Weather Controller

* To process weather requests for specific hiking

locations

* @package Drupal\HikingWeather\Controller

*/

class HikingWeatherController extends ControllerBase {

}

HikingWeatherController.php

Page 10: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

private $weatherTag = 'WEATHER';

private $weatherRegEx = '/\[(.*:\s)?(-?(?:\d+|\d*\.\d+))?,(-

?(?:\d+|\d*\.\d+))?\]/’;

HikingWeatherController.php

Use regex101.com to build your regular expression.

Properties:

Methods:

TIP:

public function content() {}

public function hiking_weather_node_view_alter() {}

public function parse_weather_tag() {}

public function getForecast() {}

Page 11: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

hiking_weather.content:

path: '/hikingweather'

defaults:

_controller: '\Drupal\hiking_weather\Controller\HikingWeatherController::content'

_title: 'Hiking Weather'

requirements:

_permission: 'access content'

hiking_weather.routing.yml

Page 12: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

hiking_weather.admin:

title: 'Hiking Weather Module Settings'

description: 'Settings for the Hiking Weather Module'

parent: system.admin_config_development

route_name: hiking_weather.content

weight: 100

hiking_weather.links.menu.yml

Page 13: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

hiking_weather.theme.css.hiking {

font-weight: bold;

}

.hiking_forecast {

background-color: #cdd9fe;

float: left;

padding-right: 5px;

margin-right: 10px;

}

Page 14: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

hiking_weather.libraries.yml

hiking-weather:

version: 1.x

css:

theme:

hiking_weather.theme.css: {}

Page 15: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Wunderground.com

Wunderground provides a Weather API

Free service for development and low usage

API Call

Page 16: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Weather Underground Map

Page 17: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Get Forecast API Call/**

* Get the Hiking Weather Forecast for a geolocation

*

* @param float $lat is the decimal latitude - e.g. 35.89

* @param float $lng is the decimal longitude - e.g. -83.94

*

* If not given, then defaults are used for home

*

* @return string rendering a DIV for the Forecast block

*/

public function getForecast($lat = 0.00, $lng = 0.00) {

$weather_api = 'http://api.wunderground.com/api’;

$api_key = APIKEY;

// Get the weather forecast from WonderGround.com

// EG: http://api.wunderground.com/api/APIKEY/geolookup/forecast/q/35.89583,-

83.9411.json

$json_string = file_get_contents($weather_api . '/' . $api_key .

'/geolookup/forecast/q/' . $lat . ',' . $lng . ".json");

$parsed_json = json_decode($json_string);

if ($parsed_json && (json_last_error() == JSON_ERROR_NONE)) {

$icon_url = (isset($parsed_json->forecast->simpleforecast->forecastday[0]-

>icon_url) ? $parsed_json->forecast->simpleforecast->forecastday[0]->icon_url :

$default_icon);

$conditions = (isset($parsed_json->forecast->simpleforecast->forecastday[0]-

>conditions) ? $parsed_json->forecast->simpleforecast->forecastday[0]->conditions :

$default_cond);

Page 18: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Get Forecast API Call// Map icon file to image on this system, since Drupal rejects Cross

Site Images

if (file_exists($images_dir . basename($icon_url))) {

$icon_img = $images_dir . basename($icon_url);

}

else {

$icon_img = $default_icon;

}

if (!$conditions || (strlen($conditions) == 0)) {

$conditions = $default_cond;

}

}

// Render DIV for the weather block with class hiking_forecast

return '<div><p class="hiking_forecast"><img src="' . $icon_img . '"

title="Weather Icon">' . $conditions . '</p><img src="' . $wuicon . '"

width="90px" title="Weather forecast courtesy of www.wunderground.com"></div>' .

PHP_EOL;

}

Page 19: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

modules/custom/hiking_weather/src/Plugin/Filter/FilterArticle.php

/**

* FILE: FilterArticle.php

* GOAL: To support Awesome Hiking by filtering articles

* AUTHOR: Bradley Roberts

* EMAIL: [email protected]

* DATE: 09/01/2017

*/

namespace Drupal\hiking_weather\Plugin\Filter;

use Drupal\filter\FilterProcessResult;

use Drupal\filter\Plugin\FilterBase;

use Drupal\Core\Form\FormStateInterface;

/**

* Class FilterArticle

* Looks for WEATHER tags to replace with a forecast object

*

* @package Drupal\hiking_weather\Plugin\Filter

*

* EG:

* @Filter(

* id = "filter_hiking_weather",

* title = @Translation("Hiking Weather Filter"),

* description = @Translation("Help potential hikers by providing forecast"),

* type = Drupal\filter\Plugin\FilterInterface::TYPE_MARKUP_LANGUAGE,

* )

*/

class FilterArticle extends FilterBase {

/**

* Process the Filter Request

* @param string $text

* @param string $langcode

* @return \Drupal\filter\FilterProcessResult

Page 20: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

modules/custom/hiking_weather/src/Plugin/Filter/FilterArticle.php

public function process($text, $langcode) {

// Instantiate the controller instance$weathering = new \Drupal\hiking_weather\Controller\HikingWeatherController();

// Identify the tag, latitude and longitude$geoTagged = $weathering->parse_weather_tag($text);

// Use API Call to retrieve the current forecast nearest this location$forecast = $weathering->getForecast($geoTagged['lat'], $geoTagged['lng']);

// Embed the rendered HTML into the markup$new_text = str_replace($geoTagged['tag'], $forecast, $text);

// Instantiate a filter process$result = new FilterProcessResult($new_text);

$result->setAttachments(array('library' => array('hiking_weather/hiking-weather'),

));

return $result;}

Page 21: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Rainbow Falls

Page 22: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Rainbow Falls Currently

<p>Current Weather on the Trail:</p>

<div>

<p class="hiking_forecast">

<img src="/modules/custom/hiking_weather/images/default_weather.gif" title="Weather Icon" />

Clear

</p>

<img src="/modules/custom/hiking_weather/images/wundergroundLogo_4c_horz.png" width="90px" title="Weather

forecast courtesy of www.wunderground.com" />

</div>

Page 23: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

CAVEATS

• Weather is always changing, so you want to provide updates

• Caching should be limited to 1 hour to ensure up-to-date data

• Copy the Weather Icons to your server to customize them

• Wunderground limits the free, basic API to 10 calls/min

Weather Icon Sets:

https://www.wunderground.com/weather/api/d/docs?d=resources/icon-sets

Page 24: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

CAVEATS

Page 25: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

DEMO

Page 26: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

QUESTIONS & ANSWERS

Page 27: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

In Conclusion

www.awesomehikingexperience.com

Select a hike

Check the weather forecast for today!

Go hiking – you’ll love it

For more info about the Great Smoky Mountains:

Page 28: Weather, Everywhere · Drupal 8 is object oriented and Drupal 7 is primarily procedural. This means that a lot of your code will now be in classes rather than simple functions. This

Learning More About Drupal 8www.drupal.org/docs/8/creating-custom-modules

Lots of great information on all aspects of creating a module.

www.befused.com/drupal/first-drupal8-module

Step by step instructions for creating a D8 module.

https://youtu.be/EPjJQ7j3GaM

Drupal Camp Atlanta 2016 module on building a site for

CancerQuest.org

https://www.wunderground.com

Weather Underground Web Service. See about/data for details

on their data sources.