a-blog cmsの拡張アプリを掘り起こしてみた

a-blog cms Advent Calendar 2013

この記事は、a-blog cms Advent Calendar 2013 - Adventarの13日の金曜です。

ご無沙汰しております。

かずみちさん、よくみたら aboogcms になってます!!

JSONプロバイダーを生やしてみた

ダイレクト編集の存在はさておき、RESTfulなJSON生成器とすることで、他システムとの連携や使い道が広がるかもしれません。かも。

今回はそんな .json でエントリー一覧系のデータを返してくれるAPIのようなものを、拡張アプリという仕組みを通してサンプルにしてみました。

拡張アプリって?

ご存じでしょうか。アンドキュメントの壁により合宿のひっそりとした話のネタになってるかもしれませんし、まあなんぞよくわかりませんが掘り起こしてみました。

php/AAPP 以下に所定のフォーマットに従ったphp(gist後述)を配置することで、拡張アプリ画面にアプリが表示されます。

ウロ覚えですが、これでGET/POSTモジュールの名前解決時の候補になるネームスペースが追加されて、 php/AAPP/APPNAME/GET 以下もオートローダーの対象になるとかだったような。


はいったー(∩´∀`)∩

はいったー(∩´∀`)∩


2.0かっこいいですね。コードネームはNewYorkなのだろうか...。

拡張アプリに使用したPHP

以下のgistがJSONプロバイダーのサンプルとして利用したPHPです。ほとんどパッケージに同梱されているサンプル通りです。

ACMS_APPabstract クラスであり、各メソッドもすべて abstract として定義されています。拡張アプリ側では、中身からっぽでもメソッドを実装してください。

拡張領域としては User のネームスペースも存在しますが、ここではよりポータブルに"よく使う拡張"をモジュール化する意図が強い・・・はず・・・です。

<?php
class AAPP_JSONProvider extends ACMS_APP
{
public $version = '0.1';
public $name = 'ACMS JSON Provider';
public $author = 'mu.aho';
public $desc = 'a-blog cms のデータをJSON APIとして扱うための拡張です';
/**
* インストールする前の環境チェック処理
* @return bool
*/
public function checkRequirements()
{
return true;
}
/**
* インストールするときの処理
* データベーステーブルの初期化など
* @return void
*/
public function install() { }
/**
* アンインストールするときの処理
* データベーステーブルの始末など
* @return void
*/
public function uninstall() { }
/**
* アップデートするときの処理
* @return bool
*/
public function update() { return true; }
/**
* 有効化するときの処理
* @return bool
*/
public function activate() { return true; }
/**
* 無効化するときの処理
* @return bool
*/
public function deactivate() { return true; }
}
<?php
class AAPP_JSONProvider_GET_Entries extends ACMS_GET
{
var $_axis = array(
'bid' => 'self',
'cid' => 'self',
);
function get()
{
$DB = DB::singleton(dsn());
$SQL = SQL::newSelect('entry');
$limit = !!LIMIT ? LIMIT : 10;
$page = !!PAGE ? PAGE : 1;
if ( $uid = intval($this->uid) ) {
$SQL->addWhereOpr('entry_user_id', $uid);
}
if ( empty($this->cid) and null !== $this->cid ) {
$SQL->addWhereOpr('entry_category_id', null);
}
if ( !empty($this->eid) ) {
$SQL->addWhereOpr('entry_id', $this->eid);
}
ACMS_Filter::entrySession($SQL);
ACMS_Filter::entrySpan($SQL, $this->start, $this->end);
if ( !empty($this->tags) ) {
ACMS_Filter::entryTag($SQL, $this->tags);
}
if ( !empty($this->keyword) ) {
ACMS_Filter::entryKeyword($SQL, $this->keyword);
}
if ( !empty($this->Field) ) {
ACMS_Filter::entryField($SQL, $this->Field);
}
$Amount = new SQL_Select($SQL);
$Amount->setSelect('*', 'entry_amount', null, 'count');
if ( !$itemsAmount = intval($DB->query($Amount->get(dsn()), 'one')) ) {
return json_encode(array('entries' => array()));
}
ACMS_Filter::entryOrder($SQL, $this->order, $this->uid, $this->cid);
$from = ($page - 1) * $limit;
$limit = ((($from + $limit) > $itemsAmount) ? ($itemsAmount - $from) : $limit);
if ( 1 > $limit ) return '';
$SQL->setLimit($limit, ($from));
$q = $SQL->get(dsn());
$rows = $DB->query($q, 'all');
return json_encode(array('entries' => array_map(function($row) {
$row['entry_url'] = acmsLink(array(
'bid' => $row['entry_blog_id'],
'cid' => $row['entry_category_id'],
'eid' => $row['entry_id']
), false);
return $row;
}, $rows)));
}
}
%{callback}(<!-- BEGIN_MODULE Entries --><!-- END_MODULE Entries -->)

