おもこん

おもこんは「思いつくままにコンピュターの話し」の省略形です

Jekyll初級編(2)GitHubへの問い合わせ

GitHubへの問い合わせ機能を使う

JekyllとGitHub Pagesを連携させるとします。 GitHubに情報を問い合わせ、GitHubのレポジトリの一覧を表示する方法について書こうと思います。 ポイントは2点あって、

  • jekyll-github-metadata gemを使う
  • データ(_dataディレクトリ以下のファイル)を使う

です。

jekyll-github-metadata gem

GitHubとローカルの環境を一致させるためにgithub-pages gemをGemfileに記述します。 これについて良くわからない場合ははじめてのJekyll + GitHub Pagesを参照してください。

github-pagesによって、jekyll-github-metadata gemも使えるようになります。 このgemによって「ローカルからGItHubに問い合わせて情報を得る」ことができるようになります。 この機能はあくまでローカルでJekyllを動かす時に役に立つ機能です。 GitHubにアップロードされたデータでは、GitHub内のJekyllがHTMLの生成をしますので、このgemを使う必要はない(と思います)。

この機能を使うときには、PATをセットしてすべてのデータが問い合わせできるようにしてください。 このことについては、jekyll-github-metadataのレポジトリの説明を見てください。 また、「はじめてのJekyll + GitHub Pages」の第4章の最後の節も参考になります。

この機能を使うとレポジトリの一覧、GitHub Pagesのアドレスなどを問い合わせることができます。

変数 変数の指すオブジェクト
site.github.public_repositories レポジトリのリスト(※)
site.github.url GitHub PagesのルートURL
site.github.owner_name レポジトリ所有者名

(※)各レポジトリのプロパティの一例

プロパティ 内容
name レポジトリ名
html_url レポジトリのURL
descriptopn レポジトリのディスクリプション

他にも多くの情報がありますが、詳細はjekyll-github-metadata gemのGitHubレポジトリをご覧ください。

この機能を使うと、「レポジトリ名の一覧表を表示する」などができます。

データ

_dataディレクトリにyamlcsvデータを置いてLiquidで参照することができます。 例えば_data/gh_pages.ymlは、私のレポジトリのうちGitHub PagesのHTMLページを持っているもののリストです。

- Gobject-tutorial
- Gtk4-tutorial
- jekyll-tutorial-for-beginners
- Rake-tutorial-for-beginners-en
- Rake-tutorial-for-beginners-jp
- ToshioCP.github.io

これをLiquidで取り込むには次のようにします。

{% assign gh_page_repos = site.data.gh_pages %}

変数gh_page_reposにはデータディレクトリのgh_pages.ymlyamlデータが代入されます。 上記の通り、yamlデータはリストなので、変数には配列が代入されます。 今回の例では配列しか扱いませんが、ハッシュを扱う場合はドット記法で値を取得することができます。

実例(レポジトリの一覧表示)

実例として、jekyll-github-metadataを使ってレポジトリ名とURLを取得し、かつyamlデータに含まれるレポジトリのHTMLページへのリンクを表示します。

---
layout: page
title: Repositories
description: The list of the repositories
lang: en
---
{% assign gh_page_repos = site.data.gh_pages %}
| Repository | GitHub Page (Document) |
|:-----------|:------------|
{%- for repository in site.github.public_repositories -%}
  {%- if repository.name == "ToshioCP.github.io" %}
    | [{{ repository.name }}]({{ repository.html_url }}) | <{{site.github.url}}> |
  {%- elsif gh_page_repos contains repository.name %}
    | [{{ repository.name }}]({{ repository.html_url }}) | <{{site.github.url}}/{{repository.name}}/> |
  {%- else %}
    | [{{ repository.name }}]({{ repository.html_url }}) | |
  {%- endif -%}
{%- endfor -%}

マークダウンで表を出力するために縦棒|と区切り|:---|:---|を使っています。

  • for文を使い、site.github.public_repositories(レポジトリの配列)からレポジトリを一つずつ取り出して変数repositoryに代入し、ループする
  • repository変数にはレポジトリのオブジェクトが代入されている。 そのプロパティは多数あるが、そのうちname(レポジトリ名)とhtml_url(レポジトリのURL)を使う この2つから、レポジトリへのリンクを作成する
  • レポジトリ名がToshioCP.github.ioであれば、GitHub Pagesのルートから展開されるHTMLページがあるので、site.github.urlへのリンクを表示する
  • レポジトリ名がgh_page_reposに含まれていれば、HTMLページがあるので、site.github.urlにrepository.name(これがBase URLになる)をつけたアドレスへのリンクを表示する
  • それ以外はHTMLページを持たないのでそこは空欄にする

