现在使用hugo-theme-learn主题,但这个主题没有提供时间线功能,为了给首页增加时间线功能,花了两天研究了一下怎么添加时间线功能。
为了方便增加时间线的事件,采用自定义shortcode的方式增加时间线,代码大部分参考引用链接里面的,魔改了一下以适应自己的主题,增加了过去多少天的显示。
在layout/shortcodes新增文件:event.html和timeline.html,内容分别如下
event.html
{{$duration := ""}}
{{$to := now }}
{{ if ne (.Get "to") ""}}
{{$to = time (.Get "to") }}
{{end}}
{{$enabledTime := ne (.Get "from") ""}}
{{if $enabledTime }}
{{$from := time (.Get "from") }}
{{ $diff := $to.Sub $from }}
{{ $days := div $diff.Hours 24 | math.Round }}
{{$tmonths:=mul ($to.Sub $from).Hours 0.00136986301 }}
{{$months := mod $tmonths 12 }}
{{$years := math.Floor (div $tmonths 12)}}
{{$yearStr := "years"}}
{{if lt $years 2 }}
{{$yearStr = "year"}}
{{end}}
{{$monthStr := "months"}}
{{if lt $months 2 }}
{{$monthStr = "month"}}
{{end}}
{{$daysStr := "days"}}
{{ $idays :=int $days }}
{{$duration = ""}}
{{if gt $years 0 }}
{{$duration = printf "%s %.0f %s" $duration $years $yearStr}}
{{$idays = sub $idays (mul 365 $years)}}
{{end}}
{{if gt $months 0 }}
{{$duration = printf "%s %d %s" $duration $months $monthStr}}
{{$idays = sub $idays (mul 30 $months)}}
{{end}}
{{$idays = int $idays}}
{{if gt $idays 0}}
{{if lt $idays 2}}
{{$daysStr = "day"}}
{{end}}
{{$duration = printf "%s %d %s" $duration $idays $daysStr}}
{{end}}
{{end}}
{{ $from := .Get "from" | time }}
{{ $to := now }}
{{ $diff := $to.Sub $from }}
{{ $ago := div $diff.Hours 24 | math.Round }}
{{ $measure := cond (eq 1 $ago) "day" "days" }}
{{ $seed := "foo" }}
{{ $random := delimit (shuffle (split (md5 $seed) "" )) "" }}
<div class="container">
<div class="content">
<div class="title">{{.Get "title"}}</div>
{{if $enabledTime }}
<div class="moment" {{ if eq .Ordinal 0 }} id="moment" {{ end }} {{ if ne .Ordinal 0 }}id="moment-{{ substr $random 0 16}}"{{end}}>
{{ if ne .Ordinal 0 }} {{$duration}} {{ end }} | {{ $ago }} {{ $measure}} ago
</div>
{{ end }}
<div class="body">
{{.Inner}}
</div>
</div>
<div class="date">{{$to.Year}}</div>
</div>
{{ if and (eq (.Ordinal) 0) $enabledTime }}
<script>
function non0plural(number, name) {
if (number == 0) {
return ""
}
if (number > 1) {
return number + " " + name + "s"
}
return number + " " + name
}
function refresh() {
start = dayjs({{.Get "from"}})
now = dayjs()
total_days = now.diff(start,"d",true)
total_months = now.diff(start, "M", true)
months = total_months % 12
years = Math.floor((total_months) / 12)
// for (var i = 0, els = document.querySelectorAll(`[id^="moment"]`); i < els.length; i++) {
// els[i].innerHTML = non0plural(years, "year") + " " + non0plural(months.toFixed(8), "month")
// }
// 如果月份大于1则
if(years>=1){
total_days-=365*years
}
if(months>=1){
total_days-=30*months
}
el = document.querySelector("#moment");
el.innerHTML = years>1? non0plural(years, "year"):"" + " " + months>1? non0plural(months.toFixed(4), "month"):"" + total_days>=1?non0plural(total_days.toFixed(2),"day"):""
el.innerHTML = el.innerHTML + " ago"
}
window.setInterval(refresh, 100);
</script>
{{ end }}
timeline.html
<style type="text/css">
.timeline {
position: relative;
margin: 0 auto;
}
/* The actual timeline (the vertical ruler) */
.timeline::after {
content: "";
position: absolute;
width: 6px;
background-color: #444;
top: 0;
bottom: 0;
left: 10%;
margin-left: -3px;
}
/* Container around content */
.timeline .container {
padding: 10px 10px 10px 40px;
margin-top: 10px;
position: relative;
/* background-color: gray; */
width: 90%;
left: 10%;
}
/* The circles on the timeline */
.timeline .container::after {
content: "";
position: absolute;
width: 25px;
height: 25px;
left: -12px;
background-color: rgb(106, 215, 229);
border: 4px solid #444;
top: 0px;
border-radius: 50%;
z-index: 1;
}
/* date display */
.timeline .container .date {
position: absolute;
top: 0px;
z-index: 1;
left: -15%;
font-size: large;
}
/* Add arrows to the right container (pointing left) */
.timeline .container::before {
content: " ";
height: 0;
position: absolute;
top: 30px;
width: 0;
z-index: 1;
left: 26px;
border: medium solid #6ad7e5;
border-width: 13px 13px 13px 0px;
border-color: #6ad7e5 #6ad7e5 transparent transparent;
}
/* The actual content */
.timeline .content {
box-shadow: 0 0 3px 3px #6ad7e5;
background-color: white;
position: relative;
border-radius: 6px;
transition: box-shadow 0.3s;
}
/* small shadow change on hover*/
.timeline .content:hover {
box-shadow: 0 0 3px 4px #6ad7e5;
}
/* card title format */
.timeline .content .title {
padding: 5px 30px;
font-weight: bold;
display: inline-block;
}
/* time moment format*/
.timeline .content .moment {
color: #c41a16;
text-align: right;
position: absolute;
top: 0;
right: 0;
padding: 5px;
}
/* body size */
.timeline .content .body {
padding: 5px 30px;
word-wrap: break-word;
/* height: 73px; */
/* max-height: 120px; */
text-overflow: ellipsis;
overflow: hidden;
}
/* responsive for small devices*/
@media screen and (max-width: 600px) {
.timeline .container {
padding: 10px 10px 0px 40px;
left: 5%;
width: 95%;
}
.timeline .container .date {
font-size: small;
transform: rotate(-90deg);
left: -5%;
top: 30px;
}
.timeline .container::after {
left: 3px;
}
.timeline .content .body {
padding: 5px 5px;
}
.timeline .content .moment {
position: relative;
}
}
</style>
<div class="timeline">
{{ .Inner }}
</div>
由于event.html里面引用了dayjs,这个js不在当前主题内,可以在config.toml新增custom_js = ["js/dayjs.min.js"],然后把dayjs.min.js放在theme\hugo-theme-learn\static\js目录内,即可解决导入dayjs的问题。
此时可以在需要添加时间线的地方使用timeline的shortcode添加,以下是我博客首页的时间线代码:
{{< timeline >}}
{{% event title="09-03至09-04" from="2022-09-03" to="2022-09-04" %}}
这两天,给hugo主题增加了timeline的shortcode,见[增加timeline功能](others/add-timeline-shortcode)
{{% /event %}}
{{% event title="08-29至09-02" from="2022-08-29" to="2022-09-02" %}}
周内审计了代码
{{% /event %}}
{{< /timeline >}}
除了这个还顺便给博客新增了基于Github issue的评论功能,参考 utteranc。
参考
https://metalblueberry.github.io/post/howto/2021-02-28_hugo_timeline_shortcode/