一番下のはjsonのサンプルです。これを例えば、使っているテーマディレクトリ内の api/entry.json として保存すると、http://example.com/api/entry.json?callback=JSON_CALLBACK のようにリクエストすればJSONPとして利用できます。

%{callback} のくだりは、GETパラメータのグローバル変数利用を使ってるだけですね。

ここで利用しているGETモジュール(サンプル2段目)は、Entry_Summaryの公開ソースをベースにいらないものを消して、json_encode しただけなので割愛します。

コンテンツストレージとしてのCMS

やや斜め方向の話になりますが、普段からa-blog cmsを使い慣れているプログラマの方でしたら、管理ページつきのデータプロバイダーとしてa-blog cmsを使い回すのは面白いかもしれません。

ライトライセンスを見る限り、商用利用も可能でモジュールIDとルール、あとカスタムフィールドあたりを使うことができれば、一般的なAPIっぽいものを作るのは容易なはずです。

もちろん、普通にWebサイトとして運用中のところで、コンテンツ資源を流用するというのもアリですよね。MySQL直でデータ抜いてくるというアプローチは前からありますが、a-blog cmsのオフィシャルな機能で完結できるのであれば、それはそれでスマートではないでしょうか。

オマケAngularJSしてみた

_人人人人人人人人人_
> 突然のAngularJS <
 ̄Y^Y^Y^Y^Y^Y^Y^Y ̄

JS BinでのAnguarJS(バックエンドにa-blog cmsのGETモジュール)サンプル も誰かの参考になる(ことはない気がするけど)と思って軽く書いてみました。

雰囲気抜粋するとHTMLがこんなカンジで...

  • {{entry.entry_title}}

JSはこんなカンジ。

var ACMS = angular.module('ACMS', []);

ACMS.controller('Entries', ['$scope', '$http', 'urlBroadcaster', function($scope, $http, urlBroadcaster) {
  $http.jsonp('http://havelog.ayumusato.com/api/entry.json?callback=JSON_CALLBACK')
  .success(function(response) {
    $scope.entries = response.entries;
  });
  $scope.onClickItem = function() {
    urlBroadcaster.prepForBroadcast(this.entry.entry_url);
  };
}]);

ACMS.controller('EntryPreview', ['$scope', 'urlBroadcaster', function($scope, urlBroadcaster) {
  $scope.url = 'http://aho.mu';
  $scope.$on('urlUpdated', function(a) {
    $scope.url = urlBroadcaster.url;
  });
}]);

Entries でa-blog cmsからJSONPでデータを取得してリスト表示し、アイテムがクリックされたときに EntryPreview に渡しています。

ひさびさでした

a-blog cms 2.0のリリース目前というところで、まさかの公式サイトアップデートには驚きました。この2つを同じタイミングにぶつけてくるだなんて、本当にお疲れ様です。

どうでもいいんですけど、bootstrapテーマでインストールしてloginしようとしたら見た目が別サービスすぎてビックリしましたw


Author

ahomuAyumu Sato

KINTOテクノロジーズ株式会社

Web 技術、組織開発、趣味など雑多なブログ。技術の話題は zenn、ご飯の話題はしずかなインターネットにも分散して投稿しています。

Bio: aho.mu
X: @ahomu
Zenn: ahomu
GitHub: ahomu
Sizu: ahomu

Related

Latest

Archives

Tags

Search