Edited at

CodeIgniterでDB連携した翻訳ボタンを実装してみる

More than 1 year has passed since last update.

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に使えるよう変更する機能はあるようなのですが、要件が厳密で、うまく適用されませんでした。


おしまい

以上!!!

多分もっといいやり方もあるんだろうけど、ボタンの反応もかなり良いので個人的には良かったな〜と思ってます。マークダウンのコード引用むずすぎかよ