ラベル CMS の投稿を表示しています。 すべての投稿を表示
ラベル CMS の投稿を表示しています。 すべての投稿を表示

2010年7月20日火曜日

Twigでテンプレート側からAppを起動

現在、当方では、PHPのテンプレートクラスであるTwigの

可能性を追求しているところです。



今回は、テーマファイルからAppを呼び出す仕組みを開発してみました。



通常のWEBアプリでは、まずAppを呼び出して処理した後に

Appでの実行結果をテーマに書き出すような処理順序になると思います。



今回、この処理順序をちょっと変えて、

テーマファイルに「app=blog fct=EntryView id=3」のように書いておけば

該当箇所にAppの実行結果が自動的に表示されるようにしてみました。

※イメージ的には、SoyCMSでやってるようなことです。
 SoyCMSでは独自テンプレートエンジンでやってると思いますが、
 当方では今回これをTwigという有名なテンプレートエンジン上で
 やってみている、というワケです。



以下、実装クラスのソースコードを晒しておきますので、

ご参考いただければ幸いです。



Extensionクラス

当該クラスで、TokenParserを定義します。(c.f. getTokenParsers())
<?php
/**
* Twig_Extension_Sample
* @author spark43
*
*/
class Twig_Extension_Sample extends Twig_Extension
{
    /**
     * (non-PHPdoc)
     * @see v0.02/Sample/_opt/Twig/Twig_Extension::getTokenParsers()
     */
    public function getTokenParsers()
    {
        return array(
            new Twig_TokenParser_Sample(),
        );
    }


    /**
     * (non-PHPdoc)
     * @see v0.01/Sample/_opt/Twig/Twig_Extension::getFilters()
     */
    public function getFilters()
    {
        return array(
            'nl2br' => new Twig_Filter_Method($this, 'nl2br'),
        );
    }

    /**
     * (non-PHPdoc)
     * @see v0.01/Sample/_opt/Twig/Twig_ExtensionInterface::getName()
     */
    public function getName()
    {
        return 'aither';
    }

    /**
     * nl2br
     * @param $string
     */
    public function nl2br($string)
    {
        return str_replace("\n", "<br />", Twig_Filter_Method);
    }
}

?>




TokenParserクラス

当該クラスでテーマに書かれた構文をトークンに解析します。
使用するフレームワークの構文に合わせることが必要です。
※オープンソースCMSなどに見られる場合があるのですが、
 使用モジュールごとにそれぞれ独自なフレームワークを使っている場合、
 該当フレームワークごとに必要となる場合もあるかと思います。
<?php
/**
* Twig_TokenParser_Sample
* @author spark43
*
*/
class Twig_TokenParser_Sample extends Twig_TokenParser
{
    /**
     * (non-PHPdoc)
     * @see v0.02/Sample/_opt/Twig/Twig_TokenParserInterface::parse()
     */
    public function parse(Twig_Token $token)
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();
        $exp = $this->parser->getExpressionParser();


        // parse
        $request = array();
        $param = array();
        while($stream->test(Twig_Token::NAME_TYPE)) {
            $expk = $exp->parseExpression();
            $stream->expect(Twig_Token::OPERATOR_TYPE, '=');
            $expv = $exp->parseExpression();

            switch ($expk['name']) {
                case 'app':
                case 'fct':
                case 'with':
                    if (! ($expv instanceof Twig_Node_Expression_Name)) {
                        throw new Twig_SyntaxError("'". $expk['name']. "' paameter is invalid", $lineno);
                    }
                    $request[$expk['name']] = $expv;
                    break;
                default:
                    // TODO : other expressions...?
                    if (! ($expv instanceof Twig_Node_Expression_Name)
                    && ! ($expv instanceof Twig_Node_Expression_Constant)) {
                        throw new Twig_SyntaxError("'". $expk['name']. "' paameter is invalid", $lineno);
                    }
                    $param[$expk['name']] = $expv;
                    break;
            }
        }
        $this->parser->getStream()->expect(Twig_Token::BLOCK_END_TYPE);


