OpenPNEガジェットは、オリジナルなSNSを作成するのを助ける
OpenPNE2系までにはなかった、概念のひとつです。

OpenPNEガジェットとは

実際にスクリーンショットで説明します。
SNSのホーム画面や、プロフィール画面では利用者にとって情報が表示される重要なページです。
ss

例えば、上のように「日記一覧」(網掛け部)、「フレンドリスト」「インフォメーション欄」などは「ガジェット」と言う単位で管理されています。

次に、管理画面を見てみましょう。
管理画面から、デザイン設定→ガジェット設定を選択すると、様々なガジェットが列挙されています。
ss2

各ガジェットは、ドラッグにより縦方向に並べ替えることができます。ガジェットを組み合わせることにより、SNS管理者は、よりオリジナルなSNSを簡単に作り上げることができます。

OpenPNEガジェットの種類

OpenPNE3.4では以下の種類のガジェットが存在します。

  • ホーム画面ガジェット(gadget)
  • プロフィール画面ガジェット(profile_gadget)
  • ログイン画面ガジェット(login_gadget)
  • サイドバナーガジェット(side_banner_gadget)
  • 携帯版ホーム画面ガジェット(mobile_gadget)
  • 携帯版プロフィール画面ガジェット(mobile_profile_gadget)
  • 携帯版ログイン画面ガジェット(mobile_login_gadget)
  • 携帯版ヘッダーガジェット(mobile_header_gadget)
  • 携帯版フッターガジェット(mobile_footer_gadget)
  • デイリーニュース(PCメールアドレス向け)ガジェット(daily_news_gadget)
  • デイリーニュース(携帯メールアドレス向け)ガジェット(mobile_daily_news_gadget)

上記で青で示したものは、ログアウトしている状態でも表示されるものになります。例えば、OpenPNE本体でサイドバナーとして定義されているものには「言語切替ガジェット」があります。
また、デイリーニュースガジェットはデイリーニュース本文の一部として利用するためのガジェットです。

OpenPNEガジェット作る

opVotePluginでは、ホームに「新規投票一覧」を表示するガジェットを作ります。

まず、ガジェットの正体を理解しましょう。ガジェットの正体はズバリ、symfonyのコンポーネントそのものです。ガジェットの使用することのできる画面では、使用するガジェットのコンポーネント名を管理画面で設定した順序で取得し、include_component()でコンポーネントとしてレンダリングするという処理を行っています。

つまり、ひとまずガジェットを作成するには、まずコンポーネントを作ればいいわけです。
symfonyのコンポーネントを復習したいかたはこちらへ
Practical symfony – 19日目: 国際化とローカライゼーション

ここでもやはり、後々問題になる携帯電話での対応を簡素化するために、コンポーネントを1つにまとめるという手法をとります。

plugins/opVotePlugin/lib/actions/opVotePluginVoteComponents.class.php

<?php

class opVotePluginVoteComponents extends sfComponents
{
  public function executeQuestionListBox(sfWebRequest $request)
  {
    $this->pager = Doctrine::getTable('VoteQuestion')->getListPager($request->getParameter('page'), 5); 
  }
}

嬉しいことに、前半部で頑張ったメソッドを再利用することができます。

plugins/opVotePlugin/apps/pc_frontend/modules/vote/actions/components.class.php

<?php

class voteComponents extends opVotePluginVoteComponents
{
}

ここは継承だけですむので、クラスを宣言するだけです。

次に、このアクションに対応するテンプレートを作成します。
コンポーネントのためテンプレートスクリプト名は_questionListBox.php となります。
plugins/opVotePlugin/apps/pc_frontend/modules/vote/templates/_questionListBox.php

<div id="homeRecentList_<?php echo $gadget->id ?>" class="dparts homeRecentList">
<div class="parts">
<div class="partsHeading"><h3>最新の投票</h3></div>
<div class="block">

<ul class="articleList">
<?php foreach ($pager->getResults() as $question): ?>
<li>
<span class="date"><?php echo op_format_date($question->created_at, 'XShortDateJa'); ?></span>
<?php echo link_to(
  sprintf("%s(%d)", op_truncate($question->getTitle(), 28, '...'), count($question->getVoteAnswers())), 
  '@vote_show?id='.$question->getId()
); ?> (<?php echo $question->getMember()->getName() ?>) 
</li>
<?php endforeach; ?>
</ul>

<div class="moreInfo">
<ul class="moreInfo">
<li><?php echo link_to('もっと見る', '@vote_list') ?></li>
</ul>
</div>

</div>
</div>
</div>

OpenPNEに用意されたヘルパー関数のひとつである op_truncate() を利用しています。これは長い文字列を省略するために作られたもので、第2引数に文字数(デフォルトは80文字)、第3引数に省略時にあとに付加する文字列を指定(デフォルトはなし)することができます。

次に、上記で作ったコンポーネントをガジェットとして利用するためにgadget.ymlファイルを作成します。
gadget.ymlファイルは、プラグインのconfigディレクトリに設置します。
plugins/opVotePlugin/config/gadget.yml

questionListBox:
  caption:
    ja_JP: "投票リスト"
  description:
    ja_JP: "最新の質問一覧を表示します。"
  component: [vote, questionListBox]

questionListBoxがガジェットの識別子となります。ほかのガジェットと被らないものを設定しましょう。captionとdescriptionは管理画面で利用するものです。
componentでは、上記のコンポーネントを モジュール名とアクション名 を並べた配列で指定してください。

設定ファイルを追加したので、キャッシュを削除します。

$ ./symfony cc

gadget.ymlは、マイホームのガジェットに利用するためのものですが、プロフィール画面の場合はprofile_gadget.ymlのように、上記のリストでカッコで囲んでいるものをymlファイルの名称にすることで同様に利用することができます。

設定と表示

管理画面から、デザイン設定→ガジェット設定→ホーム画面ガジェット設定 で、ガジェット追加をクリックすると、リストに今回追加したガジェットが表示されるようになっているはずです。
早速追加し、設定変更を行います。

ss

ユーザ側のホーム画面で以下のようなボックスが表示されていれば成功です!
ss4

OpenPNE本体のガジェットについて

OpenPNE標準で用意しているガジェットは、OpenPNE本体の lib/config/config に存在します。

デイリーニュースガジェットの懸念点

OpenPNE3では、ガジェットの仕組みにより従来のものとは大きく異なったデイリーニュースシステムを持っています。

以下のタスクをcronで1日1回実行するように設定することによりデイリーニュースを送ることができます。

./symfony openpne:send-daily-news

高い拡張性を持つ一方で、ごく小規模なSNSには使えそうですが、大規模なSNSになるとパフォーマンスの面(特にメモリ消費)で大きな懸念点が存在します。(OpenPNE3.4現在の問題点)

今後、リファクタリングされることが望まれる箇所でしょう。