Using the tomorrow.io API to Fetch Weather Data on a WordPress Website

tomorrow.io is a great real-time weather API you can use to fetch weather information and display it on your website or application. Here’s how I am using the API to display my local weather information on my WordPress website.

Firstly, I decided I didn’t want to have to hit the API every time a user visits my page. Since I am only display today’s average condition, high and low temperatures, and sunrise and sunset data—all data which isn’t going to change from minute to minute—there is no need to hit the API on every page load. And, if you have a website with a large amount of traffic, hitting the API that frequently might make you go over your Quota.

Instead, I’m just hitting the API hourly, at most, and saving the data to my database. My PHP then draws that data from my database directly. Hourly is still overkill in my use case, but still well within limits.

First I set up an ACF (Advanced Custom Fields) options page for my weather data, and included fields for the following:

  1. Last Weather Fetch Date
  2. Last Weather Fetch Hour
  3. Weather JSON
  4. Weather Fetch Error
  5. Weather Coordinates
Weather Options Page

All of these fields will be automatically populated by my PHP weather fetching function except for the weather coordinates—which is the latitude and longitude of the location I want to get my weather data for. You can easily get these via Google Maps by right-clicking any location on the map and copying the coordinates.

Next, I wrote the function to fetch the weather:

/**
 * Function - Fetch Weather
 */
function fetch_weather($current_date, $current_hour)
{

	$weather_coordinates = get_field('weather_coordinates', 'option');
	// API endpoint URL
	if ($weather_coordinates) {
		$api_url = 'https://api.tomorrow.io/v4/weather/forecast?location=' . $weather_coordinates . '&apikey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
	} else {
		$api_url = 'https://api.tomorrow.io/v4/weather/forecast?location=34.67718086406146, -118.45199326849152&apikey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
	}

	// Make the API request
	$response = wp_remote_get($api_url);

	// Check if the request was successful
	if (is_wp_error($response)) {
		// Handle the error
		// echo 'Error: ' . $response->get_error_message();
		$weather_fetch_error_field = get_field('weather_fetch_error', 'option');

		if ($weather_fetch_error_field) {
			delete_field('weather_fetch_error', 'option');
		}

		update_field('weather_fetch_error', $response->get_error_messages(), 'option');
	} else {
		// The request was successful, and $response contains the API response
		$body = wp_remote_retrieve_body($response);

		// Now you can work with the API response, for example, decode JSON
		$data = json_decode($body, true);

		// Save the data to the "Weather JSON" option field
		update_field('weather_json', $body, 'option');
		update_field('last_weather_fetch_date', $current_date, 'option');
		update_field('last_weather_fetch_hour', $current_hour, 'option');
	}
}

There is another function that will call fetch_weather() only if it’s needed (if the weather has not been updated within the last hour) and return the weather as JSON. If the weather is current, then it just gets the weather that is already saved in my database.

function get_weather_json()
{
    date_default_timezone_set('America/Los_Angeles');
    $current_date = date('Ymd');
    $current_hour = date('G');
    $last_weather_fetch_date = get_field('last_weather_fetch_date', 'option');
    $last_weather_fetch_hour = get_field('last_weather_fetch_hour', 'option');

    // Fetch new data, if necessary
    if (!$last_weather_fetch_date || $last_weather_fetch_date != $current_date || !$last_weather_fetch_hour || $current_hour > $last_weather_fetch_hour) {
        fetch_weather($current_date, $current_hour);
    }

    // Display
    $weather_json = get_field('weather_json', 'option');

    return $weather_json;
}

Next, I created a function to display the weather data that gets saved to my database.

/**
 * Function - Display Weather Card
 */
