Middlemanで記事内で使う画像をサイト全体の画像のディレクトリに入れて管理すると、どの記事に関連した画像かわかりにくくなってしまいます。記事毎に画像を管理できたら便利です。
もくじ
directory_indexesを有効にできない?
dierctory_indexesを有効にしない場合の管理方法
dierctory_indexes
を有効にしない場合は、以下のサイトの説明通りにやればうまくいきそうです。
初めてのMiddleman:Middleman-Blogで記事毎に画像を管理する方法
dierctory_indexesを有効にすると起こる問題
有効にした場合、上記のサイトの方法だと適切な画像なパスが出力されません。公式ドキュメントのこの部分には以下のように書いてあります。
記事のサブディレクトリ
ブログ記事に紐付いた拡張子なしのサブディレクトリは, ビルド時に 正しい場所へ複製されたファイルが入っています。 例えば, 次のディレクトリ構造です:
123 source/2011-10-18-middleman.html.markdownsource/2011-10-18-middleman/photo.jpgsource/2011-10-18-middleman/source_code.rb
この出力 (directory_indexes
が有効化された場合) は次のようになります:
123 build/2011/10/18/middleman/index.htmlbuild/2011/10/18/middleman/photo.jpgbuild/2011/10/18/middleman/source_code.rb
単一のブログ記事に属しているファイル (例えば画像) は source 内で一緒に保管し出力することができます。ブログ構造に依存し,記事の中で相対リンクの使用を可能にしますが, 記事の内容がサイトの他の部分, 例えばカレンダーやタグページ, で使われる場合には注意が必要です。ブログ記事から記事のサブディレクトリにあるものにリンクしたい場合,ディレクトリ名を含むことに注意してください:
12 Wrong: [私の写真][photo.jpg]Right: [私の写真][2011-10-18-middleman/photo.jpg]
この方法で動作するはずですが,:asset_hash
のようなその他の Middleman の機能では動作しません。 詳細についてはこのissueを確認してください。
directory_indexex
を有効にした場合は、:asset_has
が動かない上に、サブディレクトリ名を指定しなければならないということです。
なので、公式マニュアルはこの部分で、以下のような対処法を提示しています。
アセットパスに関する注意事項
ディレクトリインデックスを有効化する場合, 画像ファイル名だけで アセットファイルの呼び出し (例: 画像ファイル) を行うと失敗します。次のように完全な抽象パスを使って呼び出す必要があります:
1 ![すごい画像](/posts/2013-09-23-some-interesting-post/amazing-image.png)
わずかにこのプロセスを自動化するには, Markdown をまずは ERB で作成します。 例えば/posts/2013-09-23-some-interesting-post.html.markdown.erb
ファイルがあるとします:
1 ![すごい画像](<%= current_page.url %>some-image.png)
つまり、この対処法はerbを使わなければならない上に、:asset_hash
が動かない問題は解決していません。
Markdown内にerbの余計なコードを書かなければいけないし、.html.markdown.erb
という風に拡張子が長くなり見づらくなります。
また、:asset_hash
が使えないと、画像を差し替えたにもかかわらず、ユーザ側が再訪問しても古い画像をブラウザのキャッシュから表示してしまう危険性があります。
directory_indexesを有効にしつつ記事毎に画像を管理する方法
ディレクトリ構成
試行錯誤した結果、source
内の記事と画像ファイルをあるディレクトリ構成にすると可能になることがわかりました。以下はこのサイトのディレクトリ構成です。
1 2 3 4 5 6 7 8 9 10 11 |
source └─ articles └─ 2015-11 └─ 14-sample-article ├── images │ ├── sample01.jpg │ ├── sample02.jpg │ ├── sample03.jpg │ ├── sample04.jpg │ └── sample05.png └── index.html.md |
動作させるためのポイント
これと全く同じ構成しなければならないわけではなく、抑えるべきポイントは2つです。
- 記事タイトルが入ったディレクトリ内に
index.html.md
を入れます。(私の場合は{日付}-{タイトル}というディレクトリにしています。) - 画像も同じディレクトリにいれます。(お好みで画像専用のディレクトリ作ってもOKです。)
ディレクトリがすっきり見やすいという副次効果も
前述した公式ドキュメントの対処法のディレクトリ構成だと、同じ階層に記事ファイルと同じ名前のディレクトリが必要になり、項目が多くなりみずらくなります。こちらの構成だと、1つのディレクトリに記事ファイルも画像もまとめることができ、項目が少なくなりすっきり見やすくなります。
スポンサーリンク
Markdown内での書き方
このようにindex.html.md
からの相対パスを書くだけで、よしなにパスを生成してくれます。もちろん:asset_hash
のハッシュ値がついたファイル名になって生成されます。
1 |
![サンプルの画像](sample01.jpg) |
build時の画像の配置先が変わる
特に作業が変わるわけではないので意識する必要はないのですが、1つ変化することがあるので、記載しておきます。
前述した公式マニュアルでの対処法だと、middleman build
を実行したらbuild/{記事のURL}/
配下に画像ファイルが配置されます。
ですが、この記事で紹介している方法だと、source
内のディレクトリ構成でそのまま画像がbuild
配下にコピーされます。なので、上記の例だとbuild/articles/2015-11/14-sample-article/
に画像が配置されます。
上記のMarkdownの書き方できちんとこのパスを生成してくれます。
config.rbの設定
微細な差異でこの方法が動作しなくなる可能性もあるので、このサイトのconfig.rbをシェアします。(コメントは削除しています)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
activate :blog do |blog| blog.permalink = "{title}" blog.sources = "articles/{year}-{month}/{day}-{title}/index.html" blog.layout = "article" blog.default_extension = ".md" blog.tag_template = "tag.html" blog.calendar_template = "calendar.html" blog.paginate = true blog.per_page = 10 blog.page_link = "page/{num}" blog.custom_collections = { category: { link: '/categories/{category}/index.html', template: 'category.html' } } blog.new_article_template = "article.erb" end activate :directory_indexes page "/feed.xml", layout: false activate :livereload set :css_dir, 'stylesheets' set :js_dir, 'javascripts' set :images_dir, 'images' set :partials_dir, 'partials' set :trailing_slash, true set :markdown_engine, :kramdown set :markdown, input: "GFM" activate :i18n, mount_at_root: :ja activate :dotenv activate :syntax, line_numbers: true activate :asset_hash configure :build do activate :minify_html activate :minify_css activate :minify_javascript end activate :deploy do |deploy| deploy.method = :ftp deploy.host = ENV['HOST'] deploy.path = '/webfood' deploy.user = ENV['USERNAME'] deploy.password = ENV['PASSWORD'] end |
- middlemanのバージョン : 3.4.0
- middleman-blogのバージョン : 3.6.0.beta.2
まとめ
Middlemanは細かな挙動はドキュメントだけだとわからないので、一つ一つ実験していかなければならないのがつらいところです。
とはいえ、これで記事ごとに画像を管理することができ、directory_indexes
、:asset_hash
を使え、より管理しやすい構成になります。参考にして頂ければと思います。
参考
- Markdown image location
- The secret to referencing Middleman’s asset_hash-ed assets
- Middleman and relative images