がるの健忘録 このページをアンテナに追加 RSSフィード

2017-10-19

[][]基礎を学びたい時の書籍草案

発端としては。

うちの子(というか元生徒さん)が「内部的な仕組みとかハードとかやってなかったなぁ」というお話があったので。

おいちゃんなりに、多少「お勧め可能な書籍」とかを勧められればなぁ、ってのが発端でございます。


……なんか記憶にあると思ったら、以前にも http://d.hatena.ne.jp/gallu/20170119/p1 でつぶやいてございましたw

書籍にかぶりがあるのはまぁ「そんなもん」だとおもっていただければ。


注意事項

比較的ノンブレーキ(アクセルフルスロットルではない。ブレーキをかけてないだけだ)なので、書籍には偏りもあれば、濃度もあります。

適宜自分で選びなおしつつ、適量を少量づつ、用法容量を守ってお使いください*1


さて。

何はさておきまずはここからでしょう。


UNIXという考え方―その設計思想と哲学

UNIXという考え方―その設計思想と哲学

鉄板中の鉄板でございます。

まずはここから。これは必読。


この後ですが


は割とお勧め。ただ、ちと「訳が悪い」というお話もあり、確かに微妙なところもあるので。

もう一つとしては

コンピュータシステムの理論と実装

あたりもよろしいのではないかなぁ、と。

併読ももちろんありで。


プログラム自体、の話をすると、まずはなんといってもこちら。

これはやはりほぼ「必読」。


ここから先ですが……幾分深くに潜り込むのであれば

熱血!アセンブラ入門

熱血!アセンブラ入門

大熱血! アセンブラ入門

大熱血! アセンブラ入門

あたり。

ちなみに「大熱血! アセンブラ入門」は「購入したけどまだ読んでません」ので、厳密な是非は不明。

