【baserCMS】baserCMS+外部APIで簡単ウィジェット作成

![スクリーンショット 2021-12-14 13.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/91866643-b2a2-2826-0c1e-cd51bcc0afb7.png)
baserCMSってwebサイト用のCMSと思われがちなのですが、CMSとしての機能以外にカスタマイズ次第で色々なサイトが実現できます。
今回はプラグインの実装の流れを紹介しようと思います。

管理画面の既存の機能をカスタマイズしてDBにデータを保存、出力するようなプラグインの実装例については色々な記事がありますね。

今回はあまり見ない例として、「外部APIからデータを取得してテンプレートに出力する」プラグインの構築の流れを紹介します。

題材何にしようかなーと思いながらPCのウィジェット眺めてたら天気予報が目に入ったので、サイドバーに天気予報を出力するウィジェットをつくるプラグインで試してみます。

## 実装の流れを考える

以下の流れで実装します。

1. 天気予報を提供してくれるAPIを探す（できれば無料だと嬉しい）
2. APIの仕様を確認してbaserCMS実装可能か確認する
3. baserCMS最新版をセットアップする
4. プラグインフォルダに新しいプラグインを作成する
5. CMS管理画面からウィジェットを登録する

### 1.天気予報を提供してくれるAPIを探す（できれば無料で）

まずは無料で天気予報をAPIで提供してくれるサービスを探します。
海外のサービスですが、各地の天気予報を取得するのにOpenWeatherMapというサービスがちょうど良さそうでした。
APIのリクエスト数に応じて無料プラン、有料プランを提供しているようなので利用してみようと思います。

https://openweathermap.org/

![スクリーンショット 2021-12-14 13.59.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/bcdfddd2-954e-8906-1c53-729e8d7139a3.png)

OpenWeatherMapの使い方については検索すると色々なサイトで紹介されてるのでここでは省略します。

Apiページを見てみると色々な機能があるようなので気になります。

### 2.APIの仕様を確認してbaserCMS実装可能か確認する

API仕様書を確認して実装可能か確認します。
APIによってはcomposerでライブラリ追加が必要な場合があります。
baserCMS4系ではcomposerに対応しておらず手動でライブラリを集める必要があり、やや手間がかかってしまいます。
また同じbaserCMS4系であってもマイナーバージョンによってはPHP7の少し前のマイナーバージョンまでしか対応していないケースもありますので要注意です。