        // check
        if (! isset($request['app'])) {
            throw new Twig_SyntaxError("no 'app' paameter", $lineno);
        }
        if (! isset($request['fct'])) {
            throw new Twig_SyntaxError("no 'fct' paameter", $lineno);
        }
        if (! isset($request['with'])) {
            throw new Twig_SyntaxError("no 'with' paameter", $lineno);
        }


        // return
        return new Twig_Node_Sample(new Twig_Node($param), new Twig_Node($request), $lineno, $this->getTag());
    }


    /**
     * (non-PHPdoc)
     * @see v0.02/Sample/_opt/Twig/Twig_TokenParserInterface::getTag()
     */
    public function getTag()
    {
        // using tag name
        return 'aither';
    }
}
?>





Nodeクラス

当該クラスでトークンをコンパイルします。
TokenParserクラスと同様に、
使用するフレームワークとの整合性に
十分に配慮する必要があります。

<?php
/**
* Twig_Node_Sample
* @author spark43
*
*/
class Twig_Node_Sample extends Twig_Node
{
    /**
     * __construct
     * @param $name
     * @param $value
     * @param $lineno
     * @param $tag
     */
    public function __construct($param, $request, $lineno, $tag = null)
    {
        parent::__construct(array('param' => $param), array('request' => $request), $lineno, $tag);
    }

    /**
     * (non-PHPdoc)
     * @see v0.02/Sample/_opt/Twig/Twig_Node::compile()
     */
    public function compile($compiler)
    {
        $compiler->addDebugInfo($this);


        // prepare request (from token parser)
        $app = $this['request']->app['name'];
        $fct = $this['request']->fct['name'];
        $with = (isset($this['request']->with['name'])
                    ? $this['request']->with['name']
                    : VApp::BY_TPL);
        switch ($with) {
            case VApp::BY_OBJ:
            case VApp::BY_TPL:
                $withX = $with;
                break;
            default:
                $withX = VApp::BY_OBJ;
                break;
        }
        $compiler->write("\$req = new VRequest();\n")
                ->write("\$req->app = '". $app. "';\n")
                ->write("\$req->fct = '". $fct. "';\n")
                ->write("\$req->with = '". $withX. "';\n");

        // prepare parameters
        $param = $this->param;
        foreach ($param as $pk => $pv) {
            if ($pv instanceof Twig_Node_Expression_Name) {
                $compiler->write("\$req->". $pk. "=". $pv['name']. ";\n");
            }
            if ($pv instanceof Twig_Node_Expression_Constant) {
                $compiler->write("\$req->". $pk. "=". $pv['value']. ";\n");
            }
        }

        // execute requested app
        $compiler->write("\$vservice = new ThemeService(\$req);\n")
                ->write("\$aether_result = \$vservice->service();\n");
        switch ($withX) {
            case VApp::BY_OBJ:
                $compiler->write("\$context['". $with. "'] = \$aether_result;\n");
                break;
            case VApp::BY_TPL:
                $compiler->write("echo \$aether_result;\n");
                break;
        }
    }

}
?>




Twigでタグを作成する場合、それも特にNodeクラスを作成する場合には、

キャッシュしておくとcompile結果がキャッシュ・ファイルに出力されるので

compile結果がPHPとして正しく動作するか、

組み込むフレームワークとの連動が正しく行われるか、

実行結果がただしく画面表示されるか、

というようにソースコードのレベルでチェックできると思います。



このように、独自でタグを作成する場合には、

詳述しませんが、

 ・Tokenクラス

 ・TokenStreamクラス

 ・Nodeクラス

 ・Node/Expression/以下の、NodeExpressionクラス

などのソースを熟読することをお勧めしておきます。

2010年4月20日火曜日

