読者です 読者をやめる 読者になる 読者になる

桜咲く地の気まぐれ日記

管理人の半暴走日記です。勢いのまま書いてることもあるので支離滅裂でも生暖かい目で見てくださいな。

jQuery+JSONで簡易DB

最近色々後回しにしていたサイトの整理やってます。ついでにレイアウトも少々いじったり。
それでファイルが多くていい加減管理が面倒になってきたのでページをテンプレート化できないかと昨日あれこれしてたわけですが、後で見た時に自分が「あーそうだった」って思い出すためのただの覚書。

ものすごく簡単に言うとPHP+DBでやってることをjavascriptでやりたい。csvをDBにして読み込んでる人いたしajaxとか使えばこれ絶対できる。

ということでやってみた。

 


改めてやりたいこと。
一つのページを使いまわして表示内容を変更して表示したい。
つまり画像と文章を差し替えて同じページで表示する。

必要なのは使いまわせるように組んだHTMLと引っ張りだすデータ(画像パスと文章)を入れておくDBファイル、データ取得したりHTML書き換えたりするjavascriptファイル。
これらのファイル全部ブラウザから見えるから個人情報は絶対扱っちゃノーですよ。そういう場合はPHPMySQLとかのDB使わないとダメですよ。あたり前田のクラッカーですけど。

DBはcsvJSONファイルでの作成になるけど、csvはたぶん読み込んだ時が添字地獄になるから嫌だ。
使いやすいように絶対自分で配列なりオブジェクトなりを読み込んだ後に作るはめになる。それは手間が増えて大変面倒臭いのでオブジェクトの状態で読み込めるJSON使うことにします。
csv表計算ソフトとかで扱えるから視覚的にデータ管理するにはいいのだろうど、自分しか使わないから別にどっちでもいいわ。たぶんcsvで作ったところで表計算ソフトで開くことない気がするし……。

テンプレートのページにデータを読み込む流れは

リンクURLにGETクエリ付与
→テンプレートのページで読み込んだjsファイルでGETクエリ取得
jQuery.ajaxJSONファイル読み込み
→GETクエリで取得した値から欲しいデータを引き出してページに設定

以上。なんて簡単なんだろう。JSONファイルにパースエラーがなければ。

昨日コード書いててajaxはちゃんと動いてるっぽいのになぜか読み込みエラーのメッセージばっかりでて。コンソール見てもjavascriptのエラー出てないし、なんやねんって思ったらJSONファイルの方のシンタックスエラーでした。でもどこが間違ってたのか結局把握してないです。いじってたら直ってたので。まあ動けばいいや(待て)。

さて、では実装。
とりあえず適当にイラストページのHTMLをコピペして文章全部消してjavascriptから取得しやすいようにidを追加。といってもcssで使ってるのでimgタグに追加しただけですみました。

    
<img id="target" src="">
<p id="description"></p>
    

こんな感じ。〜でjQueryと作るjavascriptファイルをインクルードしときます。
さて次、JSONファイル。
ajaxで読み込んだ後にどう使うか考えながらDB設計。今回は一次創作と版権でファイル分けたい+作品ごとで取得っできればいいのでこんな感じに。

    
{
    "作品名":[
        {
            "image" : "画像ファイル名",
            "description" : "本文"
         }
    ]
}


書き方の参考・確認は主にこちらでさせていただきました。

JSON 構文


波括弧と角括弧の使う場所間違えたり、配列名の部分「:」のところは空白入れちゃいけないって学びました。配列の中は空白でレイアウト調整できるのにしょぼしょぼ。後""内で改行したら認識してくれないんですね。改行コードじゃなくて改行。横に長くなっちゃうけどまあ仕方ない。ダメだってjavascriptjsonさんが言ってるんだから。

さあJSONファイル内の形式が決まったので、これを引っ張りだすのに必要なパラメータをGETクエリで与えてあげる処理を書くぞ!
自分で書くのも面倒だしこれは転がってるからGETクエリを取得するのはネットから拾ってきました。

JavaScriptでGETパラメーターを取得する - Qiita


