なでしことGoogle Siteで、ちょっと便利なページをつくる

:::note warn
本ページの記載事項は、「初心者向け」です。初心者でない方は、[公式リファレンス](https://nadesi.com/v3/doc/index.php?%E5%91%BD%E4%BB%A4%E4%B8%80%E8%A6%A7%2F%E3%82%AB%E3%83%8A%E9%A0%86&show)でも見ておいてください。
:::
# はじめに

近年、[学校教育の中でも利用されている](https://nadesi.com/index.php?%E3%81%AA%E3%81%A7%E3%81%97%E3%81%93%E3%81%8C%E6%95%99%E7%A7%91%E6%9B%B8%E3%81%AB%E8%BC%89%E3%81%A3%E3%81%9F%E4%BB%B6)日本語プログラミング言語「なでしこ」。そのマニュアルを読んでいたら、Scriptタグを用いて、Webページに埋め込めるとの記述を見つけました。

https://nadesi.com/v3/doc/index.php?FAQ%2Fembed_html&show

そこで、なでしこと、Google Siteを使って、自分専用の「ちょっと便利なページ」を作ってみることにしました。

# テンプレート
以下の公式サイトを参考に、テンプレートを作成しました。

https://nadesi.com/v3/doc/index.php?FAQ%2Fembed_html&show

https://nadesi.com/v3/doc/index.php?plugin_browser%2FHTTP%E5%8F%96%E5%BE%97&show

```html: template.html
<html><body>

<!-- ↓が文字を表示するエリア -->
<div id="result" style="text-align: center;"></div>

<script type="なでしこ">

// ↓ここから、なでしこでプログラムを書く


// ↓で文字を表示するエリアに、テキストを設定する
「result」のDOM要素ID取得して、「ここに何か文字を書く」をDOMテキスト設定。

</script>
<script type="text/javascript"
 src="https://nadesi.com/v3/cdn.php?v=3.4.22&f=release/wnako3.js&run"
></script>
</body></html>

```

これをGoogle Siteに張り付けてみます。
Google Siteのページを開いて、上部のプラスボタンを押し、新規でページを作ったら、右側の「埋め込む」ボタンを押します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/6b8e7b8f-8ffb-51f2-d13e-570a0ea046d1.png)

開いたダイアログの「埋め込みコード」のところに、上記テンプレートをコピペし、「次へ」「挿入」の順にボタンを押すことで、Google Siteになでしこのコードを挿入できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/7caeabf5-1a45-5afb-dbac-c2e9a355e6b5.png)

下の画像のように、「ここに何か文字を書く」と表示されれば、上手く埋め込めています。実際になでしこを書いていく際には、テンプレート中の `↓ここから、なでしこでプログラムを書く` という行の下に書き連ねていくことになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/f1cc0646-1bb5-abf1-0b1c-68eb36d80365.png)

# 例1：日替わり英単語（なんちゃってバージョン）

日替わりで英単語を表示するプログラムを作ってみました。これをテンプレートの`<script type="なでしこ">`から`</script>`の間に貼り付けます。

```
《英単語一覧》は「
Important (重要な),Family (家族),School (学校),Friend (友達),Study (勉強する),
Teacher (先生),Holiday (休日),Music (音楽),Animal (動物),Book (本),
Computer (コンピューター),Exercise (運動),Health (健康),Nature (自然),Science (科学),
Food (食べ物),City (都市),Weather (天気),Color (色),Language (言語)
」を「,」で区切ったもの。

今日を「/」で区切る。
《日付》は、それ[2]。
《選んだ数字》は、《日付》を《英単語一覧》の配列要素数で、割った余り。

「result」のDOM要素ID取得して、「今日の英単語は『{《英単語一覧》[《選んだ数字》]}』です！1日1単語、覚えよう！」をDOMテキスト設定。
```

`～を「,」で区切`は、長い文字列をカンマで区切って、配列にしています。これで例えば`{《英単語一覧》[3]}`とすると、《英単語一覧》の4番目、つまり「Friend (友達)」を取得できます。
続けて記載のある`今日`は「2023/01/23」のように「/」で区切られた今日の日付を取得します。そこで、`今日を「/」で区切る。《日付》は、それ[2]。`という命令を使うことで、日付の「23」という部分だけを抜き出すことが出来るようになります。
最後に、`《英単語一覧》の配列要素数`では、20個の英単語を登録しているので、20が取得されます。よって、`《選んだ数字》`は「23」を「20」で割った余り「3」となるので、以下の画像のように、「Friend (友達)」が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/6084cec2-fcc1-b530-fac4-9a10e63510b4.png)