function display_weather_card($weather_json)
{
    $data = json_decode($weather_json, true);

    $minute_index = 0;
    $day_index = 0;

    $current_temperature_fahrenheight = number_format(($data['timelines']['minutely'][$minute_index]['values']['temperature'] * 9 / 5) + 32, 0);

    $today_high_temperature_fahrenheight = number_format(($data['timelines']['daily'][$day_index]['values']['temperatureMax'] * 9 / 5) + 32, 0);

    $today_low_temperature_fahrenheight = number_format(($data['timelines']['daily'][$day_index]['values']['temperatureMin'] * 9 / 5) + 32, 0);

    $today_rain_accumulation_sum = $data['timelines']['daily'][$day_index]['values']['rainAccumulationSum'];

    $today_cloud_cover_avg = $data['timelines']['daily'][$day_index]['values']['cloudCoverAvg'];

    $today_snow_accumulation_avg = $data['timelines']['daily'][$day_index]['values']['snowAccumulationAvg'];

    // Rain
    $will_rain = false;
    if ($today_rain_accumulation_sum >= 1) {
        $will_rain = true;
    }

    $will_snow = false;
    if ($today_snow_accumulation_avg >= 1) {
        $will_snow = true;
    }

    // Cloudy
    $cloudy = false;
    if ($today_cloud_cover_avg >= 33) {
        $cloudy = true;
    }

    $condition = 'Sunny';
    $weather_icon = '<i class="fa-light fa-sun"></i>';

    if ($cloudy) {
        $condition = 'Cloudy';
        $weather_icon = '<i class="fa-light fa-clouds"></i>';
    }
    if ($will_rain) {
        $condition = 'Rainy';
        $weather_icon = '<i class="fa-light fa-cloud-rain"></i>';
    }
    if ($will_snow) {
        $condition = 'Snowy';
        $weather_icon = '<i class="fa-light fa-cloud-snow"></i>';
    }

    // Sunsrise & Sunset times
    $today_sunrise_time = $data['timelines']['daily'][$day_index]['values']['sunriseTime'];
    $today_sunset_time = $data['timelines']['daily'][$day_index]['values']['sunsetTime'];

    // Create a DateTime object from the string
    $today_sunrise_time = new DateTime($today_sunrise_time);
    $today_sunset_time = new DateTime($today_sunset_time);

    // Set the timezone to Los Angeles
    $losAngelesTimezone = new DateTimeZone('America/Los_Angeles');
    $today_sunrise_time->setTimezone($losAngelesTimezone);
    $today_sunset_time->setTimezone($losAngelesTimezone);

    // Format the time in 12-hour format
    $today_sunrise_time = $today_sunrise_time->format('g:i A');
    $today_sunset_time = $today_sunset_time->format('g:i A');

    ?>
    <div class="cards addfade">
        <div class="card decoration-1">
            <div class="columns">
                <div class="column weather-icon">
                    <p>
                        <?php echo $weather_icon; ?>
                    </p>
                </div>
                <div class="column current-temperature">
                    <p>
                        <?php echo $current_temperature_fahrenheight . '°F'; ?>
                    </p>
                </div>
                <div class="column high-low-temps">
                    <p>
                        <span><i class="fa-solid fa-temperature-full"></i><i class="fa-solid fa-arrow-up"></i></span>
                        <span>
                            <?php echo $today_high_temperature_fahrenheight . '°F'; ?>
                        </span>
                    </p>
                    <p>
                        <span><i class="fa-solid fa-temperature-quarter"></i><i class="fa-solid fa-arrow-down"></i></span>
                        <span>
                            <?php echo $today_low_temperature_fahrenheight . '°F'; ?>
                        </span>
                    </p>
                </div>
                <div class="column sunrise-sunset-times">
                    <p>
                        <span><i class="fa-solid fa-sunrise"></i></span>
                        <span>
                            <?php echo $today_sunrise_time; ?>
                        </span>
                    </p>
                    <p>
                        <span><i class="fa-solid fa-sunset"></i></span>
                        <span>
                            <?php echo $today_sunset_time; ?>
                        </span>
                    </p>
                </div>
            </div>
        </div>
    </div>
    <?php
}

It also uses FontAwesome icons to display the general condition of the day, depending on the weather.

Lastly, my custom weather WordPress block calls the appropriate functions and displays the weather.

display_weather_card(get_weather_json());

And there you have it!