このページを表示すると次のようになります。

repositoriesページ

まとめ

GitHubの情報で最も使いそうなのがレポジトリの情報だと思います。 それ以外の情報も問い合わせできますが、あまり使い方が思いつきませんでした。 今回は名前とURLを使いましたが、他にもZIPやTAR.GZのダウンロードのURLなども役立ちそうです。

データの使い方は様々です。 今回はHTMLページのあるレポジトリ名のデータを使いましたが、応用範囲はとても広いです。 例えば気象データを表形式で表示する場合、HTMLページと気象データを分離できますから、データのみ更新すれば良いことになります。 そのため、更新が非常に楽になります。

その他にも様々なことにデータが使えます。 ぜひ、データの有効活用について研究してみてください。

Jekyll初級編(1)英語と日本語のあるウェブ

多言語のウェブサイト構築

Jekyllの勉強を兼ねてブログを書いたおかげで、だいぶ分かってきました。 それをまとめた「はじめてのJekyll + GitHub Pages」が出来上がり、一区切りですが、これからはその続編を書こうと思っています。 前回が入門編でしたので、今度は初級編です。 ネタができたら、ブログに書き留め、ある程度の分量になったら書き直してGitHubにあげようと思います。

今日は国際化もどきです。

言語の切り換え

日本語だけでなく、英語もサポートするウェブを作ることを考えてみます。 動的なサイトの場合、単語やフレーズ単位で日本語と英語を用意して、ユーザからの言語の要求に基づいて切り替えることが良く使われます。 これは、記事に対して行うというより、メニューやメッセージなどのように短く、あらかじめ決まった使い方をするものに対して行われます。

Jekyllが構築するのは静的なサイトなので、画面の一部だけを取り替えることができません。 英語の画面と日本語の画面を別々に用意し、それらの画面をビルドする段階でメニューなどの言語をチョイスすることになります。 また、リンク先も日本語と英語を別々にしなければなりません。 別言語に移動するリンクはメニューの中に用意します。

日本語/英語サイトのイメージ

ページの言語を指定するためにフロントマターに「lang: ja」「lang: en」のハッシュを設けます。

このような仕組みで実際にGitHubにページを作ったものがあります。

このページを例に、リンクの作り方を説明します。

メニューとレイアウト

すべてのページはフロントマターに言語が指定されています。 例えば、英語のaboutページのフロントマターは

---
layout: page
title: About
lang: en
---

このようになっています。 このページのメニューは英語ページへのリンクだけを貼ります。

例に用いる「ToshioCP's Homepage」ではテーマにminimaを使っています。 minimaではメニューをレイアウト自身ではなく、レイアウトがインクルードする「header.html」で記述しています。 そこで、_includesディレクトリの下にカスタマイズ用のheader.htmlを作ります。 まず、minimaのheader.htmlをコピーして、次のように一部変更します。