SoyCMS

SoyCMSの内部は、SOY2フレームワークという

自作のフレームワークで動かしているそうです。

いま、ここで解説されてます。



その中で、次の点は、個人的には特に白眉だと思いました。

SOY CMSで採用したパターンは
  1. V:リクエストからどのVを表示するか自動的に決定
    C:Vの中で必要に応じてロジックを呼び出す
  2. V:表示
のようにView内部に全ての処理を行うパターンです。




個人的には、これからこういう方向に進むのではないかと思っていたので、

それを既にしっかり形にしてウリにしてる点で、「先駆者」と感じています。

2010年3月14日日曜日

OSC神戸 ~Magento聞いてきました~

久し振りに、本当に久し振りに、神戸に行ってきまして、

OSC神戸で、magentoの話を聞いてきました。

オープンソースのECサイト構築向けCMS。


=================================================
1.機能
=================================================
☆マルチサイト対応

☆多言語(通貨も含めて)

☆BTO,ダウンロード販売,ドロップシッピング対応

などなど、非常に豊富な機能が最初から標準であり、

さらに、2,000とも3,000とも言われるプラグインを

導入することで、さらに色々できる。


=================================================
2.有償/無償
=================================================
有償のエンタープライズ版と

無償のコミュニティ版がある。

が、メインの開発者たちは、もうあまり無償版には

口や手を入れていない、らしい。


=================================================
3.デザイン変更
=================================================
デザインを柔軟に変更できるように、

「レイアウトXML」ファイルでデザイン配備を設定。

ただ、記述内容にmethod="$this->setCategoryName()"

といったように、Blockオブジェンクトのpublicな

メソッドを思い切り書くようなことができるため、

デザイナがレイアウト変更するのは、至難の業で

あろうことが容易に読み取れる。

※実際、デザイナと協業する場合には、
 デザイナ=css,js,画像の変更を担当
 プログラマ=レイアウト変更,PGカスタマイズなど
 のように進めるらしい。。。

※って言うか、そもそも、テンプレートは
 header(); ?>的な、
 いわゆるPHPテンプレートらしい。。。orz
 逆に、だからこそ柔軟に変更できるんだろう
 とは思いつつ。。。ブロックの中に別の
 ブロックを入れることとか出来るらしい。


=================================================
4.処理速度
=================================================
スゲー重いらしい。

共用レンタルサーバーとかだと遅すぎて

使えないんじゃないかって話すら。。。



・・・いずれにせよ、経験者の話というのは、

非常に有用だと改めて感じました。



magentoに対して期待が大きかっただけに、

話聞き終わってから、やっぱりそうかと思いつつ、

でも、でも、やっぱり落胆も大きく・・・。orz

2010年1月25日月曜日

改めて・・・

年も改まって早一ヶ月が経とうとしています。



改めて、当方が展開したい事業の方向のひとつを書いてみますと、

【システム開発による作業効率化のお手伝い】

というのがあります。(2010年1月現在)



今まで数日かかっていた作業が1分で終わったりすると

やはりインパクトがあります。

数日かかることを前提にした作業の進め方と

1分で終わることを前提にした作業の進め方は

当然変わってくるものです。

作業のリズムというようなものが変わり、

今まで間延びしていたようなリズムで進んでいたものが、

テンポよくピッチの速いリズムで進むようになるものです。



やがて、その作業を1分で終わらせることが当たり前に

なった頃、私の仕事は完了なんだろうと思っています。



そして、それは、お客様の苦手な分野であればあるほど、

インパクトを持っていると思います。



WEBの分野は、まだまだ未開拓な部分も多く、

技術基盤自体が日進月歩しているような状態です。

今のような変化を求められている時代に、

こういった発展途上なものを自分の仕事に

使わざるを得ないお客様にとって、

WEBというのは、まだまだ、もっと便利になる

可能性を秘めていると、私は思っています。



