本文最后更新于133 天前,其中的信息可能已经过时,如有错误请发送邮件到3046699620@qq.com
一直以来都想删掉电脑端的侧边栏,但删掉之后文章目录显示等等都会受到影响,最终决定把它留下,并将站点概览这一区域做二次开发。对这一区域的利用,有许多畅想,比如日历、天气、音乐盒,这些再后续可能会不断的实现(不排除有鸽的可能),本文将介绍实现显示访问者ip所在地的天气。
本持着有现成的,绝不自己动手,搜寻一番,无果,遂自己动手。
首先,要确定的就是各个模块的布局,有了布局,实现时思路会很清晰。每个模块对应一个div,如下图。
整体由一个大的div,包含天气图标显示区域,城市显示区域,以及具体天气信息显示区域,html页面代码如下。
<div class='weather_block'>
<!-- 天气显示区域 显示天气图标-->
<div class='weather_show'> <img src="<?php echo $weatherIcon; ?>"alt="Weather Icon" title="<?php echo $weather; ?>"></div>
<!-- 显示城市 -->
<div class='city_show'><?php echo $city; ?></div>
<!-- 分割线 -->
<hr align='center' width='200px' color='#987cb9' size=1 margin-top='10px'>
<!-- 其余信息显示 -->
<!-- 气温 风向 风速 湿度 -->
<div class='weather_info'>
<div class='info_item'>
<div>气温</div>
<div><?php echo $temperature; ?>°C</div>
</div>
<div class='info_item'>
<div>风向</div>
<div><?php echo $winddirection; ?></div>
</div>
<div class='info_item'>
<div>风速</div>
<div><?php echo $windpower; ?> 级</div>
</div>
<div class='info_item'>
<div>湿度</div>
<div><?php echo $humidity; ?>%</div>
</div>
</div>
<!-- 更新时间显示 -->
</div>
大致布局确定,修改对应区块的css样式,如下。
.weather_block {
color: black;
width: 200px;
height: auto;
border-radius: 10px;
border: 2px solid transparent;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
}
.weather_show img {
max-width: 100%;
max-height: 100%;
height: auto;
width: auto;
}
.weather_show img:hover::after {
content: attr(title);
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-50%);
background: #333;
color: white;
padding: 5px;
border-radius: 3px;
white-space: nowrap;
font-size: 12px;
margin-top: 5px;
z-index: 10;
}
.weather_show {
margin: auto;
width: 100px;
height: 100px;
}
.city_show {
margin-top: 10px;
width: 100%;
text-align: center;
font-size: 1.0em;
}
.weather_info {
margin-top: 10px;
display: flex;
width: 100%;
color: black;
justify-content: space-around; /* Adjust spacing between items */
align-items: center; /* Center items vertically */
}
.weather_info .info_item {
text-align: center; /* Center text within each item */
display: flex;
flex-direction: column;
align-items: center;
margin: 1px 1px 5px 5px; /* Horizontal spacing between info items */
}
.weather_info .info_item div {
margin: 2px 0; /* Vertical spacing between text and data in each info item */
}
hr {
margin-right:15px;
margin-top: 10px;
border: 1px solid black;
}
获取天气信息,使用到的是高德地图开放api接口,具体使用方法可查看高德天气api开发文档。需要提供城市编码,以及Key,key如何获取,文档中都有提到,操作较简单。我首先是使用固定城市编码,来测试代码的可行性,确认可行之后,再自动获取访问者ip得到IP所在地的天气信息。
获取访问者ip,得到ip所在地,同样也是使用高德地图开放api,具体实现如下。
<?php
// 获取访问者 IP 地址
$ip_address = $_SERVER['REMOTE_ADDR'];
// 获取 IP 地址的城市编码
$ip_key = 'Your Key';
$ipUrl = "https://restapi.amap.com/v3/ip?key=$ip_key&ip=$ip_address";
$response = wp_remote_get($ipUrl);
if (is_wp_error($response)) {
$city = 420100; // 请求失败就显示默认
} else {
$ipdata = json_decode(wp_remote_retrieve_body($response), true);
$city = isset($ipdata['adcode']) ? $ipdata['adcode'] : 420100;
}
$city_str=(string)$city;
if (!preg_match('/^\d{6}$/', $city_str)) {
$city = '420100'; // Default to Wuhan if not valid
}
$weatherApiKey = 'Your Key';
$weatherUrl = "https://restapi.amap.com/v3/weather/weatherInfo?city=$city&key=$weatherApiKey";
$weatherResponse = file_get_contents($weatherUrl);
if ($weatherResponse === FALSE) {
$weatherInfo = "<p>无法获取天气数据。</p>";
} else {
$weatherData = json_decode($weatherResponse, true);
if (isset($weatherData['lives'][0])) {
$liveData = $weatherData['lives'][0];
$province = htmlspecialchars($liveData['province']);
$city = htmlspecialchars($liveData['city']);
$adcode = htmlspecialchars($liveData['adcode']);
$weather = htmlspecialchars($liveData['weather']);
$temperature = htmlspecialchars($liveData['temperature']);
$winddirection = htmlspecialchars($liveData['winddirection']);
$windpower = htmlspecialchars($liveData['windpower']);
$humidity = htmlspecialchars($liveData['humidity']);
$reporttime = htmlspecialchars($liveData['reporttime']);
$weatherInfo = "<p>省份: $province</p>
<p>城市: $city</p>
<p>区域编码: $adcode</p>
<p>天气现象: $weather</p>
<p>实时气温: $temperature°C</p>
<p>风向: $winddirection</p>
<p>风力: $windpower 级</p>
<p>湿度: $humidity%</p>
<p>报告时间: $reporttime</p>";
} else {
$weatherInfo = "<p>无法获取天气数据。</p>";
}
}
当然会出现无法找到访问者所在地的情况,这里默认显示武汉的天气。还需要根据天气,显示对应的天气图标,这里我是写了一个key-value结构将天气类型和天气图标地址做了一个捆绑(只展示部分)。
$weatherIcons = [
'晴' => 'https://lumoshh.oss-cn-hangzhou.aliyuncs.com/weather_img/%E6%99%B4%E5%A4%A9.png',
'少云' => 'https://lumoshh.oss-cn-hangzhou.aliyuncs.com/weather_img/%E6%9C%AA%E7%9F%A5.png',
'晴间多云' => 'https://lumoshh.oss-cn-hangzhou.aliyuncs.com/weather_img/%E6%9C%AA%E7%9F%A5.png',
'多云' => 'https://lumoshh.oss-cn-hangzhou.aliyuncs.com/weather_img/d2-%E5%A4%9A%E4%BA%91.png',
'阴' => 'https://lumoshh.oss-cn-hangzhou.aliyuncs.com/weather_img/%E9%98%B4%E5%A4%A9.png']
代码添加到function.php中,将整体模块封装,在需要显示的位置调用短代码,下面为整体实现代码(省略到了已经展示的部分)。
/*天气小模块*/
function weather_widget_shortcode() {
ob_start();
?>
<!-- Put your HTML and PHP code here -->
<?php
// 获取访问者 IP 地址
.....
}
<!-- 天气图标地址 -->
$weatherIcons = [];
$weatherIcon = isset($weatherIcons[$weather]) ? $weatherIcons[$weather] : 'https://lumoshh.oss-cn-hangzhou.aliyuncs.com/weather_img/%E6%9C%AA%E7%9F%A5.png';
?>
<style>
.....
</style>
<div class='weather_block'>
<!-- 天气显示区域 显示天气图标-->
......
</div>
<?php
return ob_get_clean();
}
add_shortcode('weather_widget', 'weather_widget_shortcode');
自己编写代码实现一个功能是一件很有意思的事情!虽然天气模块可能用处不大,但后续会再进一步开发其它功能!