:::note info
他の多くのプログラミング言語と同じように、なでしこの配列は0番目から始まります。つまり、`{《英単語一覧》[n]}`は、n+1番目の英単語が取得されます。
:::

:::note alert
初学者の人で、最後の行を次のように書いてしまう人が、たまにいます。鍵括弧の中に、同じ種類の鍵括弧は使えないので、注意しましょう。
```
// ↓のコードはエラーになります。
「result」のDOM要素ID取得して、「今日の英単語は「{《英単語一覧》[《選んだ数字》]}」です！1日1単語、覚えよう！」をDOMテキスト設定。
```
:::

参考URL

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E9%85%8D%E5%88%97%E5%A4%89%E6%95%B0

https://nadesi.com/v3/doc/index.php?plugin_system%2F%E4%BB%8A%E6%97%A5&show

# 例2：日替わり英単語

例1の「なんちゃってバージョン」には、欠点がありました。それは、単語によって出てくる頻度が違うことです。つまり、20で割っているので2番目の「Family (家族)」は毎月1日と21日に表示されますが、20番目の「Language (言語)」は毎月19日にしか表示されないのです。
これは今日の日付だけをもとにして、日替わりしているからです。
そこで、次のようにプログラムを変えてみます。

```
《英単語一覧》は「
Important (重要な),Family (家族),School (学校),Friend (友達),Study (勉強する),
Teacher (先生),Holiday (休日),Music (音楽),Animal (動物),Book (本),
Computer (コンピューター),Exercise (運動),Health (健康),Nature (自然),Science (科学),
Food (食べ物),City (都市),Weather (天気),Color (色),Language (言語)
」を「,」で区切ったもの。

《経過日数》は、「2000/01/01」と今日の日数差。
《選んだ数字》は、《経過日数》を《英単語一覧》の配列要素数で、割った余り。

「result」のDOM要素ID取得して、「今日の英単語は『{《英単語一覧》[《選んだ数字》]}』です！1日1単語、覚えよう！」をDOMテキスト設定。
```

この`日数差`という命令を使い、作り出した変数`《経過日数》`は、毎日1ずつ変化していくので、単語によって出てくる頻度が違う、という問題を解決することが出来ます。

参考URL

https://nadesi.com/v3/doc/index.php?plugin_system%2F%E6%97%A5%E6%95%B0%E5%B7%AE&show

# 例3：天気予報APIを使った傘アラート

なでしこは、APIも叩くことが出来ます。つまり、ユーザの意図に基づいた双方向通信が実現可能ということです。（ ~~3ウェイハンドシェイクも双方向通信だろ、という突っ込みはやめてください( ;∀;)~~ ）

