11tyでブログ作ったよ

11tyという静的サイトジェネレーターを使って古き良き(?)ブログをつくった。

これまでmiddlemanやjekyllを使って作ろうとトライしたことはあったが、Rubyの知識はおろかそもそもプログラミングの知識もなかったため、途中で熱が冷めてしまい放置してそのままフェードアウトしてしまっていた。

スクールを卒業して、多少のプログラミングの知識も増え、またアウトプットしていくのって大事だな…などいろいろ思うことがあったのでイチから作ることに再チャレンジしてみた。

f:id:ksmxxxxxx:20210829224432p:plain
ブログのスクリーンショット

11tyを使った理由

MiddlemanやJekyllでもよかったし、なんなら最初はスクールでVue.jsに触れたのでNuxt.jsを使ってもいいなと考えた。

  • 個人的にはRubyよりもJavaScriptの習熟度を上げたい
  • フレームワークを使わないといけないくらいリッチなデザインのサイトなのか?→No。最初はベニヤ板小屋で十分
  • むしろなるべくシンプルに作り始めて盆栽みたいに育てる感じの方向で行きたい

と考えて11tyという静的サイトジェネレーターを使うことに決めた。

何がきっかけで知ったのかは思い出せないけど、ネットでの情報は少ない(英語の記事はそこそこあるけど、日本語は「触ってみた」程度の記事がほとんどという印象)けど、これという大きな理由はないけどなんとなーーーーく気になっているジェネレーターだったというのも理由のひとつだったりする。

「新しいのっていいな…」みたいな、ミーハー的な気持ちから来ているのかもしれない。

落とし穴について解決したメモ

Pugをサポートしているが…

公式サイトにもCodeGridの連載記事にも書かれているが、結構落とし穴がある。
NunjucksやLiquidを使っても良かったけど、終了タグを書くのがめんどくさかった。

Hamlを使っても良かったが、なんとなくSlimに似てるPugを使いたいと思って、Pugを使い始めたが……公式のドキュメントでも使えると書いてあるけど、詳しいことはあまり書いていない。
ネットで検索して調べても大抵は公式のリポジトリのIssueがヒットしてくる。

いくつかハマったところがあったので、ここにメモを残しておく。

FiltersをPugでもつかえるようにする

Pugで11tyのカスタムフィルターを使う場合、すこし手を加える必要がある。

Pug templates need better filter support · Issue #1523 · 11ty/eleventy

このIssueのコメントからヒントを得た。

