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

2010年6月24日木曜日

Xoops(Cube)でtabパネル


あまり重要でないけど表示したいといったコンテンツをタブでまとめたり、
派生項目がたくさんあるようなコンテンツをタブで分散したり、
というようなことは、アプリケーションではよくありますよね。

今回、jQueryを使ってXoops(Cube)でタブを実現する方法について、
少し試してみましたので、以下で説明します。



■0.今回の前提

(1)「jQueryを使ったタブ」のサンプルとして、こちらのサンプルを参照します。
(2)Xoops画面に配置した幾つかのブロックをタブにまとめることを目標とする


■1.そもそもjavascriptって、どうやって取り込むの?

jQueryは、要するに、javascriptです。

フツーのHTMLの場合、javascriptを取り込むには、
<head>~</head>で囲まれた部分に、
   <script type="text/javascript">
    alert("こんにちは!");
   </script>
のように書いたり、
   <script type="text/javascript" src="hogehoge.js"></script>
のように書いたりします。
※<body>~</body>で囲まれた部分に書くことも出来ますが、
 可読性や保守性を考慮して、出来るだけ避けたほうが良いようです。

Xoops(Cube)でjqueryのようなJavascriptを取り込む場合も同じです。

ただ、Xoops(Cube)の場合、~.htmlがアチコチにあるようなイメージがあります。
どのhtmlをイジればよいのか判断するためには、予備知識が必要になりますので、
次節で説明します。



■2.そもそも何をイジればよいのか ※Xoops(Cube)の画面について

「幾つかのブロックをタブにまとめる」のようなことをする場合、
そもそも、どのファイルをイジればよいのか、分かるでしょうか?
それを理解するためには、Xoops(Cube)の画面描画について
理解することが必要です。

奥深く見ていけばキリがありませんが、極めてザックリとでも
理解しておくことで、「どこを触ればいいのか」が分かるようになります。

Xoops(Cube)の画面描画は、次のような流れになっています。
    ・各モジュール・ブロックのtemplate
              ↓
    ・PHP(Smarty)で解析
              ↓
    ・PHP変数($xoops_lblockとか)に格納
              ↓
    ・テーマのtemplateにPHP変数をセット
              ↓
    ・テーマのtemplateをPHP(Smarty)で解析
              ↓
    ・Xoops(Cube)の画面として描画

つまり、テーマという大枠のhtmlの中に、
各モジュールやブロックが自動的に組み込まれていきます。
※自動的に組み込まれていく流れが、上記の流れになります。

そもそも、htmlファイルの中に<head>~</head>が現れる部分は
テーマにしかありません。


従って、今回イジるのは、テーマのhtmlファイルということになるワケです。



■3.そもそもタブって、どうやってるの?

これは、Xoopsの話ではなく、htmlとかjavascriptの話になります。
※一般的にタブでやってることをXoops(Cube)にも適用するだけの話、
 ということです。

ここで、最初のほうで挙げたサンプルを参照してみます。

まず、タブに表示するデータはすべて、<ul>でHTMLに書いてあります。
<div id="container">
    <ul class="tab">
        <li><ahref="#tab1"class="selected">JavaScript</a></li>
        <li><ahref="#tab2">CSS</a></li>
        <li><ahref="#tab3">HTML</a></li>
        <li><ahref="#tab4">jQuery</a></li>
        <li><ahref="#tab5">XHTML</a></li>
    </ul>
    <ul class="panel">
        <li id="tab1">aaa<li>
        <li id="tab2">bbb<li>
        <li id="tab3">ccc<li>
        <li id="tab4">ddd<li>
        <li id="tab5">eee<li>
    </ul>
</div>
タブのラベルに表示する文字はclass="tab"のulに、
タブの内容として表示するデータはclass="panel"のulに
それぞれ書かれているのが分かります。

このHTMLに対して、javascript(jQuery)で
panelでは現在選択されているタブの内容だけ表示する
ように制御しています。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> //・・・(A)
<script type="text/javascript">
$(function(){ //・・・(B)
    $("ul.panel li:not("+$("ul.tab li a.selected").attr("href")+")").hide();
    $("ul.tab li a").click(function(){
        $("ul.tab li a").removeClass("selected");
        $(this).addClass("selected");
        $("ul.panel li").slideUp("fast");
        $($(this).attr("href")).slideDown("fast");
        return false;
    });
});
</script>
上記(A)の部分では、Google API経由でjQueryを参照しています。
また、上記(B)の関数内で、
panelでは現在選択されているタブの内容だけ表示する
ように制御しています。

