「Bootstrap」と一致するもの

以前、Angular向けに自分で開発したsocial-cms-backendは今もメンテナンスしていますが、 これのMeteor版があったら面白いだろうなと思っていました。Meteor版だとfrontendも含まれるので、単にsocial-cmsと呼ぶものになるかなとか。 既に、似たようなものが既にあったので紹介します。自分で作る手間は省けたものの、作ってみたかったという気持ちもあったりします。

一つは、ryw:blog (GitHub)です。 これは他のアプリに組み込むライブラリとしての位置付けで作られたもので、 なんとiron-routerとflow-router両方に対応しているということです。 単体で動かそうと思うと、意外とパッケージ導入に手間がかかりました。 参考までに手順をまとめておきます。

meteor create test-app
cd test-app
meteor add ryw:blog
meteor add kadira:flow-router kadira:blaze-layout
meteor add twbs:bootstrap ian:accounts-ui-bootstrap-3
meteor add accounts-password
meteor run

その後、htmlにログインボタンを設置すれば一応動きます。 ただし、デフォルトでは全員管理者になってしまうので、ロール管理しようとするともう少し複雑になります。 accounts-admin-ui-bootstrap-3 を使うとよさそうですが、初期の管理者を手動で設定する必要があったりと多少導入にハードルを感じます。 もっと簡単にスタンドアローンで動かすための整備は、まだ残件かなと思いました。

UIはいろいろカスタマイズできるようになっているようですが、コメント機能がないのは不完全な感じがします。 DISQUSを使う方法が説明されていますが、スタンドアローンで機能拡張できるとよいです。 そういう意味では、ライブラリとして使うものなのか、すぐに使えるようにするものなのかが曖昧に感じてきました。 このあたりもう少しいじってみたいような気もします。

さて、ついでにもう一つのパッケージを紹介します。 xolvio:md-blog (GitHub)です。 これは、The Meteor Testing Manualで実際に使われているアプリのパッケージのようです。 こちらにデモサイトがあるので様子が分かります。 表示のカスタマイズやロールの設定もできるようです。 試してはいませんが、スタンドアローンで動くアプリを作るのが目的であればこちらの方が楽かもしれません。

感想ですが、だいぶ便利なものが作られているなと思う一方で、まだまだ色々登場しそうですし、何か作ってみたいなと思います。

AngularでBootstrapを使うライブラリとして、以前の記事では、UI Bootstrapを紹介しました。

最近、AngularStrapも使ってみたので感想を書いておきます。

AngularStrapは初期の頃に名前を聞いたことがあるような気がします。確か、bootstrap v2の時代に。今では、AngularStrapもv2になってjQuery依存がなくなりました。いい時代の流れです。

さて、AngularStrapはUI Bootstrapと比べると根本的な設計思想は似ています。どちらも、bootstrapのcssだけ再利用して、javascript部分は作り直し、jQueryには依存しない、Look&Feelのカスタマイズ性を考慮している、と言ったところです。

しかし、使ってみるとだいぶ考え方に違いがあるような気がします。 UI Bootstrapはできるだけシンプルにbootstrapのcssを使えるようにしている一方、AngularStrapはbootstrapのcssをベースにしてよりリッチな機能を提供しようとしているようです。最大の違いは、アニメーションのサポートでしょうか。

簡単な例として、Alertの違いを見てみます。最初は、UI Bootstrap。

<alert type="{{alert.type}}" close="closeAlert(alert)">{{alert.content}}</alert>

これだけです。ng-repeatを使う例がドキュメントに載っていますが、直感的です。ng-showとも組み合わせられます。

次に、AngularStrapです。いろいろあるようですが、attributeを使う例。

<button class="btn" title="{{alert.title}}" data-content="{{alert.content}}" data-type="{{alert.type}}" bs-alert>Show alert</button>

buttonではなくdivで直接表示しようと思いましたが、できませんでした。ドキュメントではできそうなので、何か間違えているのかもしれません。 ng-showは使わず、オプションか属性でshowフラグを指定します。このあたり思想が異なる感じです。durationとか指定できるのは便利です。 alertは単純な機能なので、そこまで違いませんが、他の機能はもっと違いがありそうです。

個人的には、ui-bootstrapの方が使いやすいです。しかし、AngularStrapでアニメーションが簡単に使えるのも魅力的です。使い分けることにします。

人に勧めるのはどちらがよいか迷います。勉強が目的ならui-bootstrapでしょうか、リッチな機能が欲しいならAngularStrapでしょうか。