このコード前にも仕事で使わせてもらった気が……。ありがたやありがたや。
ともかくテンプレートファイルを呼び出すリンクにGETクエリを追加。
今回欲しいのはJSONファイル名と作品名と作品の中での配列番号。JSONファイルの配列の何番目のデータを表示するかっていう番号です。

    
<a href="template.html?genre=original&title=作品名&number=0">リンク</a>


こんなURL。日本語使うの推奨しないのと&は特殊文字に入るのでURLエスケープするの推奨。日本語も&もURLエスケープしないで使って何かあっても知らん。

javascriptに上のGETの処理とこのGETの処理を呼ぶコードを書いてテンプレートファイルで読みこめばGETクエリ取得できます。
このURLのGETクエリの場合だと

    
var param = getUrlVars();
param["genre"];   // = original
param["title"];   // = 作品名
param["number"];  // = 0


って具合で入ってます。
ここですっごい注意しなきゃいけないのが数字が文字列として入ってるってことなんですよね―。これ整数に変換しておかないとこの後の処理で使えないんですよねー(引っかかった)。

ここまで取得できたら、さあお待ちかねjQuery.ajax()でお呼び出しです。
ということで、まずは呼び出すURLを作成。
JSONファイル名をObject["genre"]と合わせているという前提で


var url = param["genre"] + ".json";


を変数に入れればおk。
合わせたほうが楽なんですけど、嫌だって人はObject["genre"]の値でif文なりswitch文で振り分けすればよろしいと思われ。
テンプレートファイルからのパスと拡張子が.jsonになってれば別に問題無いですし。
あ、JSONPじゃないのでクロスドメインにはならにように配置してくださいね。

    
$.ajax({
}).done(function(data, status, xhr){
    // 通信成功
}).fail(function(xhr, status, error){
    // 通信失敗
    console.log(xhr.status);
    console.log(xhr.statusText);
    console.log(status);
    console.log(error);
});


jQuery11でのajaxはこの形らしいけど、どうもjQueryのバージョンで書き方変わってくるらしいですね。めんどくさ。
ajaxの括弧内にはajaxのパラメータを

    
$.ajax({
    type: "POST",
    url: url,
    dataType: "json",
    cache: false
});


こんくらい書いとけば多分大丈夫。
後は通信成功時と失敗時の処理を書いとけばよろし。失敗時は「読み込み失敗しました」とか表示するようにしておけばいいのとデバッグ様にログ出すようにconsole.logとか書いとけばいいかと。
成功時はdataにJSONのオブジェクトが入ってるのでHTMLをこのデータで書きかえればおk。
dataオブジェクトだけれど中身の見方はこんな感じ。

    
data[param["title"]][param["number"]]["image"];        // = 画像ファイル名
data[param["title"]][param["number"]]["description"];  //= 本文


これだとdata["作品名"][0]にkeyとデータが入ってます。
ここでObject["number"]は文字列だとエラーになっちゃうんですね。残念。
ここのナンバーですが、要するに配列に入ってるので何番目か指定しないと欲しいデータを持ってこれないんですね。配列に入る順番はJSONファイルの記述順です。
大体これ久しぶりに使うとオブジェクト構造どうなってんだっけってなるんですよねー。ちまちまconsole.logで中身表示して確認してく作業から始まる。

さて後は画像ファイル名にパスを追加して

    
)}.done(function(data, status, xhr){
    var image_src = "ディレクトリパス" + data[param["title"]][param["number"]]["image"];
    $("#target").attr({"src" : image_src});
    $("#description").html(data[param["title"]][param["number"]]["description"]);
})


とかすれば表示がGETクエリの値によって変わるはず!
つまり、ブラウザでjavascriptがオンになっていないと何も表示されない!(∩´∀`)∩ワーイ

そうそう画像ファイルはObject["genre"]/Object["title"]以下とかに入れておくとそのまんま使えてやっぱり楽なんだっぜ。でなければ、共通部分までdirectoryの変数とか定数とか作って入れとく楽。定番の方法だけど。

これであとで見ても問題ないでしょう!たぶんきっと!