module.exports = function (eleventyConfig) {
  global.filters = eleventyConfig.javascriptFunctions
  eleventyConfig.addPassthroughCopy('_sources/images')
  eleventyConfig.setLibrary('pug', pug)
  ...
  
  eleventyConfig.setPugOptions({
    filters: global.filters
  })

eleventyConfig.javascriptFunctionsに11tyで用意されているオブジェクトが入っているっぽいので、それをglobal.filtersに追加して、setPugOptionsでPugでも11tyのfilterを使えるようにしている

書き方はもしかしたらもっと良い書き方があるのかもしれないので、追々変えていくつもり。

以下はFiltersを使って、「最近の投稿一覧」を表示させているところのコード。

LuxonというJavaScriptでDateオブジェクトを使うときに、時間の計算をいい感じにしてくれるライブラリを使っています。
ちょっと前だとmoment.jsがよく使われていたけど、それの代替みたいな立ち位置なんですかね…(そのへんのことは調べてないのでよく知らない)

const { Settings, DateTime } = require('luxon')
Settings.defaultZoneName = 'Asia/Tokyo'
eleventyConfig.addFilter('htmlDateString', dateObj => DateTime.fromJSDate(dateObj).toISO())
eleventyConfig.addFilter('readableDate', dataObj => DateTime.fromJSDate(dataObj).toFormat('yyyy年MM月dd日 HH時mm分'))

投稿時間を日本後表記にしたかったのと、日本時間にしたかったので、上記のコードではaddFilterで関数を追加している。
htmlDateStringdatetime要素で投稿時間をISO表記で入れるためのもの。
readableDateは記事名の横に表示する投稿時間用のFilterだ。

ul.recently-posts-list
  each item in collections.articles.reverse()
    li
      time(datetime=filters.htmlDateString(item.date))
        = filters.readableDate(item.date)
      a(href=item.url)
        = item.data.title

filters.#{addFilterした関数名}(引数)で11tyの投稿に関するオブジェクトを参照できるようになる。

パーマリンクの設定

これが一番苦戦したように思う。

Pugでpermalinkの設定をすると、普通にfrontmatterで書くとPugのparseが通らずbuild errorになったり、Output conflictというエラーが返ってくる(なにそれ…)

3日くらい粘ったけど、自力での解決が「無理だ、詰んだ、全然わからん」となって、公式のIssueに助けを求めた。

この問題は記事ディレクトリの中にjsonファイル(ディレクトリデータファイル)を追加して、オブジェクトでパーマリンクの指定を書いてあげることで解決することができるトノコト。

https://github.com/11ty/eleventy/issues/1899#issuecomment-885347427

It should work because it’s a directory data file and uses liquidjs templating by default, I believe. There might be a way to change it to use Pug, I haven’t tried that before, so it could be a learning exercise for both of us (if you want to keep everything in Pug).

ディレクトリデータファイルはデフォルトでLiquid.jsだってことで、……つまり「Liquid.jsとしてparseされるからイケる」ってことなんかなぁって思ってる。(pugにfrontmatter書いたらpugのparse errorが出ていた気がするし)

_sources
├── _includes
│   ├── layouts
│   │   ├── base.pug
│   │   └── blog.pug
│   └── partials
│       ...
├── blog
│   ├── blog.json // ←ブログ記事用のjsonファイル
│   └── markdown-sample.md

なので、blogディレクトリに記事共通で使えるjsonファイルを追加した。

{
  "layout": "layouts/blog",
  "permalink": "{{ page.filePathStem }}.html"
}

{{ page.filePathStem }}はLiquid.jsのテンプレート構文で、オブジェクト名は11tyのものになる。

permalinkで使えるものは他にも日付だったり色々あるので、眺めてみるといい。

ちなみに記事タイトルやtags、投稿日などは記事ごとにfrontmatterで書かれても問題なくbuildされたので、そのままにしている。

ローカルでは解決できて「やったー!」ってなったけど、結局permalinkの指定は使っていない……。
URI構造は記事名/index.htmlにしておいたほうが何かと都合良さそうだと考えたので、そうしている。
ただ、今使わなくても、将来的には使うかもしれない……(使うことあるとおもうんだけど、どうなんだろうなぁ)

参考にした記事

pugjs.org

github.com

github.com

Netlifyにデプロイすると投稿時間が数時間前の時間でビルドされる

これはまだ未解決の問題で、何度も心当たり(luxon周りの設定)をいろいろいじってみたが、解決に至らなかった。

手元でのbuildでは普通に自分のPCと同じ時間にbuildできてるので、もしかしたらNetlify側の問題なのかもしれない?と疑っている。
詳しいところをまだ調べきれていないのかもしれないが……同じような問題にあたったことあるって方、ここをお見かけしたらアドバイスしていただけるとありがたいです……。(ブログリリース前に、少し調べたけど原因が特定できなかった)

根拠のない勘だけど……デプロイしてるサーバーの設定時間でbuildしてるんじゃないのかなぁと推測してる。(が、ggっても情報をみつけられなかった)

🍙

docs.ksmxxxxxx.page

ブログを作った経緯とか考えていることは、作ったブログにまとめてあるので、気になる方はそちらを参照してくれ。

次は、はてブの記事一覧をブログのトップページに表示させたーい。

※といいつつ、最近は同人誌(二次創作)のほうにリソースを寄せていたりするので、多分着手するのはそっちが落ち着いてきたらになる。