AngularJSの流れにちゃんとついていくためng-europeをyoutubeで見ようと思い始めて一ヶ月が過ぎてしまいました。 まだ全部は見ていませんが、今日は一本見ました。興味深かったので記事にします。

https://www.youtube.com/watch?v=tfVA1syv-3o

AngularUIのui-bootstrapのお話です。 単にラップするわけではなくAngular流に作られているのと、カスタマイズ性を重視しているあたりは参考になります。

ui-bootstrapはBootstrap 3のcssのみを利用していてjavascriptの部分は全部書き直しているようです。つまり、jQuery依存もなしです。

ちょっと昔話を。当初、Bootstrap 2を使っていたのですが、クラス名などがどうも好きになれず、その後inkというcssフレームワークを見つけて 、しばらく使っていました。

その時から、inkのcssのみを使ってコーディングしていました。ロジックが必要な場合はAngular側で自前で作ってました。 例えば、カレンダーも当初はAngularUIのui-calendarを使っていましたが、 jQuery依存に抵抗があったため、カレンダーも単純な機能ならinkで自前で実装していました。

その後、Bootstrap 3が登場し、クラス名がinkのようにシンプルになったので、少し気に入ってBootstrap 3を使い始めました。でも、cssだけで、jsは使いません。例えば、alertもロジックはangularで自前で書いていました。と言っても、あまりコーディング量は多くなく、特に困っていません。

さて、話を戻しますと、ui-bootstrapは上記でやっていたようなことをちゃんとやっているような印象です。cssだけを使って、ロジックはangular用にdirectiveを設計してあるようです。 alertを見る限りでは単純なので自前で用意しても変わりませんが、他の複雑な機能はui-bootstrapのdirectiveを使うとだいぶ楽できそうです。

というわけで、jQuery非依存のui-bootstrapはおすすめです。

Bootstrapもいいのですが、ちょっと巨大すぎるので、代替品がないかなと思って探しました。

要件は、

  • スマホでも使えるようにレスポンシブ対応
  • あまりできることは多くなくてよい、ボタンとかフォームとかの見た目がきれいになればよい
  • できれば、CSSだけでJavaScript不要のフレームワークがよい

といったところです。

色々探しましたが、有名どころでJavaScript不要と言う要件を満たすものはあまりなく、結局見つけたのがこれです。

レスポンシブ対応のサイトをサクッと作れるフレームワーク『InK』

http://ink.sapo.pt/

この「InK」というネーミングですが、何が困るって、検索キーワードとして使えないことです。Google検索すると、"do you mean link?"とかなってしまう。そんなわけで、使用感などのレポートが見つからなかったです。どれだけ有名なのかもよく分かりません。

また、日本だと、

http://d.hatena.ne.jp/keyword/InK

と混同しそうです。

さて、話を戻すと、Inkは要件を満たしています。全体的な設計がシンプルで、CSSだけで構成されていていい感じです。早速ちょっと使ってみて感じたのは、レイアウトの指定が面白いということです。Bootstrapだと12 spanでfixedとfluidがありますが、Inkだとパーセント指定です。また、fixedはなくてfluidだけのようです(未確認)。fixedも使いたいケースがあるので、それは残念なところです。で、面白いのは、「Multiple Layouts」というレイアウトの指定方法です。これは、CSSのメディアクエリを3通り用意して、それぞれのレイアウトをCSSのクラス指定で定義するのです。

うまく説明できないので、サンプルを。

<div class="ink-l50 ink-m50 ink-s100">
  エリア1
</div>
<div class="ink-l50 ink-m50 ink-s100">
  エリア2
</div>

このようにすると、大画面と中画面では、エリア1とエリア2が横に並んで2カラムのレイアウトになり、スマホなどの小画面では、エリア1とエリア2が縦に並んで1カラムのレイアウトになります。ちなみに、大画面、中画面、小画面が、それぞれ、"l", "m", "s"に対応します。

あと、Bootstrapで困っていたレイアウト時のスペース追加も、Inkではink-vspaceとink-gutterで解決しそうです。もっとも、細かい制御をするときは結局CSSを書くことになりそうですが。

とりあえずは、レイアウトだけ試して満足しました。

RSS Pipesは、JavaScriptでフィルターを書く、RSSアグリゲーターです。