ただ、以前の内容とざっと斜め読みの雰囲気からして「面白い」のは確定であろうか、と(笑


ここから一瞬寄り道をするのであれば

新装版 達人プログラマー 職人から名匠への道

新装版 達人プログラマー 職人から名匠への道

も面白い。「プログラミングを深く学ぶ」上では非常によいげなので。

この系の「少し古いけど興味深い書籍」はまだストックがあるので、興味が向いたら適宜、突っついてくださいませw


さらに深く掘り下げていくと

30日でできる! OS自作入門

30日でできる! OS自作入門

経由で

CPUの創りかた

CPUの創りかた

って方向も、存在は、する(笑


さて深堀繋がりで。

インフラの場合、深い根っこのあたりとしては

なんてのがあって、起動プロセスが理解できる、という、割合と稀有な書籍。

そこまでいかんにしても

ルーター自作でわかるパケットの流れ

ルーター自作でわかるパケットの流れ

くらいを押させておくと「パケットがどのように流れるのか」が理解できるので、なにかよい基礎が築ける可能性、が、ある。


インフラ繋がりとしては

インターネットのカタチ―もろさが織り成す粘り強い世界―

インターネットのカタチ―もろさが織り成す粘り強い世界―

を抑えておくと、今度は「インターネット」ってもん(の濃いところ)が見えてくるかもしれない。


余談だけど、あきみちさんの「IPv6本」、楽しみだよねぇ(笑


さて。

プログラムインフラときたら、次はDB

データベースシステム概論

データベースシステム概論

は面白いんだけど、絶版だし、そもそもお値が張る。古いし。

An Introduction to Database Systems

An Introduction to Database Systems

のほうにしてもお値段が以下略。


なので、とりあえず

あたりが穏当にお勧め。

あと、実務ベースだけど

SQLアンチパターン

SQLアンチパターン

は合わせて読んでおいたほうが安全な感じ。


あとは、プロジェクトぶん回し的な意味で

人月の神話【新装版】

人月の神話【新装版】

はほぼ必読。

トム・デマルコさん、って方も色々書籍だしてるんで、検索してみるとおもしろげ。

https://www.amazon.co.jp/%E3%83%88%E3%83%A0-%E3%83%87%E3%83%9E%E3%83%AB%E3%82%B3/e/B000AP7OPO/ref=pd_sim_14_bl_19?_encoding=UTF8&refRID=HG973H4YBVAFDDH1BSF1


余談だけど

暗号技術入門 第3版

暗号技術入門 第3版

もわりと「知らないと痛い」内容が多いので、一読をお勧め。


以上駆け足でなんか色々抜けてそうな気がするんだけど、今「ふと思いつく」程度の、手元にある書籍の群れからのチョイス、でした。

何かの役にでも、立つとよいなぁ。

*1PL法対策

2017-08-29

[][]夢歩き おいちゃん変

久々のTRPGネタ。

先日、他人さまのマスターで深淵をやる機会がちょいちょいとありまして。

何となく思ってないわけでもないのですが「おいちゃんの"深淵の夢歩き"」って、いくつか特徴的なところがある可能性、が想起されたので(ってか差分があったので)。

これが「駄目マスター」だと「駄目なんだなぁ」で片付くのですが、そうではないちゃんと面白いマスターさんで、かつ「おいちゃんとは違う夢歩き(の見解)」だったので、興味深いこの感覚が薄くなる前に一筆。


あぁ当然ですが、以下ぜんぶ「おいちゃんの個人的見解」ですので念のため。


さて。

おいちゃんの夢歩きスキルのベースはぶっちゃけると「Tarot占い」です。

知ってる人しか知らないような気がしますが*1、おいちゃんは、プロのTarot占い師でもあります。

それ一本で食ってた時期もそれなりにありますし、そのあとも色々と占いは受け付けてますし*2、素人さんとかセミプロさん相手に教えてた時期もある、くらいにはプロです。


閑話休題


なので、おいちゃんの夢歩きを「十全に習得する」場合「じゃぁまずはTarotを一通り理解しようか」とかいう気の狂ったお話になるので、まぁそこまで踏み込まない程度に(笑


まずは夢歩きの回数から。

まぁ深淵で「オープニング」と「エンディング」に夢を歩かない、というケースは相応にレアであると思われるのですが。

それ以外に「何回夢を歩くか」は、割と、マスターさんによる色が出るような気がいたします。


おいちゃんは、「オープニング」「エンディング」以外で、キャラにもよりますが大体3〜5回くらいは夢を歩かせるようにしています。場合によってはもうちょいましまし。

多分、めっさ多いです(笑


この辺はおいちゃんの「深淵、というゲームに対するスタンス」などあるか、と思うのですが。

おいちゃんの深淵は、どちらかというと「事実をリアルに正確に」というよりは「幻想的に美しく狂おしく感情の渦に振り回され翻弄されるように」的なセッションを、割合に好みます。

その辺で「夢歩き」ってのは、とても「日常に入り込む非日常」を演出できるんで、割と多用するんですね。

「夢と現(うつつ)の間(あわい)」ってな感じ、でしょうか。


あと、基本キャラクターは「悲惨で陰惨で致命的で暴力的*3運命」を、2つとか3つとか付与されているので。

せめても、プレイヤーが「こんな方向に話を進めたい」っていう、マスターへの意見陳述ルートだ、とも思ってます*4


なので。

基本的には、夢を使って「少しづつ事実(または別のナニカ)を明らかにしていく」っていうような感じで、運命などを紐解く情報源として使います。


んで。その「明らかになっていく情報」ですが。

キャラクターにもよるのですが、「キャラクター本人の謎」と「シナリオの謎」の、できるだけ双方を、織り交ぜたりまぜっかえしたり融合させたりしながら出す事が多いように思います。


この辺は「キャラクターの運命の使い方」にもよるのですが。

個人的には、出来るだけ「各キャラクターの運命が、今回のシナリオにも絡んでいく」ように作る事が多いので*5

キャラクターの運命のひも解きとシナリオのひも解きには「ある程度の関連性」があるので、そんなに苦労する事もないですね。


あと、そのシナリオに「フレーバー」を入れる、なんて事も割とよくあるので。

そういう時は、夢の中にそのフレーバーを、割と執拗に様々な角度からぶち込む、なんてのもやります。

つい先日やったシナリオで吐露させていただくと、多分おいちゃんだと「花畑、蜂、蜂蜜、ミード、蜘蛛、8本脚、糸」あたりのキーワードを使うと思います。


さて、ほんちゃんの夢歩きですが。

上述に書いた

・本人の運命

・シナリオ

・シナリオフレーバー

のそれぞれから、キーワードを抜き出します。

で、プラスして「出された運命カードの"語り部"の文言」を使います。


これで「語るためのベース」が揃いました。

後は「ショートショートな物語を紡ぐ」だけです。

ちなみに「最後の、真相に迫るところ」以外は、あちこちモヤっとさせたままでよいと思います。「適度に隠された」ものは、プレイヤーたちが沢山の妄想をするためのよいエサになりますから(笑


そうですねぇ今、即興で一つ、作成をしてみましょう。

http://d.hatena.ne.jp/gallu/20091223/p5 とかちょうどよいので、使ってみますw


スタート場所

 1.寒村、冬直前(もしくは春)の宿屋。旅路での宿泊

スタート付近夢歩きのきっかけ

 6.村特産の飲み物(お茶、あるいはアルコール類)

オプション

 3.満開の花(場合によっては一箇所だけ奇妙に)

中盤以降の嫌な場所/もの

 3.いきなり出現する青龍:大暴れ

シナリオKey人物の背景

 4.すでに滅びた村。何らかの理由で「すでに滅びた人々」が「夢の中で」生きている。事件の解決は夢の開放、すなわち「村人の死」を招く。が、このままではPC達も夢から出られない。

シナリオKey人物の立場

 3.騎士や貴族などの高い身分の人

シナリオKeyな魔族

 1.八弦琴の魔族


シナリオフレーバーには、前述の「花畑、蜂、蜂蜜、ミード、蜘蛛、8本脚、糸」をそのまま使ってみます。

多分……全体としては「村にしがみついていた貴族」「すでに村は滅びた」「でも"滅びた事"が受け入れられなくて(+魔族の力?)、村が"夢の中で"まだ生きている」的な背景が浮かび上がります。

スタート付近夢歩きのきっかけで「村特産の飲み物(お茶、あるいはアルコール類)」とあるので、村の特産品をミード(蜂蜜酒)としておきましょう。……金持ってそうだなぁ貴族がしがみつく理由の一端が見えそうな気がするよ(笑

恐らくですが、村が滅びた理由が「青龍」で、きっと夢の中でも定期的に「襲ってくる」のでしょう。

蜘蛛がフレーバーにあるので。貴族は「蜘蛛の糸のように現実に糸を伸ばして、"夢の村"という蜘蛛の巣に人々をとらえて、その生命を使って生きながらえている」のかもしれません。

ここで「あぁ蜘蛛の大公スフィンとかいたなぁ」からお話を紡いでもよいでしょうし、その辺はマスターの深淵知識次第なので「特に蜘蛛の魔族については気にしない(出さない)」でもよいと思います。大体、セッションやってるとちょいちょい「PCが魔族化」してたりするので、設定以外にも、大量に魔族っぽい存在は転がってるだろうしなぁ(笑


そうするとシナリオの流れは見えてきます。

http://d.hatena.ne.jp/gallu/20091223/p4 あたりでも少し語っているのですが。

ものっそおおざっぱに。コンベンション前提で、セッション前の説明やらテンプレ選びやら設定決めやらが、深淵は丁寧にやっておいたほうがよいと思うので、1〜1.5時間、と仮定して。

割と多くのコンベンションって「11時くらいに開始、18〜19時には終了」が多いように思うので、大体7時間。準備にのりしろみて2時間、昼飯1時間と考えると、残は5時間。

どこぞのお話ではないのですが*6

タイムテーブルを作ったところで「30分のシーン想定で、実際には1時間30分が必要になる」なんてのはザラ、なので。

まぁとりあえず「30分想定くらいのボリュームで実際には1時間かかるであろう」とみると、残5時間なので、大体「1シナリオ、5シーン」という大まかな流れの骨格が見えてきます。


このうち「第一シーン:オープニング」と「第五シーン:エンディング」は確定しているので、あとは2〜4までの3つ。

ごく大まかには

2.シナリオに流されている:あるいは違和感を感じて調査する(必要なら、軽いバトル一ついれて"戦闘ルールを体に叩き込む")

3.謎を解き明かし、最終ターゲットをマーキングする

4.ラストバトル


くらいの感じでしょうか。

これが謎中心だったりプレイヤーがさまよったりすると

2.シナリオに流されている:あるいは違和感を感じて調査する

3.謎が解らないまま、迷走を繰り返す

4.敵が謎を明かしつつ(大体は不利な状態で)ラストバトル


くらいまでのワンパンは許されるのではないか、と思います(笑


んで、夢歩きの話に戻りますが。

大体、おいちゃんがよく使うのは


・シナリオ導入時の「謎に満ちた」夢歩き

・「だんだん、真相の一部が明らかになっていく」夢歩き*複数回

・ラストバトル直前くらいの「全ての真実が、今、明らかになる!!」な夢歩き


くらい、ですかねぇ。

あとは、夢歩きのちょっと「ひねった」バージョンとして「最後で視点がどんでん返し」なんてのをやる事があります。

わりと強く印象に残っているのが。

「魔族に作られたもの」の運命を持っているキャラクターがいたのですが。


ず〜っと、夢歩きで「君は、何か目の前にある水槽のようなもので、"ナニカ"を作っている」という、作成者側の視点で夢をあるかせ続けて。

「自分の失った記憶……もしかして、自分は魔族ないしそれに類するもので、何かよからぬものを作ってしまったのか?」って方向にず〜〜〜っとミスリードさせておいて。

最後の「全ての真実が!!」のタイミングで、「君は水槽の中の"ナニカ"に声をかけるよ。"さぁ目覚めるんだ 'PCの名前' よ!!"」って爆弾落としたことがありました(笑

プレイヤーさんが、本気で驚いてましたねぇ(笑


まぁ、おいちゃんの夢歩きは、割とそんな感じで作っていくことが多いように思います。

実際に「どんな風に夢を歩くのか」については、そのうちBlogのほうに書いていければなぁ、と思いますので、よろしかったらご期待くださいませ。

*1:当たり前だ

*2:今は「知り合い経由」くらいしか受け付けてませんが

*3:はずの

*4:陳述が「通るのか」はまた別問題w

*5:作成場所:セッション場所。作成時間:セッション直前(若しくはセッション中)

*6:Ashenroses Report、と書いてわかる御仁でここを見る可能性があるのは、多分、地球上でわずか数名であろうw

2017-08-13

[]本当にメモ書き程度

多くの場合において

/etc/dovecot/conf.d/10-mail.conf

あたりにあると思われる、いわゆるメール受信側(POP3とか)の設定で。


first_valid_uid


ってのがあるのかへぇしらなんだ。

色々と所以があって、一部のふる〜〜〜〜いアカウントは500番台の後半くらいからアサインされてるのがあるので。

その辺のアカウントが、これでひっかかってきたお。


うんまぁ色々と面白いなぁ、と思ったので、メモり。

2017-08-11

[]CentOS7にBIND 9、のナレッジ

お引越しでインストールした&案外とあちこち躓いたので、めも。

…いやまぁそもそも「そろそろBINDやめようよ」とか思わないわけでもないのですが、一応。


インストールは、大体こんな感じ、がベース。

yum -y install bind bind-chroot

firewall-cmd --add-service=dns

firewall-cmd --add-service=dns --permanent

firewall-cmd --list-services

/usr/libexec/setup-named-chroot.sh /var/named/chroot on

# すげぇ念の為

systemctl stop named

systemctl disable named


で、設定を終えた後で

systemctl start named-chroot

systemctl enable named-chroot

でOK。


……なんだけど、設定ファイルの記述ミスその他で大量に躓いたので。

おいちゃんの脳内フラッシュメモリから(ある意味奇跡的に)こぼれていない情報を、整理もせずに羅列。


情報としては

journalctl -xe

で出てくる……って言われるんだけど、色々と「もうちょっと情報よこせ」って感じの事が多々。

日付抜くの面倒なんで日付入りで晒すと、/var/log/messagesに

Aug 11 17:51:49 localhost named[4886]: ----------------------------------------------------

Aug 11 17:51:49 localhost named[4886]: BIND 9 is maintained by Internet Systems Consortium,

Aug 11 17:51:49 localhost named[4886]: Inc. (ISC), a non-profit 501(c)(3) public-benefit

Aug 11 17:51:49 localhost named[4886]: corporation. Support and training for BIND 9 are

Aug 11 17:51:49 localhost named[4886]: available at https://www.isc.org/support

Aug 11 17:51:49 localhost named[4886]: ----------------------------------------------------

Aug 11 17:51:49 localhost named[4886]: adjusted limit on open files from 4096 to 1048576

Aug 11 17:51:49 localhost named[4886]: found 2 CPUs, using 2 worker threads

Aug 11 17:51:49 localhost named[4886]: using 2 UDP listeners per interface

Aug 11 17:51:49 localhost named[4886]: using up to 4096 sockets

Aug 11 17:51:49 localhost systemd: named-chroot.service: control process exited, code=exited status=1

Aug 11 17:51:49 localhost systemd: Failed to start Berkeley Internet Name Domain (DNS).

Aug 11 17:51:49 localhost systemd: Unit named-chroot.service entered failed state.

Aug 11 17:51:49 localhost systemd: named-chroot.service failed.

Aug 11 17:51:49 localhost systemd: Stopping Set-up/destroy chroot environment for named (DNS)...

Aug 11 17:51:49 localhost systemd: Stopped Set-up/destroy chroot environment for named (DNS).

こんな感じで出てくるのを、ヘッジした時の諸々。


とりあえず前提として

・外向けの権威サーバ立ててる

・プライマリもセカンダリも自前

chrootは「とりあえず念の為やっとく」


大本の設定ファイルは、 /etc/named.conf 。

実際には /var/named/chroot/etc/named.conf を見ているはずなんだけど、これは systemctl start named-chroot とか systemctl restart named-chroot とかすると、/etc/named.conf から持ってきてくれるぽいので。

修正などは、 /etc/named.conf にそのままぶちかます。

ちなみに、restartとかしないと反映されないので、修正されたらretartしよう。


大体同じニュアンスで。

directory "/var/named";

を前提に、zoneファイルは /var/named に置いておく。

これも実際にはchrootで以下略。

ちなみに、restart以下略。


ファイルをmvだったかcpだったかしようとしたら「same file云々」とかいうエラーメッセージが出たので、多分「内部的には完全に同一」だと思われ。

chrootのギミックなんだろうけど、一端ここは深堀せず。

そのうち余裕があったら。


んで、書式で結構色々と躓いたので、引っかかったところを列挙。

・named.confとzoneファイルで書式が違う。具体的にはコメントが。named.confは//と /**/が使えて、zoneは;がコメント。zoneで/**/は多分使えない

・named.confは後ろに ; がないとエラーになる

zoneファイルのパーミッションに注意。上述の起動の仕方だと named ユーザ起動になるんだけど。zoneファイルのパーミッション的に「読めない」と、エラーにはならないのに情報が見れないwww

・named.conf、allow-queryを「localhost;(たしか、デフォがこれ)」にすると「外部から見れない」ので注意。anyが正解

・同じくnamed.conf、「recursion no;」は忘れずに!! たしかデフォがyesなのだよねぇ……。「外向き」にするんなら必須なんじゃなかろうか?

・named.conf。「allow-transfer { none; };」「allow-update { none; };」「allow-query-cache { none; };」も必須。デフォだった気もするんだが、明示して悪いもんでもなかろうもん

・「version "unknown";」気分w

・プライマリには「notify yes;」「also-notify { 11.22.33.44; };」。セカンダリ散らかさないんなら、optionsん中でよいと思う

セカンダリzoneの中に「type slave;」「masters { 1.2.3.4; };」で、親からとってくる感じ。「同名ファイルがあるとNG」「ディレクトリパーミッションに気をつけろ」ってあたりがポイント? ここ、すんなり通ったからナレッジが今一つ……

zoneファイルのほう。おいちゃんCNAME好きなんだけど「CNAMEで宣言するドメインMXとかに使えない」ので注意。……はまりました orz

・あ。TXT書かなきゃ(まだ書いてない……メールサービス組む時でよいかし……)


ちな、試験は

dig ドメイン名 @localhost

dig ドメイン名 @[鯖のIPアドレス]

dig よそ様のドメイン名 @[鯖のIPアドレス] # エラーになる事

で実験。


さて引き続きいくつか実験君がまっているので……この三連休はその辺でつぶれそうな予感……

2017-07-22

[][][]多言語対応のあれこれ

ふと生徒さんに質問をいただいたのもあって。

ちょうどよいきっかけになったので、せっかくなんでBlogで。


本質的には「どの言語のどの領域」でもある程度応用が利くかと思われますが。

一応、おいちゃんの記述なんで「MySQLPHPつかったWebアプリケーション」をど真ん中に据えて、ってな感じで。


まず「ユーザからの入力について多言語対応したい」は簡単で「保存するデータ及びHTMLUTF-8にしましょう」で、fin。

いやまぁUnicodeであれば大体無問題だと思われるのですが*1HTMLとかでUTF-16って、あんまり見た記憶がないんですよねぇその辺詳しい諸氏の突っ込み求む。

ひとつポイントがあるとすると「MySQL文字コードは、utf8じゃなくてutf8mb4」ってあたりなのですが、そのためにはMySQL5.5.3+というバージョンが必要なのでそれより低いバージョンの場合はバージョンをあげましょうここに慈悲はない。


お次に「プログラム的に動的な文字の出力」をどうするか、ですが。例えば「お知らせ」とか。

この辺あたりから少し面倒になるのですがおおむね

・ユーザが「表示してほしい」言語を忖度する

忖度した結果としての「選択された言語」のデータを引っ張ってくる

ってまぁ、こんな感じ。


まぁ最終的には「ユーザに選んでもらう」でよいですし、選んだ結果は「Cookieあたりに保存」しておけばよいのですが。

初手のアクセスで「きっとこの人は日本語圏の人なのではなかろうか?」を推測したいのであれば、HTTP RequestヘッダのAcecpt-Languageを見ると、比較的、ヒントがあったり。

PHPの場合

$_SERVER['HTTP_ACCEPT_LANGUAGE']

で取得可能。帰ってくる値は、例えば

"ja,en-US;q=0.7,en;q=0.3"

ってな感じなので。初手にjaがあったら「なんとなくこの人、日本語圏の人なのではないだろうか?」と推測が可能。

それ以外は適宜しらべて。en-USとかきたら英語圏だし、それ以外で斜めに調べた限りだと「de (ドイツ語)」「es (スペイン語)」「it (イタリア語)」など。

後ろの「q=0.7,en;q=0.3」にも本来的には意味があるので、興味がある諸氏は適宜しらべたし(大まかには、各言語の優先確率)。

雑に行くんなら「先頭2文字で判断」でも、当面は困らないんじゃないかなぁ切り出しておいて問題が起きたら修正すればいいんだし(雑)。


で、あとは例えば「お知らせ」なら、お知らせテーブルに「言語」とかいうカラムをつけておいて

ja: お知らせです。

en: It is news

it:saluti

とかって感じでデータを用意して出力すれば、それでOKな感じ。どっちかってぇと「各言語のコンテンツ」用意するのが面倒だよねぇ、的な。

でもまぁそれはコンテンツ用意する人の問題なので、サイトの骨格であるシステム作成のおいちゃん的にはいったん気にしないw


さて割と一番大きな本題「HTMLなどの静的*2なファイルの文字」をどうするか、ですが。

大枠として2種類あって、かつその2種類にはそれぞれ亜種がいくつか存在します、ので、それぞれ、ある程度(もしくは簡単に触りだけ)説明をしていきたいかなぁ、ってのが、本文章の趣旨。


大まかには

テンプレートを切り替える

・出力文字を切り替える

の2種類。

それぞれ、少しかみ砕いて。


テンプレートを切り替える

いやまぁそのまんまなのですが。

例えば「ログイン」Pageがあるとして、ボタンに「ログイン」とか日本語で書かれると、英語圏の人は多分いろいろと困るです。

……いや日本のサイトで「login」って書いてあっても困らない気がビシバシとするのですが、その辺は置いといて。


てっとり早いのは「英語圏用のテンプレート」と「日本語圏用のテンプレート」とを別々に用意して出力を切り替える、って方法がありまして。

対応言語数が少ない&ページ数が少ない&更新頻度が低い(更新そのものが少ない)のであれば、割と手っ取り早い解決策だと思われます。


方法としては

・言語ごとにディレクトリを分ける

・言語ごとに拡張子を分ける

って方法がありまして。


例えば(Smartyチックに)login.tpl、ってテンプレートがあるとしますと。

ディレクトリで分ける」パターンであれば、

templates/ja/login.tpl

templates/en/login.tpl

って風に入れて。

拡張子で分けるのであれば、(Smarty的に「本当の意味での拡張子」はいじると面倒なんで)

templates/login.ja.tpl

templates/login.en.tpl

って感じにすると、切り分けられます。


上述のような切り替えの作業は、どこか一か所にまとめておくといろいろと楽ですよね。

うちのフレームワーク(MagicWeapon)であれば、viewクラスのmake_template_filename()メソッドを上書きして、って感じかなぁ。

まぁ大体の*3コードであれば、どこかしら「テンプレートのファイル名を取得する」的な一点があると思うので、そこを「キュッ」と絞めると、いけると思います。


出力文字を切り替える

対応言語数が多い&ページ数が多い&更新頻度が高いのであれば、「出力文字による切り替え」を想定したほうが楽かもしれません……初手面倒ですが。

端的には

・各言語用の翻訳ファイルを用意して

プログラムを通して文字列を変換する

となります。


これにも方法がいくつかあって、大まかには

サーバサイドで自力実装

クライアントサイドで自力実装

・「gettext」ってのが割とあちこちの言語でライブラリとして存在するので、それを使う

のいずれか、になります。


共通があるのでgettextがよさそうなもんですが…それなりに使い方とかお作法とか癖とかがあるので。

PHPの場合は「インストール」も必要ですしねぇ。

前提条件や癖やそのあたりが「呑み込めそう」なら、gettextを使ってみるとよいんじゃないかなぁ、と思います。

xgettextとか面白いんだけどなぁ……「テンプレートエンジンを使う」前提だと、幾分、ハードルが上がったり諸々が以下略。


自力で作る場合は、おおむね

・辞書のフォーマットを決める

・辞書ファイルを必要言語数だけ作る

テンプレートに辞書ファイルをぶつけて出力する

といった感じ。


んと……ざっぱに、例。

例えば辞書ファイルを「コード: 翻訳文」とします。

日本語と英語を用意してみませう。


辞書.ja

login_button: ログイン

login_text: こちらからログインしてください。

password_reminder_text: パスワードがわからない場合はこのボタンを押してください。

password_reminder_button: パスワードリマインダ


辞書.en

login_button: login

login_text: Please log in from here.

password_reminder_text: Please press this button if you do not know the password.

password_reminder_button: Password reminder

*4


いろいろと面倒なんでいったんSmarty前提。

まずPHP本体側で、「言語にそった辞書」を渡します。

辞書は、key=コード、value=翻訳文、のhash配列方式で情報があると仮定

// 辞書の選択
if (日本語圏なら) {
  $辞書配列 = 日本語の辞書;
} else if (英語圏なら) {
  $辞書配列 = 英語の辞書;
} else {
    // 例外でもぶん投げるかねぇ
}

// 辞書をアサイン
$smarty_obj->assign('dic', $辞書配列);

んで、Smartyでは、例えばこんな風に記述します。

{$div.login_text}
<form ...>


<button>{$dic.login_button}</button>
</form>

こんな風にしてテンプレートに「一切出力用の自然言語を書かずに」辞書ファイルに追い出すと、まぁいろいろとできたり出来たりします。ざっくりとは。


結論

がっつりと多言語対応って、割と案件数的にも少ない気がするので。

調べると、案外とネットの情報も少ないんですよねぇ……なので、書いてみた。


なんかほかにも手法ありそうなのですが、まずは「こんなのもあるよ〜」的に。

突っ込みとかあったら突っ込んでくださいませ > 諸氏

*1UTF-7? なにそれ美味しいの?

*2:政敵って変換するFEPについてどう思う?

*3:まっとうな

*4:英訳への突っ込みはこれを禁止するwww