そこで今回は、[Paizaの記事](https://paiza.hatenablog.com/entry/2021/11/04/130000)で紹介されていた、登録不要・無料で使える天気予報サービス「Open-Meteo」を使い、傘を持って行った方が良いかのアラートプログラムを作成しました。

https://open-meteo.com/

:::note warn
Open-Meteoは、登録不要・無料で使えますが、「非営利目的」「10000回/日 以内」という制限がついています。通常の利用では呼び出し制限を超えることは無いかと思いますが、同一IP内かつ複数人でプログラミングしている際には注意しましょう。
:::

次のコードはサンプルプログラムです。

```
《URL》は「https://api.open-meteo.com/v1/forecast?latitude=34.6872&longitude=135.5258&daily=precipitation_probability_max&timezone=Asia%2FTokyo&forecast_days=3」。
《データ》は、《URL》からHTTP取得して、JSONデコードしたもの。
《明日の降水確率》は、《データ》["daily"]["precipitation_probability_max"][1]。

もし、《明日の降水確率》が0以上ならば、《傘が必要？》は「傘は要らないでしょう。」。
もし、《明日の降水確率》が40以上ならば、《傘が必要？》は「傘はあると良いでしょう。」。
もし、《明日の降水確率》が60以上ならば、《傘が必要？》は「必ず傘を持っていきましょう。」。

「result」のDOM要素ID取得して、「明日の大阪市の降水確率は{《明日の降水確率》}%です。{《傘が必要？》}」をDOMテキスト設定。
```

`《URL》`は、Open-MeteoのAPIのアドレスを示しています。`latitude=34.6872&longitude=135.5258`が、緯度と経度の指定部分なので、ここで指定した場所の降水確率を取得しようとしています。
この`《URL》`に対して、リクエストを送り、JSONデコードしたものが`《データ》`に入ります。ただし、この`《データ》`には、様々な余分な情報が入っているので、`《データ》["daily"]["precipitation_probability_max"][1]`という命令で、明日の降水確率だけ抜き出しています。この部分は、何を取得したいかによって変化しますので、Open-Meteoのドキュメントを参照してください。

<details><summary>例</summary>

例えば、`《URL》`が [https://api.open-meteo.com/v1/forecast?latitude=34.6872&longitude=135.5258&daily=sunrise,sunset&timezone=Asia%2FTokyo&forecast_days=3](https://api.open-meteo.com/v1/forecast?latitude=34.6872&longitude=135.5258&daily=sunrise,sunset&timezone=Asia%2FTokyo&forecast_days=3)の場合は、
```
《明日の日の出の時刻》は、《データ》["daily"]["sunrise"][1]。
《明日の日没の時刻》は、《データ》["daily"]["sunset"][1]。
```
となるでしょう。

また、`《URL》`が[https://api.open-meteo.com/v1/forecast?latitude=34.6872&longitude=135.5258&hourly=temperature_2m&timezone=Asia%2FTokyo&forecast_days=3](https://api.open-meteo.com/v1/forecast?latitude=34.6872&longitude=135.5258&hourly=temperature_2m&timezone=Asia%2FTokyo&forecast_days=3)の場合は、例えば、
```
《明日の午前0時の気温》は、《データ》["hourly"]["temperature_2m"][24]。
《明日の午前1時の気温》は、《データ》["hourly"]["temperature_2m"][25]。
《明日の午前2時の気温》は、《データ》["hourly"]["temperature_2m"][26]。
// 以下略
```
のようになります。

</details>

これに続く`もし、～`では、条件に応じて、変数`《傘が必要？》`に格納されている文字列を変えています。これによって、最後の`「明日の大阪市の降水確率は{《明日の降水確率》}%です。{《傘が必要？》}」`で表示されるテキストを変化させているのです。
実際には、このように表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/0e6a33dc-8bfc-e0f4-1068-f571a86b05cf.png)

なお、このプログラムは、`《明日の降水確率》`が必ず、0以上の値にしかならない、という前提で記述されており、また見やすさのために冗長な書き方をしています。よりスマートに記載するならば、3行に渡る`もし、～`の直前の行に、以下のような一文を入れた方が良いでしょう。
```
《傘が必要？》は「エラー！降水確率が0以下です！」。
```

また、よりオリジナリティを出すのならば、例えば`DOMスタイル設定`という命令を使うことが出来ます。以下のサンプルプログラムは、降水確率によって、背景色と、文字色を変更しています。

```
《URL》は「https://api.open-meteo.com/v1/forecast?latitude=34.6872&longitude=135.5258&daily=precipitation_probability_max&timezone=Asia%2FTokyo&forecast_days=3」。
《データ》は、《URL》からHTTP取得して、JSONデコードしたもの。
《明日の降水確率》は、《データ》["daily"]["precipitation_probability_max"][1]。

もし、《明日の降水確率》が60以上なら、
	《傘が必要？》は「必ず傘を持っていきましょう。」。
	《背景色》は水色。《色》は黒色。
違えば、もし、《明日の降水確率》が40以上なら、
	《傘が必要？》は「傘はあると良いでしょう。」。
	《背景色》は灰色。《色》は白色。
違えば、もし、《明日の降水確率》が0以上なら、
	《傘が必要？》は「傘は要らないでしょう。」。
	《背景色》は赤色。《色》は白色。
違えば、
	《傘が必要？》は「エラー！降水確率が0未満です！」。
	《背景色》は白色。《色》は黒色。
ここまで

《表示画面》は、「result」のDOM要素ID取得したもの。
《表示画面》に、「明日の大阪市の降水確率は{《明日の降水確率》}%です。{《傘が必要？》}」をDOMテキスト設定。
《表示画面》の「色」に「{《色》}」をDOMスタイル設定。
「body」の「背景色」に「{《背景色》}」をDOMスタイル設定。
```
実際の表示例。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/cffb3418-fa50-4d22-a779-96b4acfc26c8.png)


# 例4：家を出るまでの時間を表示する

例3は、「APIの使用＋条件分岐」だけでしたが、次はこれに加えて、繰り返しも使ってみましょう。平日の朝はバタバタしており、あとどれぐらいで家を出ればいいのか分からない！という人のために「あとどれぐらいで家を出ればいいのか」を表示するプログラムを作成しました。~~時計を見ろとか、アラームを掛けろとか、突っ込みは無しでお願いします。~~

基本的な方針としては、「日本の祝日」「土曜日」「日曜日」以外の場合、平日だと判断します。そして平日だと判断されたら、現在時刻と朝8時までの秒数を取得して、0になるまでカウントダウンしていく、というものになります。
なお「日本の祝日」は、年によって変わったりするので、APIを用いて取得することとしました。

https://holidays-jp.github.io/

以下がサンプルプログラムになります。

```
《URL》は「https://holidays-jp.github.io/api/v1/date.json」。
《祝日の一覧》は、《URL》からHTTP取得して、JSONデコードしたもの。

今日の「/」を「-」に置換。
《今日の日付》は、それである。

《メッセージ》は、「今日は平日！元気に行こう！」である。
《残りの秒数》は、0である。

もし、《祝日の一覧》に《今日の日付》が辞書キー存在するならば、
	《何の祝日？》は、《祝日の一覧》[《今日の日付》]である。
	《メッセージ》は、「今日は、『{《何の祝日？》}』だから休み！」である。
違えば、もし、(今日の曜日)が「土」ならば、
	《メッセージ》は、「今日は、『土曜日』だから休み！」である。
違えば、もし、(今日の曜日)が「日」ならば、
	《メッセージ》は、「今日は、『日曜日』だから休み！」である。
違えば、
	《残りの秒数》は、今と「08:00:00」の秒差である。
ここまで。

「result」のDOM要素ID取得して、「{《メッセージ》}」をDOMテキスト設定。

もし、《メッセージ》が「今日は平日！元気に行こう！」ならば、
	《残りの秒数》が0以上の間、繰り返す
		「result」のDOM要素ID取得して、「{《メッセージ》} あと、{《残りの秒数》}秒！」をDOMテキスト設定。
		1秒待つ。
		《残りの秒数》を1減らす。
	ここまで。
	「result」のDOM要素ID取得して、「{《メッセージ》} 時間過ぎてるよ！」をDOMテキスト設定。
ここまで。
```

APIから提供される日付は「2023-01-01」のようにハイフン区切りの日付なのですが、なでしこで提供されている`今日`はスラッシュ区切りです。そこで、「それ」構文を利用し、変数`《今日の日付》`へ、今日の日付をハイフン区切りにしたものを代入しています。

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E3%81%9D%E3%82%8C

このAPIから返却される`《祝日の一覧》`は辞書型変数（キーと値を対応づけて複数保持しているもの）なので、`《祝日の一覧》に《今日の日付》が辞書キー存在`で、祝日一覧に今日の日付が登録されているか確認しています。そして、もし登録されていたら、`《祝日の一覧》[《今日の日付》]`で、何の祝日なのか、値を取り出しています。

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E8%BE%9E%E6%9B%B8%E5%9E%8B%E5%A4%89%E6%95%B0

`《残りの秒数》が0以上の間、繰り返す`は、繰り返し構文の1つで、残り秒数が0になるまで繰り返します。なので、繰り返しの中で`1秒待つ。《残りの秒数》を1減らす。`を実行することで、1秒毎に1ずつ減っていき、それが残り秒数として表示される、という仕組みになっています。

:::note warn
`1秒待つ`という命令が、厳密に1.00秒待っているかどうかは分かりません。より正確にするなら、毎回、秒差を計算しなおすほうが良いでしょう。
:::

実際にこれを張り付けると、動くタイマーが、Google Site上で作成できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/592b136a-6453-afa0-6bf5-e0aea9fe42ae.png)