[APIの仕様](https://openweathermap.org/current)をぱらぱら確認したところOpenWeatherMapはAPIとパラメータをつけたURLに対してGETアクセスするだけでデータを返してくれるようなのでそこまで複雑な実装は不要なようです。

今回は、以下のエンドポイントを使って指定地域での現在の天気予報を取得するApiを使ってみたいと思います。

https://api.openweathermap.org/data/2.5/weather?q=Tokyo,JP&appid={APIキー}&lang=ja&units=metric


### 3.baserCMS最新版をセットアップする

ここまでで実装できそうなことが分かりましたのでbaserCMSを準備します。
最新版は公式サイトの「今すぐダウンロード」のボタンからダウンロードできます。

[baserCMS公式サイト](https://basercms.net/)
![スクリーンショット 2021-12-14 14.05.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/108225ae-8f03-9036-5ad6-b4a10d968a60.png)

ダウンロード後のbaserCMSのセットアップ方法についても検索すると色々なサイトで紹介されているので省略します。

### 4.プラグインフォルダに新しいプラグインを作成する

baserCMSのインストールが完了しましたら、baserCMS内にプラグイン用のフォルダを作成します。

``` フォルダ設置箇所.
/app/Plugin/{プラグイン名をキャメルケースで記載}/
```

今回は「OpenWeatherWidget」というフォルダ名でプラグインを作成します。

``` 以下のフォルダを作成.
/app/Plugin/OpenWeatherWidget/
```


続いて、プラグインの設定ファイルや、実際のコードを書くためのファイルを準備します。

こちらの記事を参考にウィジェットエリアを追加するプラグインのファイルを構成しました。
https://qiita.com/materializing/items/9cd10c39b8226b19715e

``` ディレクトリ構成.
/app/Plugin/OpenWeatherWidget/
	┣ Cofnig/
	┃	┗ setting.php 						// OpenWeatherMapから取得したappidを格納します。
	┣ View
	┃	┗ Elements/
	┃		┣ admin/
	┃		┃ 	┗ widgets/
	┃		┃ 		┗ open_weather.php 		// 管理画面のウィジェット一覧への表示に使用します。
	┃		┗ widgets/
	┃		 	┗ open_weather.php 			// 表示画面側で表示に使用します。
	┣ config.php 							// プラグイン名等の情報を管理します。
	┗ VERSION.txt 							// バージョン番号を管理します。
``` 

それぞれのファイルの内容を以下のように記述します。

#### プラグインの設定

``` /app/Plugin/OpenWeatherWidget/config.php
<?php
$title = 'OpenWeatherウィジェット';
$description = 'ウィジェットに天気予報を追加するプラグインです';
$author = 'ichi280';
$url = 'https://catchup.co.jp';
$installMessage = '';
``` 

#### プラグインのバージョン記述

``` /app/Plugin/OpenWeatherWidget/VERSION.txt
1.0.1
``` 

#### 設定値

``` /app/Plugin/OpenWeatherWidget/Config/setting.php
<?php
$config['OpenWeather'] = [
	'appid' => '{openWatherMap登録時に取得したAppID}',
];
``` 

#### ウィジェットを管理画面にて認識させる
``` /app/Plugin/OpenWeatherWidget/View/Elements/admin/widgets/open_weather.php
<?php
$title = '天気予報';
$description = '天気予報を表示します';
``` 

#### ウィジェットの実体

``` /app/Plugin/OpenWeatherWidget/View/Elements/widgets/open_weather.php
<div class="widget widget-blog-categories-archives widget-blog-categories-archives-<?php echo $id ?> blog-widget">
<?php
// /app/Plugin/OpenWeatherWidget/Cofnig/setting.phpに記載されたconfigの内容を取得します。
$appid = Configure::read('OpenWeather.appid');

// OpenWeatherMapのAPIをコールします。
// qパラメータに都市名を指定すると任意の都市の情報を取得します。
$response = file_get_contents('https://api.openweathermap.org/data/2.5/weather?q=Fukuoka,JP&appid=' . $appid . '&lang=ja&units=metric');
$data = json_decode($response);
?>
<table width="100%" class="OpenWeatherWidget">
<tr class="head">
	<th colspan="2"><?php echo h($data->name)?></th></tr>
<tr class="weather">
	<th colspan="2"><img src="//openweathermap.org/img/wn/<?php echo h($data->weather[0]->icon)?>@2x.png"><br><?php echo h($data->weather[0]->description)?></td>
</tr>
<tr class="row">
	<th>気温</th>
	<td><?php echo h($data->main->temp)?>℃</td>
</tr>
<tr class="row">
	<th>最高気温</th>
	<td><?php echo h($data->main->temp_max)?>℃</td>
</tr>
<tr class="row">
	<th>最低気温</th>
	<td><?php echo h($data->main->temp_min)?>℃</td>
</tr>
<tr class="row">
	<th>湿度</th>
	<td><?php echo h($data->main->humidity)?>%</td>
</tr>
<tr class="row">
	<th>風速</th>
	<td><?php echo h($data->wind->speed)?>m/s</td>
</tr>
</table>
</div>

<style>
.OpenWeatherWidget{
	width: 100%;
}

.OpenWeatherWidget tr.head th{
	background-color:#777;color:#FFF;text-align:center;font-weight:bold;
}

.OpenWeatherWidget tr.weather th{
	text-align:center;
}

.OpenWeatherWidget tr.row th,
.OpenWeatherWidget tr.row td{
	border-top:1px solid #DDD;
}

</style>
```

## 5.CMS管理画面からウィジェットを登録する

baserCMS管理画面からプラグインを有効化します。

正しくインストールが完了しましたら、ウィジェットの管理画面を開き、プラグインを有効化します。
![スクリーンショット 2021-12-14 14.55.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/af8069d4-d165-25a0-d141-49a5af436e6b.png)

続いてウィジェット管理画面を表示、先ほど作成したウィジェットが表示されていることが確認できます。
![スクリーンショット 2021-12-14 14.57.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/569cfa47-eb06-571e-9b84-732905163847.png)

利用するウィジェットに登録して保存（「利用する」にチェックしないとフロント画面で表示されません）
![スクリーンショット 2021-12-14 14.57.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/f50b18fe-2724-78bb-6946-fe101bd9e672.png)


フロント画面を開くとサイドバーに天気予報が表示されていることが確認できます。
![スクリーンショット 2021-12-14 15.00.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52815/465fee98-600c-2607-bccf-36f1649cac43.png)
曇りがち。

天気予報のアイコンと日本語テキストはOpenWeatherMapのAPIで取得できるのでサクッと導入できました。

うまくブラウザのロケーション情報やフォームを組み合わせると任意の場所の天気予報を取得、表示できそうです。

## 6.おわりに
baserCMSでのプラグイン作成時、どこにどのファイルを置いたらいいのかわからなくなることがあります。
標準プラグインのブログやメールフォーム等がどのようなファイル配置になっているかを参考にすると良いです。
/lib/Baser/Plugin/Mail/
/lib/Baser/Plugin/Blog/
＊今回は、ウィジェットファイルの配備の際にブログプラグインを参考にしました。


またbaserマーケットには無料のプラグインも多数ありますので、プログラムの参考としてダウンロードするのも良いかと思います。