C言語でCMSを書く その3 HTMLの生成(マクロ展開とか)

記事
IT・テクノロジー
マクロ展開機能はとっても重要
さて、前回のブログでは、CMSで必要なデータ構造体 element型について、かなり突っ込んで書きました。
今回は、element型に入っているデータからHTMLを生成して、ブラウザに返すところについて書いていきます。で、そのキモとなるのは、マクロ展開です。マクロ展開というのは、生成されるHTMLのテキストの中に、マクロ定義された文字列があったら、その文字列を定義されている別の文字列に変更する、っていう話です。

AWExion HOTPortは、一応、分散サーバ型のNFTプラットフォームということになっているので、同じC言語のソースコードで動くサーバが多数あるわけですね。そうすると、サーバのURLなどをソースコードに埋め込んでしまうと、他のサーバで利用するときには、いちいちそこを書き換えたりする、みたいな話も出て来るから、そこは、生成されるHTMLの中で、たとえば、ThisHostと書いておいて、その部分を、実際のサーバのURLに変換してくれたりすれば良いわけです。書き方は簡単です。生成されるHTMLの中で、${ThisHost} という部分を見つけたら、その ${ThisHost}というのを、別の、たとえば、Https://coconala.com (頭のHは本当は小文字です)に変換してくれたりすれば良い、ということになりますね。

ほかに、こういうプラットフォームでは、ログインして、アクセスしてきたユーザのIDやセッションID(ログイン中に付加されるID)をあちこちに埋め込まないといけませんから、UserIdとかSessionIdとかも、マクロ定義しておけば、生成するHTMLの中には、${UserId}とか${SessionId}とか書いておくだけで、あとは、マクロ展開されますから、便利です。
で、その変換テーブルは、実は前回のブログで書いたelement型の中に入れておきます。ブラウザからアクセスされたときに、ブラウザから送られてきたヘッダーファイルの内容や、ユーザIDやセッションIDは、ElemPostというelement型の構造体の中に、タグ付きで入っています。ですから、それに基づいて、マクロ展開する、ということになります。

それから、前回のブログで貼り付けたWEBページのサンプルの左上部分について、上に「戻る」とか「最初のページに戻る」とか「ポータル」とかのボタンがあったり、左には、「カバーページ」などのメニューがありますが、こういうの、日本語表示されていますけど、これも実はマクロ展開で日本語に変換しています。ブラウザが日本語表示可能なブラウザであると判断したときは、日本語用のマクロテーブルを読み込み、そうでないときは、英語用のマクロテーブルを読み込むようにしています。現在のところは、日本語と英語だけしか作っていませんが、今後、他の言語も用意しておけば、少なくともメニューとかボタンとかは、その言語で表示できるようになるわけです。
PageSample1Part.png
で、これらの単語マクロ変換テーブルは、プログラム中では、こんな感じで、書かれています。
----ここから----
char* LexJA[] =
{
  .....
  "letsStart=さあ、始めましょう!",
  "list=一覧",
  "log=履歴",
  "login=ログイン",
  "loginName=ログイン名",
  "loginNameHidden=ログイン名は非公開です。既に登録済みログイン名の場合は登録失敗します。", 
  "loginFailed=ログインできませんでした",
  "logout=ログアウト",
  "makeNote=メモしてください。",
  ....
};
----ここまで----
で、ブラウザからのアクセスに対して、ElemPostの中で、Lexというelement型データのところに、テーブルが格納されます。そうすると、生成されたHTMLの中で、${Lex/loginFailed} という部分があったら、それが、「ログインできませんでした。」に変換される、ってわけです。
もちろん、日本語で書いた文章を英語に自動翻訳するようなわけではないにせよ、生成されたHTMLの中で、決まり文句みたいなものは、見ているブラウザの言語に合わせて変換されるので、このマクロ展開機能は便利だと思います。

マクロ展開機能の実装
では、実装方法をちょっとだけ見ておきます。まずこのブログに書きましたが、
このブログの中で、ioManagerという構造体の話をしました。これは、C言語で標準的に定義されている FILE*と同じようなものだと書きました。
HOTPortでHTMLを生成するときは、このioManagerの中にHTMLをどんどん書いていきます。で、書いていく中で、${Lex/login}とか、${UserId}とか、${ThisHost}とかのマクロ定義された部分がたくさん入り込んでいます。で、これを、マクロ展開しながら、別のioManagerに書き込むということをします。
それには、ioManager_putIHTML()という関数を使います。
その定義は、以下のようなものです。
static  bool   ioManager_putIHTML 
(threadManager*  ThMPtr, ioManager*      This,
 hotport*        HPPtr,          element*        ElemPost,
 ioManager*   IOMPtrOut)
{ /*中身は省略*/}
まず、ioManager* This  には、生成されたHTMLが入っていて、そこにはいろいろなマクロ展開すべき部分が含まれています。それを、 element* ElemPostで定義されているマクロ変換テーブルにもとづいて、変換して、ioManager* IOMPtrOutに展開します。
そして、IOMPtrOutに入っているHTMLには、まだ<html></html>などが入っていないので、それをくっつける部分を経て、最終的にHTMLファイル全体をつくって、ブラウザに返すわけですね。

最初にマクロ展開の部分を実装したとき、こんなにいろいろな使い道があるとは思っていませんでしたが、これがあるおかげで、かなりHTML生成が楽になりました。とにかく必要な定義は、 ElemPostの中に放り込んでおけば、あとは勝手に展開して、まともなHTML を生成してくれるわけですからね。

まとめに変えて
ということで、本日二つめのブログはこれで御仕舞いです。ちょっと短いですけどね。次回は、そうだなあ、検索エンジンの話でもしましょう。CMSには絶対必要なものですし。それから、文中に別のWEBページへのリンクをはるための仕組みなども畫こうと思います。

なお、ここでご紹介しているプログラムソースコードの一部、あるいは全部を必要に応じて切り出すサービスをしております。必要な方はお申し付けくださいませ。


サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す