ただし、少し手抜きが過ぎるようです。
つまり、panelに表示するデータとして、ulタグによるリストを表示しようとすると
該当リストが表示されなくなります。

そのため、次のように改造してやります。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> //・・・(A)
<script type="text/javascript">
$(function(){ //・・・(B)
    $("ul.panel > li:not("+$("ul.tab li a.selected").attr("href")+")").hide(); //・・・(modify 1)
    $("ul.tab li a").click(function(){
        $("ul.tab li a").removeClass("selected");
        $(this).addClass("selected");
        $("ul.panel > li").slideUp("fast"); //・・・(modify 2)
        $($(this).attr("href")).slideDown("fast");
        return false;
    });
});
</script>
分かりにくいですが、panelのliを参照する箇所を
「panel li」ではなく「panel > li」
に変更してあります。

あとは、CSSを使って、class="tab"の部分をタブらしくヨコに並べるなどします。
※display:blockにしてfloat:leftするなど、お馴染みの方法です。
 この例だと、class="panel"側でclear:bothしているようです。
 余談ですが、こういうのもCSS3だとラクが出来るそうでして、
 いわゆるclear-fix的なテクニックが不要になるらしいです。



■4.Xoops(Cube)でタブを使ってみよう

すっかり前提が長くなってしまいましたが、
ここまで、上記1.2.3.と説明してきた内容を元に
いよいよXoops(Cube)でタブを使ってみましょう。

大まかな手順は、上記3.から、
    ・「HTMLの編集」
        ↓
    ・「javascript(jQuery)の導入」
        ↓
    ・「cssで見た目を整える」

とすればよいことが分かります。

さらに、上記2.から、
「HTMLの編集」は、「テーマ(HTML)の編集」をすればよい
ことが分かりますので、Xoops(Cube)の場合、
    ・「テーマ(HTML)の編集」
        ↓
    ・「javascript(jQuery)の導入」
        ↓
    ・「cssで見た目を整える」

といった手順で、Xoops(Cube)にタブを導入してみます。



手順1:「テーマ(HTML)の編集」

今回は、LEFTブロックに配置されるブロックをすべてタブに入れてみます。
テーマ(HTML)のLEFTブロックに該当する部分について、
上記3.と同じようにするために、次のように修正します。
<div id="container">
    <ul class="tab">
<{foreach item=block from=$xoops_lblocks name=tab_title}>
        <li><a href="#tab<{$smarty.foreach.tab_title.iteration}>" <{if $smarty.foreach.tab_title.first}>class="selected"<{/if}>><{$block.title}></a></li>

<{/foreach}>
    </ul>
    <ul class="panel">
<{foreach item=block from=$xoops_lblocks name=tab_content}>
        <li id="tab<{$smarty.foreach.tab_content.iteration}>"><{$block.content}></li>
<{/foreach}>
    </ul>
</div>




手順2:「javascript(jQuery)の導入」

上記1.で説明したように、<head>~</head>で囲まれた箇所に
javascript(jQuery)を導入するための記述を追加します。
追加する内容は、上記3.で説明したjavascriptをそのまま転記すれば大丈夫です。
転記する場所は、テーマ(HTML)の<head>~</head>で囲まれた箇所の
最後にでも書いておけば大丈夫です。
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
    $("ul.panel > li:not("+$("ul.tab li a.selected").attr("href")+")").hide();
    $("ul.tab li a").click(function(){
        $("ul.tab li a").removeClass("selected");
        $(this).addClass("selected");
        $("ul.panel > li").slideUp("fast");
        $($(this).attr("href")).slideDown("fast");
        return false;
    });
});
</script>




手順3:「cssで見た目を整える」

上記3.でも触れたように、タブをタブらしく見せるなど、
cssで見た目を整えてあげましょう。

リストをヨコに並べるには、「float:left;」を使うのが定番みたいです。
「float:left;」だとそれを解除するコードが必要になりますが、
この辺りのテクニックは「clear-fix」で検索すればたくさん見つかります。