<header class="site-header">
  {%- if page.lang == "ja" -%}
  {%-   assign root_path = "/index_ja.html" -%}
  {%-   assign lang_change_path = "/" -%}
  {%-   assign lang_change_title = "English" -%}
  {%- else -%}
  {%-   assign root_path = "/" -%}
  {%-   assign lang_change_path = "/index_ja.html" -%}
  {%-   assign lang_change_title = "日本語" -%}
  {%- endif -%}
  <div class="wrapper">
    {%- assign target_pages = site.pages | where: "lang", page.lang -%}
    {%- assign target_default_pages = site.header_pages | where: "lang", page.lang -%}
    {%- assign target_pages = target_default_pages | default: target_pages -%}
    <a class="site-title" rel="author" href="{{ root_path | relative_url }}">{{ site.title | escape }}</a>

    <nav class="site-nav">
      <input type="checkbox" id="nav-trigger" class="nav-trigger" />
      <label for="nav-trigger">
        <span class="menu-icon">
          <svg viewBox="0 0 18 15" width="18px" height="15px">
            <path d="M18,1.484c0,0.82-0.665,1.484-1.484,1.484H1.484C0.665,2.969,0,2.304,0,1.484l0,0C0,0.665,0.665,0,1.484,0 h15.032C17.335,0,18,0.665,18,1.484L18,1.484z M18,7.516C18,8.335,17.335,9,16.516,9H1.484C0.665,9,0,8.335,0,7.516l0,0 c0-0.82,0.665-1.484,1.484-1.484h15.032C17.335,6.031,18,6.696,18,7.516L18,7.516z M18,13.516C18,14.335,17.335,15,16.516,15H1.484 C0.665,15,0,14.335,0,13.516l0,0c0-0.82,0.665-1.483,1.484-1.483h15.032C17.335,12.031,18,12.695,18,13.516L18,13.516z"/>
          </svg>
        </span>
      </label>

      <div class="trigger">
        {%- for target_page in target_pages -%}
          <a class="page-link" href="{{ target_page.url | relative_url }}">{{ target_page.title | escape }}</a>
        {%- endfor -%}
          <a class="page-link" href="{{ lang_change_path | relative_url }}">{{ lang_change_title | escape }}</a>
      </div>
    </nav>
  </div>
</header>
  • 2行目から10行目で、現在開かれているページが日本語か英語かによって、root_pathなどの変数を設定します。
    • root_path それぞれの言語のトップページへのパス
    • lang_change_path 別の言語のトップページへのパス
    • lang_change_title 別の言語へのメニュー文字列
  • 12-14行目でメニューに表示するページの配列をtarget_pagesに代入。 このとき、whereフィルターで同言語のページのみに絞ります。 なお、minimaではsite.header_pagesが設定されていれば、それだけをメニューに表示するようになっています。 これはページの数が多くて、なおかつ全部をメニューに入れる必要がない時に使います。
  • 15行目でトップページへのリンクを貼ります。

下から8行目から5行目がメニューを表示する部分です。 for文でtarget_pagesへのリンクを作ります。

  • target_page.urlにはrelative_urlフィルタをかけなければならない
  • target_page.titleにはHTMLの特別な文字が含まれる可能性があるのでescapeフィルターをかける

for文の次に他の言語へのリンクを付け加えます。 リンク先はその言語のトップページです。

ポイントになるのはwhereフィルターで同言語のページのみを抽出するところです。

以上で日本語ページのメニューには日本語ページへのリンクだけが、英語ページのメニューには英語ページへのリンクだけが設置されます。

トップページのブログの一覧表示

トップページは英語がindex.html、日本語がindex_ja.htmlになります。 それぞれブログへのリンクがリストされますが、英語のトップページには英語のブログだけ、日本語のトップページには日本語のブログだけがリストされます。

これはレイアウトのhome.htmlで設定されています。 カスタマイズのために、_layoutsディレクトリを作り、そこにminimaのhome.htmlをコピーし書き換えます。

---
layout: default
---

