LoginSignup
0
2

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-02-09

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

おしまい

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

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2