java

【Spring Boot x Thymeleaf】foreach文で同じ要素を大量に作り出す(そして良い塩梅にif文を挟む)

mokabuu

おうち時間を有意義に過ごすために
皆さんはおうち時間をいかがお過ごしでしょうか?

我が家はもうダメです。

毎日「ひまだね〜」「やることないね〜」から1日が始まり、夜寝る前には「あれやればよかったね〜」「まあいっか、おやすみ〜」で1日が終わる自堕落な生活を送っております。

そこで、

  • その日やること(前日に書いたものが引き継がれる)
  • その日やったこと
  • その日の反省
  • 明日やること

を書き留められるwebアプリをイントラで動かし始めたのですが、その時に…

「投稿や編集の歴をタイムライン的に表示したい」
「自分が作成したものは編集できるけど、他人のものは編集できないようにしたい」

と言う仕様を実現するためにthymeleafをイジイジしたので、備忘も兼ねて記事を残したいと思います。


完成図
自分の投稿にはeditリンクがあり、他人の投稿にはeditリンクがない。


コード
Viewはこんな感じ。thymeleafで実装しています。

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
<div id="timeline" th:if="timelineList != null" style="margin-top: 64px;">
    <div th:each="d : ${timelineList}" class="container-fluid">
        <div class="mdl-card mdl-shadow--2dp" style="margin: auto; margin-top: 10px; min-width: 90%;">
            <div class="mdl-card__title" th:style="${d.category == 'TL_MSG'} ? 'background: #3498DB; color: #FFF; overflow: visible;' : 'background: #009688; color: #FFF; overflow: visible;'">
                <h2 class="mdl-card__title-text">
                    <img th:src="${d.picture}" style="width: 32px; height: 32px; margin-right: 4px;">
                    <span th:utext="${d.username}"></span>
                </h2>
            </div>
            <div class="mdl-card__supporting-text">
                <th:block th:if="${d.message}">
                    <th:block th:each="str, stat : ${d.message.split('\r\n|\r|\n', -1)}">
                        <th:block th:text="${str}" />
                        <br th:if="${!stat.last}" />
                    </th:block>
                </th:block>
                <p th:if="${d.otherid}!=0">
                    <a th:href="@{/open(repid=${d.otherid})}">open</a> /
                    <a th:if="${d.userid == userid}" th:href="@{/edit(repid=${d.otherid})}">edit</a>
                </p>
            </div>
            <div class="mdl-card__actions mdl-card--border" style="text-align: right;">
                <span style="font-size: 0.8em;" th:utext="${#dates.format(d.entryDate, 'yyyy/MM/dd HH:mm')}"></span>
            </div>
        </div>
    </div>
</div>

Controllerはこんな感じ。

1
2
3
4
5
6
7
8
9
10
11
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView index(@AuthenticationPrincipal OidcUser user, ModelAndView mav) {
    mav.setViewName("index");
    mav.addObject("message", "");
    mav.addObject("username", user.getFullName());
    mav.addObject("userid", user.getEmail());
    mav.addObject("picture", user.getPicture());
    List<TimelineContent> timelineContentList = timelineRepo.findAllByOrderByIdDesc();
    mav.addObject("timelineList", timelineContentList);
    return mav;
}

timelineListで渡したjava.util.Listから1件ずつforeachで中身を取り出してtimelineを作成しています。

1
<div th:each="d : ${timelineList}" class="container-fluid">

のところですね。

で、中身を取り出す際は

1
2
<img th:src="${d.picture}" style="width: 32px; height: 32px; margin-right: 4px;">
<span th:utext="${d.username}"></span>

と、してあげると取り出せます。

if文なんかも取り込めて、

1
<a th:if="${d.userid == userid}" th:href="@{/edit(repid=${d.otherid})}">edit</a>

と書いてあげて、投稿の作成者が自分だったら編集リンクを出すみたいなことをやっています。
※Java側にも編集者と作成者が一致していることを確認するロジックを入れてあげるとより安全だと思います。

if文は、もちろんこんな感じで書くこともできます。

1
<div class="mdl-card__title" th:style="${d.category == 'TL_MSG'} ? 'background: #3498DB;' : 'background: #009688;'">

投稿のカテゴリごとに、カードの背景色を変更するようにしています。
CSSは後から書くので許して・・・。


総括
実装は至ってシンプルなので、サンプルコードさえあれば迷わずにさくっと実装できるのではないかと思います。

って、ことで備忘も兼ねてコードを残しました。

[adsense]

Xからの読者コメントをお待ちしています。
ブログ更新の励みになります!
スポンサーリンク

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

ABOUT ME
mokabuu
mokabuu
ブログ管理人
2014年1月からmokabuu.comを運営しております。現在10年間で老朽化したサイトをリフォーム中です(2025/1〜)。
記事URLをコピーしました