Contents

Add time line in hugo website

Expected result

Step 1. Add scss file _custom.scss under static/css/

  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
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/************************************
timeline
************************************/

/* The actual timeline (the vertical ruler) */
.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: 22px;
  z-index: 1;
  left: -10%;
  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: #16c4a4;
  text-align: right;
  position: absolute;
  top: 0;
  right: 0;
  padding: 5px;
}

/* body size */
.timeline .content .body {
  padding: 5px 30px;
}

/* 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;
  }
}

Step 2. Add event.html under layouts/shortcodes

 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
53
54
55
56
57
58
{{$duration := ""}}
{{$to := now }}
{{ if ne (.Get "to") ""}}
  {{$to = time (.Get "to") }}
{{end}}
{{$enabledTime := ne (.Get "from") ""}}
{{if $enabledTime }}
  {{$from := time (.Get "from") }}
  {{$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}}

  {{$duration = ""}}
  {{if gt $years 0 }}{{$duration = printf "%s %.0f %s" $duration $years $yearStr}}{{end}}
  {{if gt $months 0 }}{{$duration = printf "%s %d %s" $duration $months $monthStr}}{{end}}
{{end}}

<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 }} {{$duration}} {{ end }}
    </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
  }

  el = document.querySelector("#moment");
  function refresh() {
    start = dayjs({{.Get "from"}})
    now = dayjs()

    total_months = now.diff(start, "M", true)
    months = total_months % 12
    years = Math.floor((total_months) / 12)
    el.innerHTML = non0plural(years,"year")+" "+non0plural(months.toFixed(8),"month")
  }
  window.setInterval(refresh, 100);
</script>
{{ end }}

Step 3. Add timeline.html under layouts/shortcodes

1
<div class="timeline">{{ .Inner }}</div>

Step 4. Add the time line content in your md file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
{{< timeline >}}

  {{< event title="XXX Inc." from="2022-10-01">}}
    Current position
  {{< /event >}}
  <br>
  {{< event title="YYY Inc." from="2020-07-01" to="2021-04-01">}}
    Past position
  {{< /event >}}
{{< /timeline >}}