# 例5：今日のトップニュースを表示する

ここまで、APIの取得、条件分岐、繰り返しを使ってきました。最後に、関数を使った例を紹介します。「今日のトップニュースをまとめて読みたいけれど、中にはあまり面白くないものもあるし、とりあえず見出しだけ教えて欲しい！」という人がいるかもしれません。そこで、ネットニュースを取得してみましょう。
世の中にはRSSという文書フォーマットがあります。これは、ニュースサイト等の更新情報を配信するため文書フォーマットで、多くのニュースサイトが配信しています。そこで、なでしこの`HTTP取得`を使い、ニュースサイトのRSSを取得して、見出しを抽出してみます。今回、使用するのはNHKニュースです。RSSのフォーマットに慣れていない人は、試しに次のリンクをクリックしてみましょう。

https://www.nhk.or.jp/rss/news/cat0.xml

このRSSからニュースを取得してくるプログラムのサンプルは次の通りです。
```
//↓自作関数↓
●(《文章》から《N番目》の《タグ名》を)探す処理とは、
	《検索済の場所》は、0である。

	《N番目》回、繰り返す
		《文章》で、《検索済の場所》から「<{《タグ名》}>」を文字検索。
		《検索済の場所》は、それである。
	ここまで。

	《検索済の場所》と(「<{《タグ名》}>」の文字数)を足す。
	《開始位置》は、それである。

	《文章》で、《検索済の場所》から「</{《タグ名》}>」を文字検索。
	それから《開始位置》を引く。
	《文字数》はそれである。

	《文章》で、《開始位置》から《文字数》文字抜出す。
	それを戻す。
ここまで。
//↑自作関数↑


《URL》は「https://www.nhk.or.jp/rss/news/cat0.xml」。
《生のデータ》は、《URL》からHTTP取得。

《HTMLの改行記号》を、「<br>」に定める。
《表示する文章》は、「【現在のニュース トップ3】{《HTMLの改行記号》}」である。
Nを2から4まで繰り返す
	《生のデータ》からNの「title」を探す処理。
	《ここまでの文章》は、《表示する文章》である。
	《表示する文章》は、「{《ここまでの文章》}{それ}{《HTMLの改行記号》}」である。
ここまで。

「result」のDOM要素ID取得して、「{《表示する文章》}」をDOMテキスト設定。
```