RSSの登録数が増えてきたら検索機能を作ろうと思っていたのですが、 先に作ってしまいました。検索と言っても、表示されているものを絞り込むだけです。

AngularJSには標準でフィルターというものが組み込まれているので非常に簡単にできました。ソースコードに検索ボックス配置の1行と、フィルター追記の1行で済んでしまいました。Bootstrapのレイアウトでもう数行いじりましたが、トータルで5行の改変のみです。

興味ある方は、diffを見てみてください。

https://github.com/dai-shi/rss-pipes/commit/c250c8a7d9b03476503c78fda5a2f0ab5cef5894#views/partials/home.jade

お手軽です。詳しくは、AngularJSのチュートリアルを参照しましょう。

http://docs.angularjs.org/tutorial/step_03

JQueryやAngularJSはGoogle Hosted Librariesが配信してくれて、 BootstrapはBootstrapCDNというのもあって 便利です。

しかし、マイナーなライブラリになるとどうしたものかと思っていました。手を入れないライブラリは自分でホスティングする理由もないので、CDNがないかなと思って探したところ、

を見つけました。cdnjsはGitHubのPull Requestsでライブラリの登録を依頼できるというのが面白いです。

しかし、どちらもcssファイルは登録されていない様子なので、結局すべてを外部CDNに頼ることはできないと。探せば他にもありそうですね。

AngularJSのangularInitを読みました。

<html ng-app="<mymodule>" class="ng-app:<mymodule>">

と書くことは、

angular.bootstrap(document, ["<mymodule>"]);

とたぶん同等です。 より正確には、readyで呼ばれるので、

angular.element(document).ready(function() {
  angular.bootstrap(document, ["<mymodule>"]);
});

となります。angular.elementはJQueryかJQLiteです。

分かったことは、それだけです。


追記。

よく読んだら、ドキュメントにちゃんと書いてありました。

http://docs.angularjs.org/guide/bootstrap

最近、テスト書きながらでコーディングしていますが、 https://github.com/dai-shi/connect-prerenderer のe2eテストで少し困ってます。

AngularJSのブートストラップは通常、

<html ng-app class="ng-app:<modulename>">

とアノテーションをつけることによって行われるのですが、 ある理由からブートストラップを自分で呼びたいと考えています。 これ自体は比較的簡単で、

angular.bootstrap(document, ["<modulename>"]);

を呼び出せばいいだけです。より正確には、

<script>
  angular.element(document).ready(function() {
    angular.bootstrap(document, ["<modulename>"]);
  });
</script>

といったことろです。

ところが!

このブートストラップの方法だと、testacularが動いてくれないのです。困りました。browser().navigateTo(...)を呼び出すと返ってこないのです。

解決策は今のところ見つかっていません。とりあえず、テストするときは、ng-appをつけておくしかありませんね。

https://github.com/dai-shi/connect-prerendererを開発中に出会った事象について書き留めておきます。

jsdomでAngularJSを使ったテストページにアクセスすることになったのですが、 angularが初期化されなくて困ってました。ぐぐったところ、

AngularJSがIE8で動かないときは

を見つけたのですが、この方法では解決せず。結局、次のようにしたら動きました。

<html ng-app class="ng-app">

id="ng-app"はあってもなくても変わらず。モジュールがある場合は、class="ng-app:<modulename>"でもうまくいくのかもしれません。

angularのソースコードを少し眺めると、

function angularInit(element, bootstrap) {
  var elements = [element],
      appElement,
      module,
      names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
      NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
//-----snipped-----
  forEach(names, function(name) {
    names[name] = true;
    append(document.getElementById(name));
    name = name.replace(':', '\\:');
    if (element.querySelectorAll) {
      forEach(element.querySelectorAll('.' + name), append);
      forEach(element.querySelectorAll('.' + name + '\\:'), append);
      forEach(element.querySelectorAll('[' + name + ']'), append);
    }
  });

ってな感じで、どんな風に書いても動きそうです。なぜ、id="ng-app"でうまくいかなかったのか疑問が残りますが、追求しないことにします。


追記。

ng-appだけではダメだった理由は、ng-app="ng-app"に展開されてしまうからのようなので、ng-app="<modulename>"にすればうまくいくのかもしれません。

さらに、追記。

結局、ng-app=""で動いたので、ng-appだけだとjsdomでうまくいかないというのは正しそうです。class="ng-app:<modulename>"もうまくいきそう。id="ng-app"で動かなかった理由はおそらく、ng-appが残っていたからでしょう。