WixStudioでVeloを使う Step 11 「コレクションを使う(wix-dataで目的のデータを取得する)」
はじめに
コレクションについてもっと触ってみたい。コレクションを使ってデータを適切な形で溜め込んで。「はい、おわり」は良くない。なんでも使ってこそ価値がある。使い方に触れてみたい。蓄積されたデータを使う方法に触れる。
データを取り出して出力したり、内容に応じて変化させたり。してみる。
目標
コレクションに登録されている情報を使ってサイトやページに変化を加えてみる。
準備
データが登録されたコレクションを一つ用意したい。簡単にコレクション作成出来る方法はないかと考えた。コレクションにはCSVインポートという機能がある。CSVファイルで用意されたデータがあればいい。ちなみにCSVを簡単に説明すると、1件当たりの情報がカンマ区切りで整列されたデータ形式。
祝日データ
日本の祝日データが内閣府のサイトに用意されていた。データとしては昭和30年から令和6年までのデータ。今後もちゃんと更新されるらしい。これを使う。
昭和30年(1955年)から令和6年(2024年)国民の祝日(csv形式:20KB)
例えば、サイトヘッダーに「今日は何の日?」的な情報が出ていても面白いような気がする。祝日データじゃなくて店舗の休み予定を登録しておくなんて応用もできる。サイトを見れば店舗が休みなのかどうかが一目瞭然なら素敵な気がしてきた。
とりあえずダウンロードしておく。
コレクションを作成
祝日データを登録しておくためのコレクションなので「Holidays」とでもしておく。
コレクション作成
とりあえずフィールドは2つで良い。祝日名とその日付。元々Title(テキスト)フィールドが用意されているので、追加で日付用のフィールドを追加する。
日付用のフィールドを作成
フィールドタイプ | フィールド名 |
---|---|
日付 | Date |
時刻フィールドは不要なのでチェックしない。
Holidaysコレクション
データをインポート
後はデータをインポートすれば良いのだが、検証したら色々と問題が起きたので、もう一手間準備が必要。
このまま進めると発生する問題
データの加工
加工内容は具体的には3点ある。
- (準備)ファイルを開く
- 日付の区切り文字を「/」から「ー」に変更する。
- 文字コードを指定して保存する。
ファイルを開く
まずは、CSVファイルをVSCodeなどのエディタで開く。文字化けした状態でファイルが開かれる。
VSCodeで開くと文字化けが確認出来る
文字化けが確認出来たら、VSCodeの右下に「UTF-8」という表示を見つけクリックする。
UTF-8の表示
文字コードを指定して開き直すことが出来る。「Reopen with Encoding」を選択する。
文字コードを指定して開き直す
現在はUTF-8が指定されているので「Japanese(Shift JIS)」を指定する。
ShiftJISを指定する
正常に表示されたCSVファイル
VSCodeで正しくファイルが開かれたら編集作業を始める。
日付の区切り文字を「/」から「ー」に変更する
区切り文字については置換処理で一撃で終わる。Ctrlキーを押しながらHキーを押す。置換処理の小窓が現れる。二つの入力フィールドががあるので一つ目には置換対象となる「/」、二つ目には置換後の文字列「ー」を指定する。どちらも半角で指定する。
置換処理の小窓
入力後ReplaceAllボタンを押すと置換が開始される。
Replace Allボタン
置換に失敗した場合は、Ctrlキーを押しながらZキーを押せば元に戻る。
置換処理の小窓を再度利用する。
まず、一つ目のフィールドには-(\d)([-,])
を指定する。さらに、一つ目のフィールド右端にある.*
をクリックしておく。
「.*」を選択する
これは正規表現を利用した置換を行う為の設定。
二つ目のフィールドには-0$1$2
を指定し、ReplaceAllボタンを押す。一度では全て置換できない場合があるので置換対象がなくなるまで数回ボタンを押す。置換対象がなくなると「No results」と赤文字で表示される。
2回目の置換処理
以上で置換処理が完了。
文字コードを指定して保存する
編集が終わったら保存しておく。VScodeの右下の「Shift JIS」表示をクリックする。
Shift JISの表示
文字コードを指定して保存することができる。「Save with Encoding」を選択する。
UTF-8を指定する
現在は「Japanese(Shift JIS)」が指定されているので「UTF-8」を指定する。
文字コードを指定して保存する
以上で、HolidaysコレクションにインポートするためのCSVファイルの準備が完了になる。
インポートする
HolidaysコレクションのCMS画面を開く。右上に「その他のアクション」ボタンを押し、「アイテムをインポート」を選択する。
アイテムをインポート
専用のウィザードが開く。「ファイルを選択」ボタンを押す。先程整えたCSVファイルを指定する。
ファイルからコンテンツをインポートのウィザード
指定したCSVデータをコレクションのカラムと対応付けるための設定が開かれる。画面構成として、左側にCSVの列。右側にはコレクションの列が設定できるようになっている。
CSVデータとコレクションのカラムを対応付ける
設定の流れとしては次のようになります。
- 左側のCSVの列を選択する
- 右側でコレクションのカラムを指定する。
- 「インポート後の例」を確認し、CSVの次の列の設定に進む。
国民の祝日・休日月日 設定
国民の祝日・休日名称 設定
「カラムの設定」は「既存のフィールド」を指定し、「コレクションフィールド...」で適切なフィールドを選択する。
今回は予めコレクションを準備しているため選択するだけで良い。インポートのタイミングで新規で列を作成することも出来る。
設定を進めるときは、必ず「インポート後の例」を確認する。今回の場合はコレクションのTitle列に休日名称がインポートされることが確認出来る。Date列には休日月日がインポートされる。
設定が完了したら「次へ」ボタンを押し直前のインポート確認が表示される。
インポートするファイルを確認
これが最後の確認。「インポート」ボタンを押すと処理が実行される。
インポート処理
処理が完了したらコレクションを確認し、データが正しくインポートされていることを確認する。
インポートが完了
コレクションに対する準備は以上。
画面の準備
Homeページにテキスト要素を配置しておく。
テキスト要素を配置する
テキストの内容にこだわりはない。
処理を書く
Homeページに用意したテキスト要素に、本日が何の日なのか表示する処理を書く。
ページコードを書く
とりあえずページコードを書く。HomeページのページコードをVeloで開き以下のソースを記述する。
ページコード(Home)を記述
import wixData from 'wix-data';
// ページが表示されるときに実施される
$w.onReady(function () {
// 現在の日時を取得する
let today = new Date();
// 日時の情報から2023-01-01の部分を取得する
let todayStr = today.toISOString().split('T')[0]
// コレクションから、今日の日付に該当するデータを探す。
// 今日の日付に該当する休日データがあれば該当したものの中から1件を取得する
wixData.query('Holidays')
.eq('date',todayStr)
.limit(1)
.find()
.then( results => {
// 画面に配置したテキスト要素に表示する文言を準備する。「今日は....」
let todayIs = "今日は"
// 該当データの有無を確認
if(results.items.length == 1){
// 該当データがあった場合、該当データ休日名称を取得する。
todayIs += results.items[0].title
}else{
// 該当データが無ければ、今日は祝日じゃない
todayIs += "祝日じゃない"
}
// テキスト要素にメッセージをセットする。
$w("#text4").text = todayIs
})
});
ポイントはいくつかある。特に重要なのはコレクションを取得する手順。import wixData from 'wix-data'
が必ず必要。コレクションから目的のデータを取得する溜にはVeloAPIのwix-dataを使う必要がある。
使い方は単純。上記インポート文を冒頭に記述した上で、wixData.query('Holidays')
とする。この記述によって、Holidaysコレクションから目的のデータを探すことが指定できる。続いて.eq('date',todayStr)
はHolidaysコレクションから探したいデータの条件を指定している。eqはequal(等しい)の意味。.limit(1)
は該当したデータの内1件を取得するという指定。念のために指定した。最後に.find()
が処理の実行になる。英単語的に言えば「探せ!」って命令だと思えば良い。「どこから」「どんな条件で」「探せ」が基本的な構造だと思えば良い。
順番が前後したがlet today = new Date();
とlet todayStr = today.toISOString().split('T')[0]
について触れる。前者は現在の日時を取得する処理。年月日に加えて時分秒までの日時情報。これはページを開いた時点で毎回異なる。後者は日時情報から年月日の情報を文字列として取得するための処理。.toISOString()
は日時情報をYYYY-MM-DDTHH:mm:ss.sssZ
の書式で文字列表現してくれる。こちらが求めている日時情報はYYYY-MM-DD
なので余分な情報が多い。.split('T')
は以前の記事でも出てきた。丸括弧で指定した文字を使って対象の文字列を区切り配列化してくれる。YYYY-MM-DDTHH:mm:ss.sssZ
の中央に注目。中央の「T」は日付と時刻の情報を区切る文字。この文字を区切り文字として指定すると日付と時刻を分割し配列にする事が出来る。もちろん必要なのは前者になるので、最後に[0]
を付加し配列の先頭要素を取得している。先頭要素にはYYYY-MM-DD
の書式で年月日を表す文字列が格納されている。
mdn web docs - Date.prototype.toISOString()
話を戻す。Holidaysコレクションから情報を取得する際に指定した条件に注目する。.eq('date',todayStr)
は、Holidaysコレクションのdate列の値がtodayStrと同じものを条件として指定している。todayStrは本日の日付情報をYYYY-MM-DD
形式で表す文字列が格納されている。例えばtodayStrが2024-01-01だとすれば、元旦のデータが手に入る。
2024-01-01は元旦
取得した結果を処理するのは.then( results => { ... })
の部分。
Homeページには祝日であれば「今日は○○」、祝日でなければ「今日は祝日じゃない」と表示するつもり。いずれにしても「今日は」は共通なのでlet message = '今日は'
としている。続きの部分は条件や日によって異なる。if(results.items.length == 1){...}else{...}
は条件判定。今回は「本日の日付(YYYY-MM-DD
)は、祝日コレクションに該当したかどうか」という条件。該当すればtodayIs += results.items[0].title
、該当しなければtodayIs += "祝日じゃない"
としている。todayIs += ....
の表記は追記を表す記述。todayIsには「今日は」までの文字列が既に格納されているので、その続きの文字を+=
の後に記述する。条件に応じてtodayIs
には「今日は○○」の文字列が完成する。
$w("#text4").text = todayIs
で完成した文字列を画面に表示している。
動作を確認する
サイトを公開し結果を確認する。
サイトにアクセスした直後は画面に「今日は何の日?」が表示される。
まずは「今日は何の日?」が表示される
しかし、瞬時に「今日は○○」の表記に切り替わる。
瞬時に「今日は○○」が変化する
検証した今日は2023年9月8日なので平日。だから「今日は祝日じゃない」になる。
まとめ
コレクションで管理されている情報を扱うときにはwix-dataを利用する。情報を取得するには「どこから.query()
」「どんな条件で.eq()
」「探せ.find()
」が基本的な構造。条件が複数ある場合には.eq()
を続けて書けばいい。結果は.then(results => {...})
で処理を書く。これは.find()
が結果としてPromiseを返すためだが、まずは形式的に憶えておけば良い。
VeloReference - WixData.query()
VeloReference - WixDataQuery.eq()
VeloReference - WixDataQuery.find()
VeloReference - WixDataQueryResult
応用
バックエンドコードを使って、処理をかき分けても良いと思う。汎用的な形にしておくと便利になる。
import wixData from 'wix-data';
export async function checkHoliday( date ){
let todayIs = ''
let todayStr = date.toISOString().split('T')[0]
await wixData.query('Holidays')
.eq('date',todayStr)
.limit(1)
.find()
.then( results => {
todayIs = "今日は"
if(results.items.length == 1){
todayIs += results.items[0].title
}else{
todayIs += "祝日じゃない"
}
})
return todayIs
}
import {checkHoliday} from 'backend/holidays'
$w.onReady(function () {
let today = new Date();
checkHoliday(today)
.then( msg => {
if(msg){
$w("#text4").text = msg
}
})
});
つづき
WixStudioでVeloを使う Step 12 「コレクションを使う(wix-dataで目的のデータを取得する。条件指定。)」
Discussion