Perron
Published at 2026/03/24
Perron でブログをつくる
1. アプリ作成
rails new <appname> --minimal -T -O -m https://perron.railsdesigner.com/library/new/template.rb
Markdownパーサーを聞かれるので kramdown を入力:
Which markdown parser would you like to use? kramdown
2. ディレクトリ移動
cd <appname>
3. テンプレート導入
rails app:template LOCATION='https://perron.railsdesigner.com/library/personal-blog/template.rb'
4. ビューの不要な記述を削除
app/views/shared/_navigation.html.erb から下記を削除
<ul class="flex items-center gap-x-4 sm:gap-x-6">
<%= render partial: "shared/navigation/item", collection: items %>
</ul>
app/views/content/posts/show.html.erb から下記を削除
<%= link_to "← View all my writings", posts_path, class: "text-sm font-sans font-normal text-gray-500 transition hover:text-gray-800" %>
<section id="comments" class="mt-8 max-w-4xl mx-auto">
<chirp-form form-id="ADD_YOUR_CHIRP_FORM_ID_HERE" button-text="Add comment" class="grid gap-y-4 p-2">
<header slot="header">
<h2 class="text-lg font-bold tracking-tight text-slate-800 md:text-xl">
Comments
</h2>
<p class="mt-0.5 text-base text-slate-600">
What do you think? Got ideas or suggestions? Let me know below.
</p>
</header>
</chirp-form>
<p class="mt-2 px-2 text-xs text-slate-500">
Comments are powered by <a href="https://chirpform.com/?ref=<%= Rails.application.name %>" rel="nofollow">Chirp Form</a></p>
</p>
<chirp-feed form-id="ADD_YOUR_CHIRP_FORM_ID_HERE" filter-url="current" class="grid gap-y-4 mt-4 py-4 border-t border-slate-100">
<template type="style">
.content + .content {
padding-block-start: .875rem;
border-top: 1px solid #f1f5f9;
}
.header {
display: flex;
justify-content: space-between;
}
.name {
font-size: .875rem;
font-weight: 500;
color: #64748b;
}
.time {
font-size: .75rem;
color: #94a3b8
}
.comment {
margin: 0;
font-size: 1rem;
color: #0f172a
}
</template>
<template type="submission">
<article class="content">
<header class="header">
<strong class="name">{{name}}</strong>
<time class="time">{{created_at}}</time>
</header>
<p class="comment">{{comment}}</p>
</article>
</template>
</chirp-feed>
</section>
5. outputフォルダを.gitignoreから削除
# grep して output が表示されるかの確認
cat .gitignore\|grep output
# output が書かれてたら削除して保存
nano .gitignore
# nano で開いてoutput を削除して保存
cat .gitignore\|grep output
6. Timezone修正
app/config/application.rb を修正
config.time_zone = "Tokyo"
7. CSSを整える
7-1. app/assets/tailwind/application.css に追記
@import "tailwindcss";
@theme {
--font-sans: "Helvetica Neue", "Arial", "Hiragino Kaku Gothic ProN W6", "Hiragino Sans", "BIZ UDPGothic", "Meiryo", "apple-system", "BlinkMacSystemFont", sans-serif;
--font-serif: "YuMincho", "Hiragino Mincho ProN", serif;
}
/* 既存のスタイル... */
@layer component {
.content {
@apply [&_*+h2,&_*+h3]:mt-8;
@apply [&_*+h4,&_*+h5,&_*+h6]:mt-4;
@apply [pre]:mt-5;
@apply [blockquote]:mt-5;
/* 下記の2行をコメントアウト */
/* @apply [&_*:not(h1,h2,h3,h4,h5,h6)+*:not(pre,code,li,blockquote>p,svg),blockquote+pre]:mt-5; */
/* @apply [&_h1+p,&_h2+p,&_h3+p,&_h4+p,&_h5+p,&_h6+p]:mt-1.5; */
/* 既存のスタイル... */
/* コードブロック */
@apply [&_pre]:bg-gray-100 [&_pre]:relative;
@apply [&_pre]:pt-8; /* 言語ラベルの分の余白 */
& *+pre {
@apply mt-2; /* preの上の要素とのスペース */
}
& pre+* {
@apply mt-7; /* preの下の要素とのスペース */
}
/* リスト */
li {
color: var(--color-stone-500);
}
li a {
font-weight: var(--font-weight-bold);
color: var(--color-stone-800);
}
/*段落*/
p {
@apply text-gray-500;
@apply text-base;
}
@apply [&_ul,&_ol]:space-y-1.5;
/* 引用ブロック */
blockquote {
@apply border-l-4 border-gray-500 my-8 pl-4 md:pl-8 py-4 mx-4 md:mx-10 max-w-md;
}
/* 引用本文 */
blockquote p {
@apply text-lg font-medium;
}
/* 引用元 */
blockquote p:has(cite) {
@apply text-right text-gray-600;
}
}
}
7-2. フォントを font-sans に変更
app/views/layouts/application.html.erb
<body class="font-sans antialiased">
8. コードブロックの調整
8-1. 複数行表示
kramdown はデフォルトの設定だとコードブロックが1行になる。
GFM(GitHub Flavored Markdown)モードにするとコードブロックの改行が保持される。
config/initializers/perron.rb に以下を追加する。
config.markdown_options = { input: "GFM" }
kramdownでGFMを使うには kramdown-parser-gfm gemが必要
下記を実行してインストール
bundle add kramdown-parser-gfm
8-2. コピーボタン設置
app/javascript/code_blocks.js を作成
document.addEventListener("DOMContentLoaded", () => {
document.querySelectorAll("pre code[class*='language-']").forEach((code) => {
const pre = code.parentElement;
const lang = code.className.replace("language-", "");
// 言語ラベル
const label = document.createElement("span");
label.textContent = lang;
label.className = "absolute top-0 left-3 text-xs text-gray-400 font-sans";
label.style.top = "0.25em";
label.style.marginTop = "0.25em";
pre.appendChild(label);
// コピーボタン
const button = document.createElement("button");
button.textContent = "Copy";
button.className = "absolute top-0 right-3 text-xs text-gray-400 font-sans hover:text-gray-700";
button.style.top = "0.25em";
button.style.marginTop = "0.25em";
button.addEventListener("click", () => {
navigator.clipboard.writeText(code.textContent).then(() => {
button.textContent = "Copied!";
setTimeout(() => button.textContent = "Copy", 2000);
});
});
pre.appendChild(button);
});
});
8-3. importmap の導入
rails new のときに –minimal していると importmap のインストールがスキップされる
JavaScript を使用する場合は、自分で入れる必要がある
8-3-1. importmap の install
bundle add importmap-rails
rails importmap:install
8-3-2. config/importmap.rb にJSファイルを登録
pin "application"
pin "code_blocks"
8-3-3. app/javascript/application.js に記載
import "code_blocks"
9. メタ文字をエスケープする
マークダウンリンクを取得すると「ページタイトル|サイト名」という形式になっていることがある。
マークダウンでは「|」が表のメタ文字なので、これをエスケープする必要がある。
app/helpers/application_helper.rb
def escape_markdown(text)
text.gsub(/(?<!\\)\|/, '\|')
end
10. index を最新順で表示する
file_path で降順ソートする
app/controllers/content/posts_controller.rb
def index
@resources = Content::Post.all.order(file_path: :desc)
end
11. root を posts#index に変更
app/config/routes.rb
# root to: "content/pages#root"
root to: "content/posts#index"
12. 起動して確認
bin/dev