FileMakerでメディア管理 – サムネイルのタイルビューを作った その4。使用するフィールドの詳細な説明です。
フィールド
使用する全てのフィールドについて、この後細かな説明をしています。文章だけでは掴みにくいかもしれないのでフィールド設定の画像を載せておきます。コメント付き。
基礎的なフィールド
画像データベースそのものについてここではあまり触れませんが、基本のフィールドについてだけ少し。
イメージ
オブジェクトフィールドの「イメージ」です。画像データベースだから画像が要ります。当たり前ですね。
ID
未入力不可、重複不可のユニークな値である必要があります。シリアルナンバーを自動で付けてもいいし、uuid をそのまま利用してもいいでしょう。必須のテキストフィールド。
サムネイル
サムネイルをタイルに並べるお話をしているのでオブジェクトフィールドのサムネイルはあったほうがいいですね。 GetThumbnail 関数があるので自動で作ってもらいましょう。
GetThumbnail ( イメージ ; 150 ; 150 )
こう書くと、最大150pxで「イメージ」フィールドからサムネイルを作ってくれます。
最低限、これらがあれば画像データベースとして成り立ちます。でもあまりにも淋しいのでもうちょっとだけフィールドを作りましょうか。
fileName
ファイル名です。オブジェクト関数 GetContainerAttribute を使ってイメージから取得しましょう。
GetContainerAttribute ( イメージ ; "filename" )
fileSize
ファイルサイズもGetContainerAttributeで取得します。最後を “filesize” でOK。でもこれは最小単位で取得します。膨大な桁数の数字がやって来ますから、桁を作って表示し直す仕組みとセットで使いたいところ。
カスタム関数を作ってみましたがこんな感じで合ってます? ・・・ちょっと怪しいですか。怪しいです。検証と改訂をお願いします。。。
Let ( [
B = field ;
KB = Round ( B/1024; 1 ) ;
MB = Round ( KB/1024 ; 1 ) ;
GB = Round ( MB/1024 ; 1 ) ;
TB = Round ( GB/1024 ; 1 ) ;
l = Length ( B );
sz = Case (
l ≥ 13 ; TB & "TB" ;
l ≥ 10 ; GB & "GB" ;
l ≥ 7 ; MB & "MB" ;
l ≥ 4 ; KB & "KB" ;
B & "B"
)
]; sz )
“filiSizefield”がゲットしたバイト数のフィールドです。
GetContainerAttribute は他にも作成日やイメージサイズを取得できたりします。
それ以外では GetAsText が使えます。GetAsText のデータをSubstitute や ValueCount や GetValue と組み合わせていろいろ取得して表示しましょう。
以前どこかに書いたような・・・ありました。
→ FileMakerでメディア管理システムを作る話 2-1 フィールド
HTMLテンプレート
Webビューアに表示するため、その内容のすべてを最終的にHTMLの形で仕上げます。そのためのベースとなるHTMLテンプレートのフィールドです。もちろんテキストフィールド。そしてグローバルフィールドです。
HTML_template
全体のHTMLです。<head>内には<style>も含めます。cssも全部ひっくるめた大元のテンプレート。
参考に、実例で使用しているものを載せておきます。
<html> <head> <title></title> <style> body { background: #777; font-family: "Hiragino Kaku Gothic Pro", sans-serif; } ul{ display: flex; margin: 0; padding: 3px; list-style: none; justify-content: space-around; align-items: center; flex-flow: row wrap; } ul li{ flex: 0 0 150px; margin-bottom: 20px; padding: 4px; } .thumbnail { height: 130px; } img{ object-fit: contain; } a img:hover, a span:hover { opacity: 0.8; transition: all 0.2s; } a { display: flex; justify-content: space-between; flex-direction: column; text-decoration: none; } .title{ font-size:10px; color:#fff; text-decoration: none; max-width:140px; height:2.5em; word-break: break-all; padding-top:0.5em; margin: auto auto 0 auto; } </style> </head> <body> <main> <ul> -----html_inners----- </ul> </main> </body> </html>
この中 <ul> ありますね。<ul>〜</ul> の中に <li> も何もなく、奇妙な文字列「—–html_inners—–」てのがあります。そうです。「—–html_inners—–」は、別で作成した <li> 部分を束ねた html を読み込む・・・というか検索・置換で当てはめるためのターゲット文字列です。
HTML_inner_template
ターゲットに潜り込ませるのはパーツとしてのループ束です。その束を作るために個々のHTMLが必要で、それを作るための<li>〜</li>のリスト中身のテンプレートがこれです。
<li> <a href="ビューアからカードを開くURL"> <div class="thumbnail"> <img src="data:image/jpeg;base64, サムネイルbase64" /> </div> <div class="title"> ファイル名 </div> </a> </li>
これがレコードごとに作られるデータのひな形。ちらほら見えるターゲット文字列部分に、レコードからデータを転記して実際のHTML_innerを生成します。
見慣れないのは画像を表示させるタグでしょうか。
<img src=”data:image/jpeg;base64, サムネイルbase64″ />
ここですね。data:image/jpeg;base64,と書いてからカンマの後ろにbase64文字列を入れます。base64エンコードでテキスト化された画像を表示するときはこのように書きます。こう書くんだからそのまま覚えます。PNGをテキスト化したのならdata:image/png;base64と書くんでしょうね。
個別のHTMLを作成するためのフィールド
タイルビューに必要な措置がいろいろあります。計算フィールドでそれを行っています。
サムネイルbase64
Webビューアで表示するにはすべてHTMLテキストである必要があります。サムネイル画像をテキストに変換しましょう。テキストならHTMLに直接書き込めます。base64エンコードの関数があるのでそれを使いましょう。
Base64EncodeRFC ( "" ; サムネイル )
Base64Encode() ではなくBase64EncodeRFC() のほうです。デフォルトのルールが違うようですのでこっちで。
HTML_inner
HTML_inner フィールドは計算フィールドです。HTML_inner_templateを元にして、ターゲット文字列にレコードデータを落とし込み、<li>〜</li> のパーツを作成します。
Substitute ( HTML_inner_template ; ["ビューアからカードを開くURL" ; ビューアからカードを開くURL]; ["サムネイルbase64" ; サムネイルbase64]; ["ファイル名" ; fileName ] )
FileMakerの計算式では、ダブルクォーテーションで括ると文字列、何も括らないとフィールド名となりますね。ターゲット文字列を、同じ名前のフィールド内容で置き換えていることがわかります。
この中では「ビューアからカードを開くURL」が注目点です。
テンプレートの a href=”” の中にあります。リンクされているURLです。
FileMakerに命令するURL
「ビューアからカードを開くURL」という名前の計算フィールドです。紛らわしい名前でごめん。
FileMakerに命令するURL を計算式で生成します。生成と言っても、生成部分はほんの僅かです(IDだけ)ではこれが何なのか見ていきましょう。
GetAsURLEncoded ( "fmp://$/サムネイルタイル表示.fmp12?script=ビューアからカードを開く¶m=" & ID )
概要の「機能: サムネイルをクリックするとプレビュー画像が表示される」に書いたとおり、FileMakerへの命令をURLで行うことが出来ます。そういう書き方が用意されてるんです。
この計算式がどんなふうにURLを作成しているのか、言葉に翻訳するとこうです。
「このFMファイル(サムネイルタイル表示.fm12)」の「ビューアからカードを開く」という名前のスクリプトを実行、同時に、スクリプト引数としてフィールドIDの内容を渡す。そしてその計算式全体をURLエンコードしています。
命令するURLについて、FileMakerヘルプ「URLを使用してファイルを開く」に実例と共に詳しく載っています(リンク先は FileMaker Pro 17 のヘルプ )
関連する事柄をいくつか書き記しておきましょう。
開いているFileMakerファイルを指定するURLの書き方
まずファイルです。FileMakerのファイルを指定して開くことが出来ます。現在開いているファイルという指定もできます。
「現在開いているファイル」の指定は、まず「$」を書きます。
fmp://$/
こうですって。暗号か変数みたいですね。これが開いているFileMakerファイルを指定する第一歩、この後ろにファイル名を書きます。この稿で実例としてあげているファイルは「サムネイルタイル表示」という名前です(またまた変な名前で申し訳ありません)ですのでURLはこうなります。
fmp://$/サムネイルタイル表示.fmp12
スクリプトを実行させるURLの書き方
スクリプトの実行は、URLパラメータの書き方で行います。即ち「?」 で始まる文字列です。それはこうです。
?script=スクリプト名
ここでは「ビューアからカードを開く」という名前のスクリプトを実行させますからこうなります。
?script=ビューアからカードを開く
スクリプト引数を指定するURLの書き方
スクリプトと一緒にスクリプト引数を渡せます。同じくURLパラメーターの扱いですから「&」で繋ぎます。スクリプト引数を渡すパラメータは param ですって。
ここではスクリプト引数としてIDを渡しますから、param= の後、フィールド「ID」の内容を指定しなければなりません。ただ「param= ID」と書いてもだめですよ。それだと「ID」という文字列を送るだけです。
param= の後、ダブルクォーテーションを入れて「テキストである」ことを一旦切断、改めて & ID と繋げます。フィールド「ID」の指定となり、フィールドの内容が転記されます。
最初から全部繋げるとこうなります。
“fmp://$/サムネイルタイル表示.fmp12?script=ビューアからカードを開く¶m=” & ID
これで完成。ではないです。なんせこれはURLです。記号や日本語を並べ立ててもURLになりません。ちゃんとURLエンコードを施します。GetAsURLEncoded で括りましょう。
命令URLを生成するフィールドの計算式、完成形はこうなります。
GetAsURLEncoded ( "fmp://$/サムネイルタイル表示.fmp12?script=ビューアからカードを開く¶m=" & ID )
アーカイブ用のデータフィールド
その2 概要の “対象レコードから一意のレコードを特定する仕組み” の中でこう書きました。
レコードを直接ループさせる暴挙を辞め、レコードの代わりに身代わりをループさせます。
身代わり
身代わりとは「対象レコードの某かのフィールドをリスト化したテキスト」です。
表示中の対象レコードが3つあって、それぞれIDが001と003と049だったとします。身代わりフィールドには「001¶003¶049」という改行区切りのテキストが作成されているということです。
値一覧に少し似ています。値一覧も、特定フィールドの内容を改行区切りのテキストに格納できます。
値一覧と身代わりで何が違うって、そりゃ対象レコードに準じるか準じないかってところです。それに値一覧では重複をひとつにしたりしますし、並び順もなくなります。だから似ているようで全然違います。
集計フィールドのオプションで「一覧」を選ぶ
身代わりリストの正体は集計フィールドです。
集計フィールドのオプションに「一覧」なんてありました??全然知らなかった。でも知りました。集計フィールドで「一覧」を選択すると、対象レコードの集計として指定フィールドの内容が改行区切りテキストでリストされます。対象の有無だけでなく、その並び順も正確に集計します。
対象レコードが変化する度に集計しリストします。並び順も正確。ということは、テキストの行がレコード番号と一致します。1行目にはレコード番号1のレコードのフィールドが、100行目にはレコード番号100のレコードのフィールドがあります。
これは凄いことです。なんと便利なことか。いえ、まじでこの機能知らなかったので驚きました。いつからこんな良い機能付きましたか。

IDs
IDの集計リストのフィールドです。IDのリストだからIDsです。これはちょっとイケてる名前ですよね?だめ?
現在表示されている対象レコードのIDが改行区切りのテキストとなってリストされます。この集計されたテキストを実際のレコードの身代わりとしてループしたりいろいろします。
例えば手元にIDがひとつあるとします。対象レコードからこのIDのレコードを特定して表示したいとします。対象レコードをくずしたくないから検索して絞り込むことはできません。そこでIDsをループで回して手元のIDと一致するIDでストップ、何行目にあるかを知ることでレコード番号がわかります。スクリプトステップ「レコード移動」でレコード番号を指定、目的のレコードが表示されます。
html_inners
HTML_inners_templateを元にしてデータを流し込み、HTML_inner を生成しました。このHTML_innerを対象レコード分リストした集計フィールドがhtml_innersです。つまりこれはレコードごとの<li>の、対象レコード分の束です。
HTML_innerのリストだからhtml_innersです。ちっちゃい s を見逃しがちなのでこの名前はあまりイケてないか。
html_inners は、HTML_innerの対象レコード分のリスト束ですから、HTML_templateの<ul>〜</ul>の中にまるごとごっそり代入するためにあります。
最終形のHTML
生成HTML
最終形のHTMLを作成する計算フィールドです。HTML_template の<ul>〜</ul>の中、検索置換のターゲットテキスト「—–html_inners—–」にhtml_innersをどかっと入れ込みます。
Substitute ( HTML_template ; "-----html_inners-----" ; html_inners )
対象レコードが多いと、ものすごいテキスト量のHTMLが仕上がります。
これでHTMLが完成。Webビューアの設定ではこの生成HTMLフィールドを表示することにしていますので、晴れてタイルビューの表示が完了します。
このように、タイルビューに必要なほぼすべての計算をフィールドだけでやりました。構築して行くにあたり、スクリプトに書いて進めるより理解がしやすいのでした。
次回はスクリプトについてです。
→ 次のお話 その5 スクリプト