タブの背景画像をオンラインで作ってくれるサービスなんかも
検索すればたくさん見つかります。

デザインを頑張るのは、割と楽しいです。(仕事でなければ・・・)
どうか頑張ってデザインしてみてください。




・・・長くなりましたが、以上で説明は終わりですが
どうだったでしょうか?

結局、長々と説明した割りには、Xoops(Cube)に特化した部分は
ほとんど出てきませんでした。

実は、Xoops(Cube)だからって、何か特別なことをしなければ
いけないということはありません。

でも、Xoops(Cube)って難しいと思われがちで、敬遠されがちなので、
こういったエントリを書いてみました。


皆様の何かのご参考になれば、幸いです。

2010年1月9日土曜日

XDebug

長らく、PHPプログラムのテストは

Zend Debuggerでやってましたが、

今日、諸事情により、XDebugに乗り換えました。

個人的に、一番参考になったのは、

日本語サイトじゃなくて、英語サイトでした。

Getting Xdebug to work with Apache/XAMPP to debug PHP



Zend Debuggerだと、XoopsCubeのテストしてるとき

管理画面に遷移したらコケる率が異様に高かったのでした。

XDebugはまだやっとセットアップと動作確認が終わった程度ですが、

今のところ、管理画面に遷移してもコケてないです。

期待大、です。



・・・えええっと、がんばります。

2009年9月30日水曜日

XCでlog4phpを使う

XoopsCubeで開発していると、デバッグログの貧弱さにウンザリすることがありました。

そこで、log4phpをXoopsCubeのpreloadでセットアップできるようにしてみました。

とは言え、まだ当方のローカルな開発環境のみで使用しています。

これを近日中に公式サイトからダウンロード可能にする予定です。

※モジュール開発者用です。

※XOOPS_TRUST_PATH必須です。



仕組み自体は単純で、log4phpの設定ファイルをpreFilterで動的に生成しつつ、

getLogger()してdebug()したりinfo()したりするというようなものです。

まあ、誰でも簡単に作れると思いますが、誰も公開してないみたいなので。

2009年9月14日月曜日

XoopsでSSLログイン

【参考】Xoops Users Group Japan - XCLBasicManual/SSLログイン [SSLログインの流れと動作原理] - XUGJ Wiki


基本的に、上記リンクの記事を参考にすれば、誰でも出来ると思います。

以下、別に意味はありませんが、上記リンクの記事の内容をを私の言葉で
書き写しただけの文章を書いてみます。


  1. 【ローカルPC】「Package_Legacy/extras/login.php」の先頭の辺りの$path='';の部分を自サイト用に書き直し

  2. 【ローカルPC→サーバ】「Package_Legacy/extras/login.php」を自サイトの公開側パスにFTPアップロード

  3. 【ローカルPC→サーバ】上記リンクの記事に添付されている「SSLLogin.class.php」を有難く頂戴し(普通はここで御礼をお伝えするのでしょうね、私はサッサとダウンロードして使っておりましたが。。ゴメンナサイ。。。)、自サイトの公開側パス/modules/user/preload/直下にFTPアップロード

  4. 【XoopsCube管理画面】「ユーザモジュール」⇒「一般設定」で表示される画面の最下部付近にSSLに関する設定があるので、それを設定する(※1)



ここまですれば、少なくとも(※1)で設定したURLにアクセスすればSSLログインが可能になりました。(spark43の公式サイトではできました。)

ただ、普通にhttp://hogehoge.url/user.phpでログインする分には、
SSLにはなりません。(当然)

これをSSLにするには・・・やったことありませんが、きっと・・・・
有名な「どこでもSSL」というモジュール?(or ハック?)を適用するのが
いいんだろうと推測しています。

また、ヒマを見つけてやってみようと思います。

2009年8月14日金曜日

spark43オフィシャルサイトのRSS

文字化けしてました。。。