まず、RSSを取得する場合も、APIから取得する場合も、同じ`HTTP取得`という命令で出来ます。
次に、HTML内で改行するための文字`<br>`を`《HTMLの改行記号》`という定数に格納した上で、3回、自作関数`《生のデータ》からNの「title」を探す処理`を行っています。そして、最終的に表示される文章である`《表示する文章》`に、ここまで追加してきた文章と、自作関数の結果と、改行記号を追加しています。なお、Nが2から4なのは、NHKのRSSには、1番目のtitleとして、必ず「`<title>NHKニュース</title>`」が入っているため、2番目以降を取得しています。

https://nadesi.com/v3/doc/index.php?%E6%96%87%E6%B3%95%2F%E9%96%A2%E6%95%B0

では、自作関数の説明をします。関数とは、沢山ある処理をまとめて、なんども使えるようにしたもののことです。なでしこで、関数を作成するには、●からはじめます。
RSSでは、`<タグ名>`から`</タグ名>`の間に、何らかの情報が書かれていることが一般的です。そこで、自作関数`探す処理`では「元の文章（RSS）のなかから、N番目に登場する、タグ名の間に書かれている文章を返す」という働きをします。
まず、`《N番目》回、繰り返す`から`ここまで。`の間では、N番目に登場する`<タグ名>`の位置を探しています。それに、タグ自身の文字数を足したものが、変数`《開始位置》`に格納されます。その次に出てくる`</タグ名>`の位置を取得すれば、両者の差を求めることで、`<タグ名>`から`</タグ名>`の間に書かれている情報の文字数が分かります。最後に、`《文章》で《開始位置》から《文字数》文字抜出す`という命令を使い、`<タグ名>`から`</タグ名>`の間にある文字列を抜き出しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/3a38c0be-d20c-280b-39a9-f9c1904dd85a.png)

実際には、上の写真のような表示になります。

<details><summary>より発展的なサンプルプログラム</summary>

自作関数以外の、表示部分をこのようにすると、DOMを操作して少し見た目の良い、Google Siteにすることが出来ます。
```
《URL》は「https://www.nhk.or.jp/rss/news/cat0.xml」。
《生のデータ》は、《URL》からHTTP取得。
「result」にDOM親要素設定。

「h1」のDOM部品作成して、「【今日のニュース トップ3】」をHTML設定。

Nを2から4まで繰り返す
	「a」のDOM部品作成。
	《リンク》は、それ。

	《生のデータ》からNの「title」を探す処理。
	《リンク》にそれをHTML設定。

	《生のデータ》からNの「link」を探す処理。
	《リンク》の「href」にそれをDOM属性設定。
	改行作成。
ここまで。
```
細かい説明は省きますが、親要素設定したところ（ここでは「result」）に、HTML要素を作成しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197285/822fa5a5-d59c-0cab-94b5-2fcc09d8ff79.png)
このようにすると、実際に押せるリンクを作成することが出来ます。

</details>

# おわりに

Google Siteは、非常に手軽に、全世界（あるいは共有を掛けた範囲）に向けたWebサイトを作成することが出来ます。一方で、プログラミング言語「なでしこ」は、日本語であり、JavaScript等と比べると初学者にとって分かりやすい、にも関わらず、より実用的な社会で役立つものを作成できます。
なでしことGoogle Siteを組み合わせることで、簡単に、身の回りの問題を解決できる可能性があるでしょう。

　

以上。