同じような記述を繰り返す一覧のコーディングってめんどくさいですよね。
たくさんコーディングした後に HTML の構造を変える必要が出てくるとイラッとします。
Pug のループ処理を利用すると、こんなイライラともおさらばです。
また、HTML タグを1回記述するだけで済むので、HTML の構文エラーも少なくなります。
というわけで、よく利用するループ処理をまとめてみました!
基本編
for
指定回数をループさせるには JavaScript の for
を利用します。
文頭に半角ハイフン -
をつけることで、JavaScript のコードとして実行します。
Pug
ul
- for (var i = 1; i < 4; i++)
li リスト#{i}
HTML(コンパイル結果)
<ul>
<li>リスト1</li>
<li>リスト2</li>
<li>リスト3</li>
</ul>
each in
配列要素をループさせるには each in
を利用します。
Pug の構文のため、文頭に半角ハイフン -
をつけずに使用可能です。
配列
Pug
ul
- const list = ['1','2','3']
each item in list
li リスト#{item}
HTML(コンパイル結果)
<ul>
<li>リスト1</li>
<li>リスト2</li>
<li>リスト3</li>
</ul>
連想配列
Pug
ul
-
const list = [
{
num: 1,
text: 'ほげほげ',
},
{
num: 2,
text: 'ふがふが',
},
{
num: 3,
text: 'ぴよぴよ',
},
]
each item in list
li リスト#{item.num} : #{item.text}
HTML(コンパイル結果)
<ul>
<li>リスト1 : ほげほげ</li>
<li>リスト2 : ふがふが</li>
<li>リスト3 : ぴよぴよ</li>
</ul>
応用編
画像のリスト
画像名が連番
Pug
ul
- const altList = ['ほげほげ', 'ふがふが', 'ぴよぴよ']
each alt, index in altList
- const imageNum = ('00' + (index + 1)).slice(-2)
li
img(src=`${imageNum}.jpg` alt=`${alt}`)
HTML(コンパイル結果)
<ul>
<li><img src="01.jpg" alt="ほげほげ"></li>
<li><img src="02.jpg" alt="ふがふが"></li>
<li><img src="03.jpg" alt="ぴよぴよ"></li>
</ul>
画像名が文字列
Pug
ul
-
const imageList = [
{
filename: 'hogehoge',
alt: 'ほげほげ',
},
{
filename: 'fugafuga',
alt: 'ふがふが',
},
{
filename: 'piyopiyo',
alt: 'ぴよぴよ',
},
]
each image in imageList
li
img(src=`${image.filename}.jpg` alt=`${image.alt}`)
HTML(コンパイル結果)
<ul>
<li><img src="hogehoge.jpg" alt="ほげほげ"></li>
<li><img src="fugafuga.jpg" alt="ふがふが"></li>
<li><img src="piyopiyo.jpg" alt="ぴよぴよ"></li>
</ul>
画像とキャプションのリスト
画像の alt
属性にキャプションと同じ内容を設定すると冗長なため空にしています。
画像名が連番
Pug
ul
- const captionList = ['ほげほげ', 'ふがふが', 'ぴよぴよ']
each caption, index in captionList
- const imageNum = ('00' + (index + 1)).slice(-2)
li
img(src=`${imageNum}.jpg` alt=``)
if caption !== ''
span #{caption}
HTML(コンパイル結果)
<ul>
<li>
<img src="01.jpg" alt="">
<span>ほげほげ</span>
</li>
<li>
<img src="02.jpg" alt="">
<span>ふがふが</span>
</li>
<li>
<img src="03.jpg" alt="">
<span>ぴよぴよ</span>
</li>
</ul>
画像名が文字列
Pug
ul
-
const imageList = [
{
filename: 'hogehoge',
caption: 'ほげほげ',
},
{
filename: 'fugafuga',
caption: 'ふがふが',
},
{
filename: 'piyopiyo',
caption: 'ぴよぴよ',
},
]
each image in imageList
li
img(src=`${image.filename}.jpg` alt=``)
if image.caption !== ''
span #{image.caption}
HTML(コンパイル結果)
<ul>
<li>
<img src="hogehoge.jpg" alt="">
<span>ほげほげ</span>
</li>
<li>
<img src="fugafuga.jpg" alt="">
<span>ふがふが</span>
</li>
<li>
<img src="piyopiyo.jpg" alt="">
<span>ぴよぴよ</span>
</li>
</ul>
お知らせのリスト
お知らせの仕様は以下とします。
- Newアイコン
- class属性に
is-new
を設定
- class属性に
- リンクに
target="_blank"
を設定- 外部リンク
* リンク文字列の先頭がhttp
- pdfファイルへのリンク
- リンク文字列の末尾が
.pdf
- リンク文字列の末尾が
- 外部リンク
- リンクがない場合はテキストのみ表示
Pug
-
const newsList = [
{
isNew: true,
date: '2022年4月4日',
text: 'Newアイコンを表示',
link: '/news.html'
},
{
isNew: false,
date: '2022年3月3日',
text: '外部リンク',
link: 'https://www.google.com/'
},
{
isNew: false,
date: '2022年2月2日',
text: 'PDFリンク',
link: '/news.pdf'
},
{
isNew: false,
date: '2022年1月1日',
text: 'リンクなし',
link: ''
},
]
each news in newsList
-
const isExternalLink = /^http/.test(news.link)
const isPdfLink = /\.pdf$/.test(news.link)
const newClass = news.isNew ? 'is-new' : ''
const target = isPdfLink || isExternalLink ? '_blank' : false
mixin newsBody
p #{news.date}
p #{news.text}
article(class=newClass)
if news.link
a(href=news.link target=target)
+newsBody
else
+newsBody
HTML(コンパイル結果)
<article class="is-new">
<a href="/news.html">
<p>2022年4月4日</p>
<p>Newアイコンを表示</p>
</a>
</article>
<article>
<a href="https://www.google.com/" target="_blank">
<p>2022年3月3日</p>
<p>外部リンク</p>
</a>
</article>
<article>
<a href="/news.pdf" target="_blank">
<p>2022年2月2日</p>
<p>PDFリンク</p>
</a>
</article>
<article>
<p>2022年1月1日</p>
<p>リンクなし</p>
</article>
年ごとに見出しを追加
Pug
-
const newsList = [
{
isNew: true,
date: '2022年4月4日',
text: 'Newアイコンを表示',
link: '/news.html'
},
{
isNew: false,
date: '2022年3月3日',
text: '外部リンク',
link: 'https://www.google.com/'
},
{
isNew: false,
date: '2022年2月2日',
text: 'PDFリンク',
link: '/news.pdf'
},
{
isNew: false,
date: '2022年1月1日',
text: 'リンクなし',
link: ''
},
{
isNew: false,
date: '2021年1月1日',
text: 'リンクなし',
link: ''
},
{
isNew: false,
date: '2020年1月1日',
text: 'リンクなし',
link: ''
},
]
const yearList = []
for (const news of newsList) {
const year = news.date.slice(0, 4);
if (yearList.includes(year)) continue;
yearList.push(year)
}
each year in yearList
section
h2 #{year}年
each news in newsList
if news.date.includes(year)
-
const isExternalLink = /^http/.test(news.link)
const isPdfLink = /\.pdf$/.test(news.link)
const newClass = news.isNew ? 'is-new' : ''
const target = isPdfLink || isExternalLink ? '_blank' : false
mixin newsBody
p #{news.date}
p #{news.text}
article(class=newClass)
if news.link
a(href=news.link target=target)
+newsBody
else
+newsBody
HTML(コンパイル結果)
<section>
<h2>2022年</h2>
<article class="is-new">
<a href="/news.html">
<p>2022年4月4日</p>
<p>Newアイコンを表示</p>
</a>
</article>
<article>
<a href="https://www.google.com/" target="_blank">
<p>2022年3月3日</p>
<p>外部リンク</p>
</a>
</article>
<article>
<a href="/news.pdf" target="_blank">
<p>2022年2月2日</p>
<p>PDFリンク</p>
</a>
</article>
<article>
<p>2022年1月1日</p>
<p>リンクなし</p>
</article>
</section>
<section>
<h2>2021年</h2>
<article>
<p>2021年1月1日</p>
<p>リンクなし</p>
</article>
</section>
<section>
<h2>2020年</h2>
<article>
<p>2020年1月1日</p>
<p>リンクなし</p>
</article>
</section>