恐らく環境の問題な気もしますが、
ソース修正で乗り切ることにしました。(汗


XOOPS_ROOT_PATH/modules/legacy/actions/BackendAction.class.php
を書き換えました。


/**
*
* @package Legacy
* @version $Id: BackendAction.class.php,v 1.4 2008/09/25 14:31:58 kilica Exp $
* @copyright Copyright 2005-2007 XOOPS Cube Project
* @license http://xoopscube.sourceforge.net/license/GPL_V2.txt GNU GENERAL PUBLIC LICENSE Version 2
*
*/

if (!defined('XOOPS_ROOT_PATH')) exit();

/***
* @internal
*/
class Legacy_BackendAction extends Legacy_Action
{
    var $mItems = array();
    
    /**
     * The spec of getRSS():
     * append your RSS item to $eventArgs array. You don't need to sanitize your values. Use raw value.
     *
     * $item['title']
     * $item['link'] ... permanent link
     * $item['guid'] ... permanent link
     * $item['pubdate'] ... unixtime
     * $item['description'] ... not required.
     * $item['category'] ... not required.
     * $item['author'] ... not required.
     *
     * @var XCube_Delegate
     */
    var $mGetRSSItems = null;
    
    function Legacy_BackendAction($flag)
    {
        parent::Legacy_Action($flag);
        
        $this->mGetRSSItems =& new XCube_Delegate();
        $this->mGetRSSItems->register('Legacy_BackendAction.GetRSSItems');
    }
    
    function getDefaultView(&$controll, &$xoopsUser)
    {
        $items = array();
        $this->mGetRSSItems->call(new XCube_Ref($items));

        $sortArr = array();
        foreach ($items as $item) {
            //shiraga (2009.08.14) ==>
            $item['title'] = mb_convert_encoding($item['title'], "EUC-JP", mb_detect_encoding($item['title']));
            $item['description'] = mb_convert_encoding($item['description'], "EUC-JP", mb_detect_encoding($item['description']));
            //shiraga (2009.08.14) <==
            
            $i = intval($item['pubdate']);
            for (; isset($sortArr[$i]) ; $i++);
            
            $sortArr[$i] = $item;
        }
        krsort($sortArr);
     $this->mItems = $sortArr;
        return LEGACY_FRAME_VIEW_INDEX;
    }
    
    function executeViewIndex(&$controller, &$xoopsUser, &$render)
    {
        $xoopsConfig = $controller->mRoot->mContext->mXoopsConfig;
        
        //
        // Set up the render buffer.
        //
        $renderSystem =& $controller->mRoot->getRenderSystem('Legacy_RenderSystem');
        
        $renderTarget =& $renderSystem->createRenderTarget('main');

        $renderTarget->setTemplateName("legacy_rss.html");
        
        $renderTarget->setAttribute('channel_title', $xoopsConfig['sitename']);
        $renderTarget->setAttribute('channel_link', XOOPS_URL . '/');
        $renderTarget->setAttribute('channel_desc', $xoopsConfig['slogan']);
        $renderTarget->setAttribute('channel_lastbuild', formatTimestamp(time(), 'rss'));
        $renderTarget->setAttribute('channel_webmaster', $xoopsConfig['adminmail']);
        $renderTarget->setAttribute('channel_editor', $xoopsConfig['adminmail']);
        $renderTarget->setAttribute('channel_category', 'News');
        $renderTarget->setAttribute('channel_generator', 'XOOPS Cube');
        $renderTarget->setAttribute('image_url', XOOPS_URL . '/images/logo.gif');
        
        $dimention = getimagesize(XOOPS_ROOT_PATH . '/images/logo.gif');

        $width = 0;        
        if (empty($dimention[0])) {
            $width = 88;
        }
        else {
            $width = ($dimention[0] > 144) ? 144 : $dimention[0];
        }
        
        $height = 0;
        if (empty($dimention[1])) {
            $height = 31;
        } else {
            $height = ($dimention[1] > 400) ? 400 : $dimention[1];
        }
        
        $renderTarget->setAttribute('image_width', $width);
        $renderTarget->setAttribute('image_height', $height);
        $renderTarget->setAttribute('items', $this->mItems);

        //
        // Rendering
        //
        $renderSystem->render($renderTarget);
        
//shiraga (2009.08.14) ==>
//        if (function_exists('mb_http_output')) {
//            mb_http_output('pass');
//        }
//shiraga (2009.08.14) <==
        header ('Content-Type:text/xml; charset=utf-8');
        
//shiraga (2009.08.14) ==>
//        print xoops_utf8_encode($renderTarget->getResult());
        print mb_convert_encoding($renderTarget->getResult(), "UTF-8", "EUC-JP");
//shiraga (2009.08.14) <==
        
        exit(0);
    }
}

2009年7月9日木曜日

コードジェネレータと云ふもの

いま、XoopsCube向けのコードジェネレータを
PHPで作成しています。(間隙を見つけて。)

一番うっとうしいのは、DBテーブルの各フィールドを
意識しなければいけない箇所です。

フレームワークがあっても、DBのフィールドを
まったく意識しないでコーディングすることは
余程ショボいアプリでない限りは、
有り得ないと思います。

現在、ADOdbを使って、DBのメタ情報を取得して
DBの各フィールドに関するコード部分を
ジェネレートするよう開発しているところです。

今回の開発で一番の難所だと思われます。

別に仕事というより、ただの自社開発なので
タイムリミットに追いまくられることがないだけ
気楽ではありますが、いま開発しているものを
今後の開発で大いに活かしていくつもりなので
気が張る開発になっています。

CMSというものをより深く知る機会にもなっていて
大変勉強になっています。

CMSに関連した開発をされている方は、
コードジェネレータを一度作ってみては
いかがでしょうか?

かなり、おススメです。

2009年5月28日木曜日

XCのセッション管理

XoopsCube向けモジュールを開発中なのですが、セッション周りで少しハマってしまいました。


【やろうとしていたこと】


wizardっぽい画面(群)を作成するため、それら全てのデータを包括できるようなActionFormクラスを定義しておき、インスタンスをセッションに持っておいてwizardの各画面で入力された値をActionFormに格納するような構造を考えました。


【そういうときフツーは・・・】


こういうとき、つまりPHPでクラス(インスタンス)をセッションに保持する場合には、自分でserializeして$_SESSIONに格納するようプログラムを書きます。


【しかし、こんな現象が・・・】


なので、今回もそのようにしたのですが・・そうすると何故か、セッションに格納した他の変数が欠落して取得できなくなってしまい、プログラムが正常に動作しなくなりました。

欠落したのは、一番最後にセッションに格納されるデータ=画面formに埋め込むtokenです。


【調査開始】


今回、firefoxで確認していたので、firefoxで「セッションが保存されない」と来ればローカルに保存されたクッキーが何かの拍子に破壊されたとかそういうのが考えられます。そのため、真っ先にクッキーを一度削除してからfirefox再起動による再作成を行いましたが、現象は変わりません。。。
※この辺りで、正直、頭を抱えてしまいました。


【さらに詳しく調査】


XoopsCubeでは、セッションに格納したデータはDBテーブルに書き出されるようですので、該当テーブルを参照にいくと、最後にセッションに格納したハズのデータが確かに欠落しています。DB保存した段階で既に。

該当テーブルの中でセッションデータを保持するフィールドはtext型で定義されていました。MySQLでtext型というのは最大で65535byteを格納できる、かなり大きなフィールドです。

で、今回私が格納しようとしたデータをみると、クラス自体がかなり入り組んだ構造になっているため、そのまんまシリアライズ化すると、入れ子入れ子の連続で、かなり大きなサイズになっているだろうことが容易に予測されました。


【このように対策しました】


ActionFormをそのまんまシリアライズするのをやめて、各フィールドの値だけを配列に抜き出してきて、それをセッションに格納するようにプログラムを修正したところ、たちどころに、見事に、解決してしまいました。(めでたしめでたし?)


【少し考え事。。。】


どう考えてもActionFormをそのままセッションに持てたほうがプログラム的にはスッキリするとは思うのですが、セッションデータをDBに保存することを考えると、やはりあまり巨大なデータを格納することはできないと考えるほうが正解だろうと思うようになりました。

※そもそも何故セッションデータをDBに保存するのかについては、ネットで調べれば、参考になる情報が実にたくさん見つかります。

今までオレオレ・プログラムを書いたりするときには、ついついセッションを安易にファイルに格納するようにばかりしていたため、思わぬところで先入観に縛られてしまっていました。

反省しきりです。。。

2009年5月16日土曜日

XoopsCubeLegacy

OSC2009島根 - なぜ私たちは Ruby版 XOOPS を開発したか


http://www.ustream.tv/recorded/1513813


時限コンテンツだとは思いますが、
Xoops Cube Legacy2.2の紹介や、
Xoopsの並列化の試みなど、
興味深い話が聞けます。

個人的には、面白かったです。すごく。