<div class="home">
  {%- if page.title -%}
    <h1 class="page-heading">{{ page.title }}</h1>
  {%- endif -%}

  {{ content }}

  {% comment %}
  No pagination is available.
  {% endcomment %}

  {% assign posts = site.posts |where: "lang", page.lang %}


  {%- if posts.size > 0 -%}
    {%- if page.list_title -%}
      <h2 class="post-list-heading">{{ page.list_title | escape }}</h2>
    {%- endif -%}
    <ul class="post-list">
      {%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
      {%- for post in posts -%}
      <li>
        <span class="post-meta">{{ post.date | date: date_format }}</span>
        <h3>
          <a class="post-link" href="{{ post.url | relative_url }}">
            {{ post.title | escape }}
          </a>
        </h3>
        {%- if site.show_excerpts -%}
          {{ post.excerpt }}
        {%- endif -%}
      </li>
      {%- endfor -%}
    </ul>
  {%- endif -%}

</div>

ポイントは中程やや上にある

  {% assign posts = site.posts |where: "lang", page.lang %}

です。 これで、ブログ記事(site.posts)から同言語のページのみを抽出します。

まとめ

ポイントはリンクを同言語に限るようwhereフィルターを使うところです。 やってみるとさほど複雑ではないことが分かると思います。

日本語が難しい

この3日ほど「はじめてのJekyll+GitHub」の手直しをしていた。

内容の間違いも少なくなかったが、それ以上におかしな日本語が多くて時間がかかった。 自分の文章力の低さにへこんでいる。

おかしな文章は意図的に書いているわけではないので、あらためて文例を作るのは難しいが、例えば次のようなものだ。

GitHubは、実際にウェブを作ってみると思ったよりも簡単にできあがって、Jekyllのサポートがありがたい」

はじめは「GitHubは」を主語にするつもりで書き出したが、最終的に「Jekyllのサポート」が主語になっている。 おそらく、いくつかの文章に分けると良くなるのだと思う。

  • GitHubで実際にウェブを作ってみると、思ったよりも簡単にできた
  • 簡単な理由は、GitHubがJekyllをサポートしているからだ
  • Jekyllはウェブ制作者にとってありがたいアプリである

だが、この文章の主眼が「Jekyllがありがたい」ことであるならば、もっと別の書き方をすべきだろう。 GitHubの経験よりも、Jekyllがありがたい理由を書くほうが良い。

  • ウェブ制作にはコンテンツ以外の煩わしい作業が多数ある
  • Jekyllはそれらを自動化してくれる
  • Jekyllはウェブ制作者にとってありがたいアプリである

助詞の使い方にも悩んだ。

「京都は古い建物が多い」

これは正しいのだろうか? 「象は鼻が長い」(これは正しい文章)にも似ているが。

「京都には古い建物が多い」

のように「に」を入れるのが正しいのだろうか? あるいは「に」なしと「に」ありには意味の違いがあるのだろうか?

考えれば考えるほど筆が進まなくなる(キーボードが進まなくなる?)。 すらすらと文章の書ける人が羨ましい。

【森を見よ】マイナスの数の掛け算

マイナスの数の掛け算について書きます。 よくある間違いに、マイナス✕マイナスがマイナスになる、というのがあります。 正しくはプラスになる、と教わるのですが「なぜ?」となってしまうのです。 そう思う理由は、

  • プラス✕プラスがプラスになるから、マイナス✕マイナスがマイナスになる
  • プラスにマイナスをかけるとマイナス、つまり小さくなる。 だからマイナスにマイナスをかければ余計小さくなるはずだ

などでしょう。

これは掛け算の一部を見て類推しているのです。 もっと掛け算の全体を見なければならないのですね。

負数(マイナスの数)の仕組み

−2は数なんだから、「ー」と「2」を分けてはだめ、「−2」でひとつの数だから。

負数を習うと最初はこう教えられるかもしれませんが、実は「−2」は「ー」と「2」に分けて考えるべきです。

  • 「ー」は「+」と逆の向きを表す
  • 「2」はプラスとマイナスの中間にある「0」からの距離を表す

実は正の数も同じで「5」と「+5」は同じで、向きが「+」の向き(一般には正の向きという)で0からの距離が「5」です。

数直線

「プラス✕プラス」と「マイナス✕プラス」

2✕3は2を3回足すことだから、6になります。

2✕3=2+2+2=6

同じように考えれば、(−2)✕3は−6になります。

(−2)✕3=(−2)+(−2)+(−2)=−6

このように「3をかける」というのは

  • 向きを変えず
  • 大きさを3倍(0からの距離を3倍)

ですが、「向きを変えず」というのは大事なポイントです。

「プラス✕マイナス」

掛け算は前後を入れ替えても同じになるので、

3✕(−2)=(−2)✕3=−6

ですが、ここから「−2をかける」というのは

  • 向きが反対になる(正の数が負の数になる)
  • 大きさが2倍(0からの距離が2倍)

ということになります。 ここで、向きが反対になるのは「−2」の「ー」の部分のためです。大きさ2倍は「−2」の「2」の部分が関わっています。

「マイナス✕マイナス」

「−3」をかけると「向きが反対」「おおきさ3倍」ですから、

(−2)✕(−3)=6
  • −2は負の向きなので、向きを変えると「正の向き」
  • 0からの距離は2の3倍で6

ということですね。 だから、マイナス✕マイナスは(向きが反対になるから)プラスになります。

数学的、形式的な論法

形式的には、マイナスの数はプラスの数の逆元として導入していくことになるので、

(−3)+3=0

負数でも分配法則が成り立てば

(−2)✕{(−3)+3}=(−2)✕0
(−2)✕(−3)+(−2)✕3=0
(−2)✕(−3)+(−6)=0
(−2)✕(−3)=6

このようにマイナス✕マイナスがプラスにならなければならない。 そうでなければ、分配法則は負の数では使えなくなってしまう、ということです。

発展編=>虚数

−1をかけると向きが変わるだけで大きさが変わりません。 「2✕(−1)=−2」「(−2)✕(−1)=2」です。 「向きが変わる」というのは「180度回転」させるのと同じです。

ところで、虚数iは2乗すると−1になる数ですから、

2✕(−1)=2✕i✕i

です。では、「2✕i」はどうなるのでしょう? iは2回かけて(−1)で、−1倍は180度の回転でしたから、「i倍は90度回転」と考えればつじつまが合います。

虚数

このことから、iの倍数は垂直に並ぶことになります。

複素平面

これが高校で習う「複素平面」です。 「マイナスをかけると向きが変わる(=180度回転)」を発展させて複素平面の考えにたどり着くわけですね。 もしもマイナス✕マイナスがマイナスだったら、このように発展させることはできませんでした。

【森を見よ】2✕3の呪縛

算数で教わる掛け算

小学校の算数で「2✕3は2が3個」と習います。 つまり

2✕3=2+2+2

ということですね。

「みかんが2つ入っている袋が3つある。みかんは全部でいくつ?」

この問題は2✕3で解くんだよ、と教わります。 そのとき、これを3✕2と書くと不正解になる(と記憶しています)。

みかんと袋

交換法則

小学校の高学年だと思うのですが、掛け算の前後を入れ替えても答えは同じになることを習います。 これを数学では「交換法則」とか「可換律」といいます。

2✕3=3✕2

ということですね。 これは、箱に入ったまんじゅうの例で説明できます。

箱入りまんじゅう

はこには6個のまんじゅうが長方形に並んでいます。 左側では、横に2つ並んだまんじゅうのグループが3つあるので「2✕3」。 右側では、縦に3つ並んだまんじゅうのグループが2つあるので「3✕2」。 どちらもまんじゅうの総数6に等しいので、

2✕3=3✕2

2と3に限らず、どの掛け算も「箱入りまんじゅう」の縦横の数だと思えば同様に交換法則が成り立つことが分かります。

2✕3の新たな見方

交換法則が成り立つのだから「2✕3」の意味を2通りのどちらでも良いと見ることができます。

  • 3つのものが入った袋が2個あるときの「もの」の総数
  • 2つのものが入った袋が3個あるときの「もの」の総数

小学校低学年では「2✕3」は上の意味であって、下の意味ではないと教えるのは、児童が無用の混乱をきたさないための教育上の手法です。 本当は2通りの意味が含まれると考えるのが正しいです。

中学になって文字式を習うと「 2x」が出てきます。

  • 2が x
  •  xが2個

のどちらも正しいけれども、通常は「 xが2個」でしょう。

小学校で習った解釈ではなく、小学校で誤りとされた考えが正しいわけです。 おそらく、ここで混乱する中学生は少なくないと思います。 なぜ「 x2」じゃなくて「 2x」なのか? すぐに理解できるようになるとは思いますが・・・

英語ではどうなんだろう?

英語で「2✕3」は

  • two times three
  • two multiplied by three

です。 それぞれ、

  • 3つのものが入った袋が2個あるときの「もの」の総数
  • 2つのものが入った袋が3個あるときの「もの」の総数

に対応するように思いますが、「timesの方は両方の解釈ができる」というネット情報もありました。 ネイティブの間でも議論になるようです。

蛇足ですが、

A is three times as big as B. => AはBの3倍の大きさである

A is three times bigger than B. => 「AはBの4倍の大きさである」との解釈も成り立つ

で、前者が曖昧さの残らない表現でよろしい、ということだそうです。

Herokuのフリープランが11月で終了

Herokuからフリープラン終了の通知

Herokuはセールズフォース・ドットコムという会社のPaaSです。 PaaSというのはレンタルサーバーみたいなものですが、様々な機能(OS、データベース、その他)がはじめから備わっています。 私はHerokuでWNoteというrailsを用いたウェブ・アプリケーションを動かしていました。

Herokuは無料プランがあり、railsなどで作ったアプリをネット上で試すことができます。 この無料プランが11月28日から無くなる旨のメールが届きました。 このことはHerokuのウェブにも公開されています。

Herokuからの引っ越し

WNoteをネット上で動かす実験はHerokuですでに行ったので、それを場所を移してまで続けるつもりはないのですが、WNoteに記録したドキュメントをどこかに移動したいと思っています。

  • Gtk+3入門」(現在は出版停止)のサポートページ
  • WNoteの解説ドキュメント
  • プログラム言語Luaチュートリアル
  • その他

これからぼちぼち考えますが、結構手間がかかりそうです。

ウェブサイトの静的と動的

GitHubレポジトリのブログ更新

久しぶりにレポジトリ・ブログの更新をしました。

このブログは作ってはみたもののあまり更新せずにいました。 実はJekyllを使ったサイトです。 このサイトを作った頃はまだJekyllがよく分かってなくて、あまり深入りせずにいました。 今はJekyllの理解が深まったので改めてこのサイトを手直ししようと思ったのです。

リニューアルされたサイトは日本語と英語の両方が使えるサイトになっているのが特徴です。 ただJekyllが静的なサイト・ジェネレータなので動的なサイトのようにユーザアクセス時点の言語要求によって言語を選択することはできません。 特にブログの部分のパジネーションが難しいのです。 それで、ブログはパジネーション無しで日本語の投稿と英語の投稿が別々に表示される形になっています。

静的と動的

言語の選択に対して、そのサイトが静的か動的かが実装に関わるので、改めて「静的と動的」について考えてみました。

静的なサイトというのはそのウェブサイトにHTMLファイルが配置されていて、それをブラウザがアクセスします。 画面の遷移はリンクを通してリソースのファイルを移動することによって行われます。

動的なサイトの場合はサイトにファイルがあるわけではなくて、ブラウザからのリクエストがあった時にサーバー内のプログラムが動き始め、Webページのデータを作り出して送ります。 ですから最初からページが出来ているわけではなくて、リクエストに応じて作るわけで、非常に柔軟に内容を作ることができるわけです。 しかもページの内容を決めるのが、ブラウザとのインタラクション時点というのが強みです。 ちょうど、プログラム言語のコンパイラインタプリタの違いに似ています。

動的なサイトが日本語と英語のページ切り換えをするのはサーバ側のプログラムなので、様々な方法が可能です。 静的なウェブサイトの場合はそうはいかないので、予め日本語のページと英語のページを用意しておくしかありません。

Jekyllにおけるパラメータ処理の質問をネットで見かけますが、静的サイトでブラウザとのインタラクション時の処理はできません。 (「https://・・・・/somepage.html?japanese」のようなクエスチョンマーク以下をパラメータという) こういう混乱が起こるのは「静的と動的」の理解が足りないのです。 無理にやるとしたら、Javascriptを使ってブラウザの内部で処理するしか方法は無いと思います。

静的なサイトの安全性

動的ページはユーザから送られてくるデータに対応できますので、例えばユーザー名やパスワードをサーバに登録することができます。 それに対して静的なページではユーザとのインタラクションの段階ではプログラムは全く動いていませんので(Jekyllはサイト作成時に動くだけです)、ユーザー名やパスワードの処理はできないのです。 静的なページにはログインとかログアウトはありません。

その代わり静的なサイトでは、悪質なユーザがどんなに手のこんだデータを送ってもサーバに残りませんから、安全性は高いわけです。 それに、動的サイトで一般ユーザが投稿できるブログでは、投稿内容のルール(例えば犯罪につながるような投稿禁止)が重要ですが、静的サイトでは内容を作るのは自分しかいないのでルールは必要ありません。

静的と動的のミックス

静的と動的は概念上の問題なので、実装上は両者をミックスすることが可能です。

例えばコメント機能を動的サイトで作り、静的サイトからそのコメント機能へのリンクを貼っておきます。 ユーザからの投稿は動的サイトに記録されますから、その記録を静的サイトからリンクして見られるようにすれば良いのです。 実際GitHub Pagesでブログを作っている人の中には、そういうことをしている人がいるようです。

動的なサイトに興味のある人は

動的なサイトに興味がある人はrailsを使うと良いと思います。 長い間開発が続いていて、信頼できるフレームワークです。 ただ、Jekyllよりは学習に時間がかかると思います。 以前ブログにRailsの学習について記事にしたので、参考にしてください。