localdisk

PHP とか Java とか Web とか好きなことを書きます。

テンプレートエンジン Smoochy を公開します

Twitter で再三「リリースするよ」とか言っておきながら全然出来ていませんでしたが、せっかくのクリスマスなので、公開してみることにしました。コードがかなり汚いですが、一応意図通り動いてますので。お正月とかにドキュメント書いたりリファクタリングするつもりです。
名前は Smoochy(すむーちー) です。由来は作ってる時によく聴いていた坂本龍一のアルバム名から。
以下説明。

はじめに

Smoochyとは?

Smoochy は PHP で作られたテンプレートエンジンです。Smoochy は Pure HTML をテンプレートとして使用するため、本当の意味で「デザインとロジックの分離」を実現しています。
独自タグや独自属性、ましてや {$hogehoge} のようなマークアップも必要ありません。

インストール

  1. bitbucket.org より Smoochy.zip をダウンロードします。
  2. zipファイルを解凍し、Smoochy ディレクトリを include_path に含まれている場所に設置して下さい。

簡単な使い方

サンプル HTML(hello.html)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title id="title"></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
      <h1 id="h1">Hello World.</h1>
  </body>
</html>

サンプル PHP(hello.php)

<?php
require_once 'Smoochy/Smoochy.php';
require_once 'Smoochy/Page.php';
class Hello extends Page {
    public function title() {
        $this->_query->text('Hello Smoochy!');
    }
    public function h1() {
        $this->_query->text('Hi! Smoochy!');
    }
}
$smoochy = new Smoochy();
$page = new Hello();
$smoochy->rendar($page);

処理結果

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title id="title">Hello Smoochy!</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
      <h1 id="h1">Hi! Smoochy!</h1>
  </body>
</html>

結果を見るとご覧通り、title 要素と h1 要素の中身が変更されているのがわかると思います。
この、仕組の肝は

  1. Page クラスを継承したクラスを作成する。
  2. そのクラスに変更したい要素の id 属性名で function を作成する。
  3. _query オブジェクトの text メソッドで要素の中身を変更する。

です。他にも、属性を変更する attr/removeAttr メソッド、class 属性を変更する addClass/removeClass/toggleClass、該当要素に html を追加する html メソッド、ノードを追加する append メソッド、form 関連要素の value 属性の値を操作する val メソッド、繰り返し処理に使用する loop メソッドなどを用意しています。
メソッド名を見てピンときた方もいらっしゃると思いますが、メソッド名は jQuery からいただいています。そして Smoochy も jQuery のようにメソッドチェインを使用することができます。

<?php
$this->_query->attr('title', 'foo')->addClass('bar')->text('hoge');

ちょっと特殊な処理1(繰り返し処理)

繰り返し処理はちょっと特殊です。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>foreach</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p id="loop" title="message">foreach test</p>
  </body>
</html>

上記 HTML の p 要素が繰り返し処理対象です。 title 属性が与えられていることにお気づきでしょうか? title 属性が Smoochy での繰り返し処理での肝です。

<?php
class Hello extends Page {
    public function loop() {
        $arr = array();
        for ($i = 0; $i < 5; $i++) {
            $clazz = new stdClass();
            $clazz->message = $i;
            $arr[] = $clazz;
        }
        $this->_query->loop($arr);
    }
}

for ループの中で stdClass を作成し、 message というプロパティにループカウンタの値を代入しています。この message というプロパティと、繰り返し処理の title 属性の値が同じ場合繰り返し処理の対象要素となります。
以下が結果のHTMLです。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>foreach</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p title="message">0</p>
    <p title="message">1</p>
    <p title="message">2</p>
    <p title="message">3</p>
    <p title="message">4</p>
  </body>
</html>

p 要素から id 属性が消えていますね。 id 属性の値は HTML ファイル内でユニークにしなければならないため、Smoochy が消去しています。
これが基本の繰り返し処理です。もちろん table にも適用することができます。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>foreach</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
      <table>
          <tbody>
              <tr id="loop">
                  <td title="message1"></td>
              </tr>
          </tbody>
      </table>
  </body>
</html>

ループ対象の要素に id 属性を与えて、テキストを追加したい要素に title 属性を与えます。PHP コードは先ほどのサンプルがそのまましようできます。

ちょっと特殊な処理2(レイアウトの継承)

Web サイトを作成する場合、同様のレイアウトのページが多く存在することと思います。そのため Smoochy にはレイアウト継承処理を実装しました。
レイアウトの継承は簡単です。継承したい Page クラスを継承すれば終了です。

<?php
class Base extends Page {
    // 色々な処理…
}
class Foo extends Base {
}

このように継承すれば Base で定義された function は Foo クラスでもコールされます。
他にもあったりしますが、力尽きたのでまたの機会に…。

これから実装予定の処理

  • 他の HTML ファイルの import
  • 携帯対応
    • Shift_JIS で出力したり
    • キャリア毎の絵文字とか
    • DOCTYPEの自動切り替えとか
  • Ajax Helper
  • クライアントサイド Validation
  • 高速化(処理の最適化とか中間ファイルを作ったりとか?)