K-POPのダンスを習い始めようかと思っています。キリョウです。
最近リープモーションを買ったので何かに活かしたいです。
本日はサイトに翻訳機能ボタンを作った話。
順序は以下。
DB翻訳ボタンの実装順序
1. jsのダウンロード
2. 翻訳データの作成
3. 任意のviewファイルに翻訳ボタンを設置する
4. フッターのviewファイルにjsのスクリプトを貼り付ける
5. コントローラーで翻訳したいページにデータ受け渡しを設定
6. 翻訳部分のviewファイルに変更の目印を貼り付ける
7. modelにデータを返す機能を追加する(説明がヘビー)
必要な知識と今回の前提
・Igniterのコントローラーの役割とかがわかる
・Igniter内でJavascriptの設置方法がわかる
・databaseは連携してあってMYSQLにデータを作れる
・コントローラー内でviewファイルを組み合わせて作るパターン
・読解力()
Javascriptが出てきますが中身の理解はいらないです。初心者向けですが、説明がややこしい。
ではいってみよう。
1.jsのダウンロード
下記からtranslate.jsをダウンロードして、jsのフォルダに設置。
http://www.openxrest.com/translatejs/
2翻訳データの作成
DBにテーブルを作って、日本語と英語のカラムと各データを入れる。
ここでは例として、nameとname_en、summaryとsummary_enを作成。
ポイント。
・シングルクォーテーションは使えますが、ダブルクォーテーションは使わないでください。
・最終的にHTMLとして出力されるため、タグを入れることができます。(<br>
)
・データベース内での手打ちの改行はしないでください。
id | work_name | work_name_en | summary | summary_en |
---|---|---|---|---|
1 | ハンバーグ | Hunburg | 肉 | nice meat |
2 | ポテト | Potato | 芋だよ | this is imo |
3任意のviewファイルに翻訳ボタンを設置する
ここでは翻訳ボタンを、よくありがちなヘッダーのナビメニューの横にペロッと貼ります。
ボタンはもちろんテキストでも画像でもお好みで。
要素内にclassとdata-valueという項目を設定します。
<span class="lang_selector trn" data-value="jp">JP</span>
<span class="lang_selector trn" data-value="en">EN</span>
ポイント
・translate.jsはjqueryなので、まだ置いていなかった人は、viewファイルのhead内に<script src="jquery.js"/>
を入れておいてください。
4フッターのviewファイルにjsのスクリプトを貼り付ける
下記を、</body>
の直前に貼ります。ここでtranslate.jsのリンクを貼ります。
手順3で、head内に貼っても大丈夫なはずですが、こっちの方が画面表示が軽そうな気がします。
<script src="<?=base_url();?>js/jquery.translate.js"></script>
<script>
$(function() {
var t = <?=$honyaku?>;
var _t = $('body').translate({lang: "en", t: t});
var str = _t.g("translate");
console.log(str);
$(".lang_selector").click(function(ev) {
var lang = $(this).attr("data-value");
_t.lang(lang);
console.log(lang);
ev.preventDefault();
});
});
</script>
ポイント
・ここで指定した、"<?=$honyaku>"
という関数でデータの受け渡しを行います。必要に応じて変更してください。
5コントローラーで翻訳したいページにデータ受け渡しを設定
まずは、コントローラーのコンストラクタに下記を追加。
class Web extends CI_controller {
private $data;//受け渡し用の変数を作ります
public function __construct(){
parent::__construct();
$this->load->database(); // データベース設定ファイルの読み込み
$this->load->model("j_model"); // モデルの読み込み
}
後ほどj_modelというモデルファイルを作成していきます。
コンストラクタの後に、下記のようにworksページを作成していたとします。
public function works(){
$this->load->view('header');
$this->load->view('works');
$this->load->view('footer');
}
下記のように、変数にj_modelファイル内のgetJsonAllファンクションの結果を入れます。
public function works() {
$data['query'] = $this->j_model->getData();//全データを取るやつ
$data['honyaku'] = $this->j_model->getHonyaku();//翻訳用の文字列を取るやつ
$this->load->view('header');
$this->load->view('works',$data);//受け渡し用の変数追加
$this->load->view('footer',$data);//受け渡し用の変数追加
}
6翻訳部分のviewファイルに変更の目印を貼り付ける
ここではworkというviewファイルになります。
このファイルには、コントローラーから渡された、$query
と、$honyaku
という変数が利用できます。
foreachで、idの数の分繰り返しています。(ここではハンバーグとポテトの2回分繰り返されます)
<?php foreach($query->result()as $row):?>
<div class="trn" data-trn-key="work<?=$row->id?>name"> <?=$row->work_name?></div>
<div class="trn" data-trn-key="summary<?=$row->id?>name"> <?=$row->summary_name?></div>
<?php endforeach;?>
ポイント
・classにtrnを、data-trn-keyという項目に、好きな名前を設定します。すべて同じdata-trn-keyの値になると、すべて同じ翻訳の値になってしまうため、案件のidを入れてforeachで回す分だけ、動的に追加します。
・idの位置は、work<?=$row->id?>name
など真ん中に入れてください。
※DBのテーブルを使用せず、それぞれ固有のdata-trn-keyを設定する場合はworknameなど、お好きな文字列をどうぞ!
7modelにデータを返す機能を追加する
コントローラーで呼び出している、J_model.phpを作成します。
ちょっとここがヘビーです。まずは全部貼ってください。「a-数字」のところが変更部分です。
<?php
class J_model extends CI_Model {
/**
* getData
* テーブルkiryoから全データを取得して,データを戻り値として返す
*/
function getData() {
$this->db->select("*");
return $this->db->get("kiryo"); //a-1
}
/**
* getJsonAll
* テーブルkiryoから全データを取得して,JSONに成形して返す
*/
function getJsonAll() {
$this->db->select("*");
$query = $this->db->get("kiryo"); //a-1
$honyaku= array();
while ($row = $query->unbuffered_row()){
$honyaku[] = array(
'work'.$row->id.'name' => array( //a-2
'jp'=> $row->work_name,
'en'=> $row->work_name_en
),
'summary'.$row->id.'name' => array(
'jp'=> $row->summary,
'en'=> $row->summary_en
)
);
};
header('Content-type: application/json; charset=utf-8');
header('X-Content-Type-Options: nosniff');
$honyaku = json_encode($honyaku,JSON_UNESCAPED_UNICODE);
$trim1 = array("\"en\"","\"jp\"","}},{\"work","\"summary","\"work","name\""); //a-3
$trim2 = array("en","jp","},work","summary","work","name"); //a-4
$houyaku = str_replace($trim1, $trim2, $honyaku);
$honyaku = trim( $honyaku, "[] \\" );
$this->output->set_header('Content-type: text/html; charset=utf-8');
return $honyaku;
}
getDataではすべての情報を取り出しています。
getJsonAllでは何をやっているかというと、、、
DBに接続して、データをすべて取り出しJSONとして出力。
その後、js内で使用するために、trimやstr_replaceで文字列を変更し、サーバーに送信されるヘッダー情報をhtml文書に戻しています。最後に、整形し終わった文字列を$honyaku
に入れて返します。
a-1
テーブル名をお使いのものに適宜変更してください。
a-2
これは、'work1name'というタグをviewファイル内で使用する目的があります。
'workname1'や'1workname'だと、JSON出力後の文字列の加工がうまくいきません。
※DBのテーブルを使用せず、それぞれ固有のdata-trn-keyを設定する場合は、while文はいりません。'work'.$row->id.'name'
ではなく、'workname'にして、'jp'=>'ハンバーグ','en'=>'Hunburg'
などここに直接打ち込めます。
a-3,a-4
JSONに変換した際、'jp'は"jp"として出力されます。
これだとtranslate.jsが動かないため、"jp"をjpに変換します。("はエスケープしてあります。)
a-3にJSONの文字を、a-4に変更後の文字を入れています。
ここではまた、"work1name"をwork1nameと変更したいため、"workをwork、name"をnameと分解して変更しています。
※DBのテーブルを使用せず、それぞれ固有のdata-trn-keyを設定し、なおかつwhile文がなくmodelに翻訳内容を書いてしまう場合は、$trim1 = array("\"en\"","\"jp\"","\"workname\"","\"summary\"");
で大丈夫です。
ご利用のDBに合わせてカスタマイズするのは下記の通りです。
変更なし
"jp"→jp
"en"→en
カスタマイズ
}},{"work→},work --配列の先頭 b-1
"work→work --配列の先頭
"summary→summary --先頭以外の配列要素
name"→name --worknameとsummarynameの共通の末尾name
ポイント
・配列の初めの要素
a-2の配列(work_nameやclient_name)では、while文で要素を複数回取りだしているため、配列の一番初めの要素(ここではwork_name)は、}},{"workと区切り用の括弧が無駄に出力されてしまいます。これを},workに変える必要があるため、配列の先頭の要素は、b−1のように変更する項目が一つ多くなります。
・文字列の変更に関しては、jsにJSONparserというJSONをjsに使えるよう変更する機能はあるようなのですが、要件が厳密で、うまく適用されませんでした。
おしまい
以上!!!
多分もっといいやり方もあるんだろうけど、ボタンの反応もかなり良いので個人的には良かったな〜と思ってます。マークダウンのコード引用むずすぎかよ