その一例がCMSと呼ばれるシステムです。

CMS 【コンテンツマネジメントシステム】
CMSとは、Webコンテンツを構成するテキストや画像、レイアウト情報などを一元的に保存・管理し、サイトを構築したり編集したりするソフトウェアのこと。広義には、デジタルコンテンツの管理を行なうシステムの総称。
Webサイトを構築するには、テキストや画像を作成するだけでなく、HTMLやCSSなどの言語でレイアウトや装飾を行ない、ページ間にハイパーリンクを設定するなどの作業も行なう必要がある。これらの要素を分離してデータベースに保存し、サイト構築をソフトウェアで自動的に行なうようにしたものがCMSである。
(以上、e-wordsより転載)

専門知識とか無くても、WEBの更新や管理を簡単に行えるようになる、

ということです。



現在、CMSは、無料(オープンソース)のものから、有料なものまで、

とてもたくさんの種類の製品が世の中に出回っていて、

どれを選べばよいのか困るほどです。

新しいものが生まれては消えていったりすることもありますので、

迂闊に手を出すのは躊躇われます。



その中で、当方は、Xoops(ズープス)という製品を推しています。

これは、オープンソースのライセンスで開発が行われている、

無料のCMSです。



無料ですので、手取り足取り教えてくれることはありませんが、

オープンソースだし、日本でも長い間使われてきたので、

WEBで検索すれば、知りたい情報をたくさん得ることができます。



昨年くらいから、各種CMSの使われ方を探るべく、裏で情報を

取っていたのですが、Xoopsはまだ人気があるようです。

色々なCMSを横に並べて眺めていると分かるのですが、

イノベーション採用者カテゴリが必ずしも

分かりやすくキレイには当てはまりにくく、

最初の内は、イノベータ・初期採用者・初期多数者が

渾然となって、使い始めているようなところがあります。

 ・システム開発を生業とするような人たちが使う
  ⇒「こんなシステム開発技術を使っているらしい」
  ⇒「導入してみた」
  ⇒「機能の一部をネチネチと使ってみた」
  ⇒「デザインをこのように改造した」
  ⇒「機能の一部をこのように改造した」
  ⇒「機能の一部をこのように新しく作った」

 ・ビジネスに目を光らせている人の中で
  割とシステムに明るい方々が使う
  ⇒「こんな機能やあんな機能がビジネスで使える」
  ⇒「導入してみた」
  ⇒「機能の一部をネチネチと使ってみた」
  ⇒「デザインをこのように改造した」

 ・一般の新しいものがお好きな方々が使う
  ⇒「こんな機能やあんな機能が面白そう」
  ⇒「導入してみた」
  ⇒「機能の一部をネチネチと使ってみた」
  ⇒「デザインをこのように改造した」

それが、やがて、後期多数派やラガートへと伝播されていきます。

 ・フツーの人たちが使う
  ⇒「こんな機能やあんな機能があるらしい」
  ⇒「導入してみた」
  ⇒「機能の一部をネチネチと使ってみた」

いま、新しく出てきているCMSは、まだまだ前者のレベルにあって

その普及に腐心しているようなところが見受けられますが、

Xoopsは、既に、すっかり後者の領域に入っているようです。

導入事例も星の数ほど豊富にあります。

つまづくポイントとその対策も、もう出尽くしている感すらあります。



・・・と、ここまで説明して、改めて、

当方の事業の方向の一つを書いてみると、

【CMSによるサイト構築のお手伝いと
 CMS利用による効率的なサイト運営のお手伝い】


ということになろうかと思います。



今年は、この辺りをもう少し深く踏み込んで

事業展開していけたら、と考えています。



今年も宜しくお願いします。

2009年11月14日土曜日

自前で動画共有サイトを立ち上げられるCMS

自分にとっての研究課題として、覚書しておきます。

いつか時間が出来たら研究してみたいです。

PHPmotion