Skip to content

Commit 8fe5bed

Browse files
committed
ui update
1 parent 43b9e0c commit 8fe5bed

4 files changed

Lines changed: 329 additions & 25 deletions

File tree

my-site/_config.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,14 @@ url: "https://leo0331.github.io"
77
theme: minima
88
plugins:
99
- jekyll-feed
10+
11+
home_curation:
12+
pinned_titles:
13+
- "投資思考 04"
14+
- "投資思考 03"
15+
- "投資思考 02"
16+
- "投資思考 01"
17+
headline_initial: 6
18+
headline_max: 24
19+
latest_initial: 9
20+
latest_max: 24

my-site/_layouts/home.html

Lines changed: 190 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ <h1>{{ site.title }}</h1>
1111
<a href="#lead">封面故事</a>
1212
<a href="#headlines">焦點新聞</a>
1313
<a href="#latest">最新文章</a>
14+
<a href="{{ '/investing-thoughts/' | relative_url }}">投資思考專欄</a>
1415
<a href="{{ '/archive/' | relative_url }}">文章彙整</a>
1516
<a href="{{ '/about/' | relative_url }}">關於本站</a>
1617
</nav>
@@ -24,6 +25,9 @@ <h1>{{ site.title }}</h1>
2425
{% assign featured = site.posts.first %}
2526
{% endunless %}
2627
{% assign non_featured_posts = site.posts | where_exp: "post", "post.url != featured.url" %}
28+
{% assign pinned_titles = site.home_curation.pinned_titles | default: empty %}
29+
{% assign editor_selected = '|' %}
30+
{% assign headline_selected = '|' %}
2731

2832
{% if featured %}
2933
{% assign featured_parts = featured.content | split: 'src="' %}
@@ -51,57 +55,183 @@ <h2><a href="{{ featured.url | relative_url }}">{{ featured.title }}</a></h2>
5155

5256
<div class="lead-side">
5357
<h3>編輯精選</h3>
54-
{% for post in non_featured_posts limit:3 %}
55-
{% assign side_parts = post.content | split: 'src="' %}
56-
{% if side_parts.size > 1 %}
57-
{% assign side_image = side_parts[1] | split: '"' | first %}
58-
{% else %}
59-
{% assign side_image = nil %}
58+
{% assign editor_count = 0 %}
59+
60+
{% for pinned_title in pinned_titles %}
61+
{% if editor_count >= 5 %}
62+
{% break %}
6063
{% endif %}
64+
{% assign pinned_post = non_featured_posts | where: "title", pinned_title | first %}
65+
{% if pinned_post %}
66+
{% assign pinned_key = '|' | append: pinned_post.url | append: '|' %}
67+
{% unless editor_selected contains pinned_key %}
68+
{% assign side_parts = pinned_post.content | split: 'src="' %}
69+
{% if side_parts.size > 1 %}
70+
{% assign side_image = side_parts[1] | split: '"' | first %}
71+
{% else %}
72+
{% assign side_image = nil %}
73+
{% endif %}
74+
75+
<article class="mini-story">
76+
{% if side_image %}
77+
<a class="mini-media" href="{{ pinned_post.url | relative_url }}" aria-label="{{ pinned_post.title | escape }}">
78+
<img src="{{ side_image }}" alt="{{ pinned_post.title | escape }}" loading="lazy" decoding="async" width="92" height="72" />
79+
</a>
80+
{% endif %}
81+
<div>
82+
<p class="meta">{{ pinned_post.date | date: "%Y-%m-%d" }}</p>
83+
<h4><a href="{{ pinned_post.url | relative_url }}">{{ pinned_post.title }}</a></h4>
84+
</div>
85+
</article>
86+
{% assign editor_selected = editor_selected | append: pinned_post.url | append: '|' %}
87+
{% assign editor_count = editor_count | plus: 1 %}
88+
{% endunless %}
89+
{% endif %}
90+
{% endfor %}
6191

62-
<article class="mini-story">
63-
{% if side_image %}
64-
<a class="mini-media" href="{{ post.url | relative_url }}" aria-label="{{ post.title | escape }}">
65-
<img src="{{ side_image }}" alt="{{ post.title | escape }}" loading="lazy" decoding="async" width="92" height="72" />
66-
</a>
92+
{% for post in non_featured_posts %}
93+
{% if editor_count >= 5 %}
94+
{% break %}
95+
{% endif %}
96+
{% assign post_key = '|' | append: post.url | append: '|' %}
97+
{% if post.title contains '投資思考' %}
98+
{% unless editor_selected contains post_key %}
99+
{% assign side_parts = post.content | split: 'src="' %}
100+
{% if side_parts.size > 1 %}
101+
{% assign side_image = side_parts[1] | split: '"' | first %}
102+
{% else %}
103+
{% assign side_image = nil %}
67104
{% endif %}
68-
<div>
69-
<p class="meta">{{ post.date | date: "%Y-%m-%d" }}</p>
70-
<h4><a href="{{ post.url | relative_url }}">{{ post.title }}</a></h4>
71-
</div>
72-
</article>
105+
106+
<article class="mini-story">
107+
{% if side_image %}
108+
<a class="mini-media" href="{{ post.url | relative_url }}" aria-label="{{ post.title | escape }}">
109+
<img src="{{ side_image }}" alt="{{ post.title | escape }}" loading="lazy" decoding="async" width="92" height="72" />
110+
</a>
111+
{% endif %}
112+
<div>
113+
<p class="meta">{{ post.date | date: "%Y-%m-%d" }}</p>
114+
<h4><a href="{{ post.url | relative_url }}">{{ post.title }}</a></h4>
115+
</div>
116+
</article>
117+
{% assign editor_selected = editor_selected | append: post.url | append: '|' %}
118+
{% assign editor_count = editor_count | plus: 1 %}
119+
{% endunless %}
120+
{% endif %}
121+
{% endfor %}
122+
123+
{% for post in non_featured_posts %}
124+
{% if editor_count >= 5 %}
125+
{% break %}
126+
{% endif %}
127+
{% assign post_key = '|' | append: post.url | append: '|' %}
128+
{% unless editor_selected contains post_key %}
129+
{% assign side_parts = post.content | split: 'src="' %}
130+
{% if side_parts.size > 1 %}
131+
{% assign side_image = side_parts[1] | split: '"' | first %}
132+
{% else %}
133+
{% assign side_image = nil %}
134+
{% endif %}
135+
136+
<article class="mini-story">
137+
{% if side_image %}
138+
<a class="mini-media" href="{{ post.url | relative_url }}" aria-label="{{ post.title | escape }}">
139+
<img src="{{ side_image }}" alt="{{ post.title | escape }}" loading="lazy" decoding="async" width="92" height="72" />
140+
</a>
141+
{% endif %}
142+
<div>
143+
<p class="meta">{{ post.date | date: "%Y-%m-%d" }}</p>
144+
<h4><a href="{{ post.url | relative_url }}">{{ post.title }}</a></h4>
145+
</div>
146+
</article>
147+
{% assign editor_selected = editor_selected | append: post.url | append: '|' %}
148+
{% assign editor_count = editor_count | plus: 1 %}
149+
{% endunless %}
73150
{% endfor %}
74151
</div>
75152
</section>
76153
{% endif %}
77154

78155
<section id="headlines" class="headline-ribbon">
79156
<h3>焦點新聞</h3>
80-
<ul>
81-
{% for post in non_featured_posts offset:3 limit:6 %}
82-
<li>
83-
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
84-
<span>{{ post.date | date: "%Y-%m-%d" }}</span>
85-
</li>
157+
{% assign headline_initial = site.home_curation.headline_initial | default: 6 %}
158+
{% assign headline_max = site.home_curation.headline_max | default: 24 %}
159+
{% assign headline_count = 0 %}
160+
{% assign headline_selected = editor_selected %}
161+
162+
<ul class="js-paginated-list" data-batch="{{ headline_initial }}">
163+
{% for post in non_featured_posts %}
164+
{% if headline_count >= headline_max %}
165+
{% break %}
166+
{% endif %}
167+
{% assign is_travel_or_practical = false %}
168+
{% if post.title contains '遊記' or post.categories contains '實用' %}
169+
{% assign is_travel_or_practical = true %}
170+
{% endif %}
171+
{% assign post_key = '|' | append: post.url | append: '|' %}
172+
{% if is_travel_or_practical %}
173+
{% unless headline_selected contains post_key %}
174+
<li class="paged-item{% if headline_count >= headline_initial %} is-collapsed{% endif %}">
175+
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
176+
<span>{{ post.date | date: "%Y-%m-%d" }}</span>
177+
</li>
178+
{% assign headline_selected = headline_selected | append: post.url | append: '|' %}
179+
{% assign headline_count = headline_count | plus: 1 %}
180+
{% endunless %}
181+
{% endif %}
182+
{% endfor %}
183+
184+
{% for post in non_featured_posts %}
185+
{% if headline_count >= headline_max %}
186+
{% break %}
187+
{% endif %}
188+
{% assign post_key = '|' | append: post.url | append: '|' %}
189+
{% unless headline_selected contains post_key %}
190+
<li class="paged-item{% if headline_count >= headline_initial %} is-collapsed{% endif %}">
191+
<a href="{{ post.url | relative_url }}">{{ post.title }}</a>
192+
<span>{{ post.date | date: "%Y-%m-%d" }}</span>
193+
</li>
194+
{% assign headline_selected = headline_selected | append: post.url | append: '|' %}
195+
{% assign headline_count = headline_count | plus: 1 %}
196+
{% endunless %}
86197
{% endfor %}
87198
</ul>
199+
200+
{% if headline_count > headline_initial %}
201+
<div class="section-actions">
202+
<button type="button" class="load-more-btn js-load-more" data-target="#headlines .js-paginated-list">
203+
載入更多焦點新聞
204+
</button>
205+
</div>
206+
{% endif %}
88207
</section>
89208

90209
<section id="latest" class="latest-grid">
91210
<div class="section-head">
92211
<h3>最新文章</h3>
93212
<a href="{{ '/archive/' | relative_url }}" class="section-link">查看全部</a>
94213
</div>
95-
<div class="post-cards">
96-
{% for post in non_featured_posts offset:9 limit:9 %}
214+
215+
{% assign latest_initial = site.home_curation.latest_initial | default: 9 %}
216+
{% assign latest_max = site.home_curation.latest_max | default: 24 %}
217+
{% assign latest_count = 0 %}
218+
{% assign curated_selected = editor_selected | append: headline_selected %}
219+
220+
<div class="post-cards js-paginated-list" data-batch="{{ latest_initial }}">
221+
{% for post in non_featured_posts %}
222+
{% if latest_count >= latest_max %}
223+
{% break %}
224+
{% endif %}
225+
{% assign post_key = '|' | append: post.url | append: '|' %}
226+
{% unless curated_selected contains post_key %}
97227
{% assign card_parts = post.content | split: 'src="' %}
98228
{% if card_parts.size > 1 %}
99229
{% assign card_image = card_parts[1] | split: '"' | first %}
100230
{% else %}
101231
{% assign card_image = nil %}
102232
{% endif %}
103233

104-
<article class="post-card">
234+
<article class="post-card paged-item{% if latest_count >= latest_initial %} is-collapsed{% endif %}">
105235
{% if card_image %}
106236
<a class="card-media" href="{{ post.url | relative_url }}" aria-label="{{ post.title | escape }}">
107237
<img src="{{ card_image }}" alt="{{ post.title | escape }}" loading="lazy" decoding="async" width="400" height="260" />
@@ -113,8 +243,18 @@ <h4><a href="{{ post.url | relative_url }}">{{ post.title }}</a></h4>
113243
<p>{{ post.excerpt | strip_html | normalize_whitespace | truncate: 120 }}</p>
114244
</div>
115245
</article>
246+
{% assign latest_count = latest_count | plus: 1 %}
247+
{% endunless %}
116248
{% endfor %}
117249
</div>
250+
251+
{% if latest_count > latest_initial %}
252+
<div class="section-actions">
253+
<button type="button" class="load-more-btn js-load-more" data-target="#latest .js-paginated-list">
254+
載入更多最新文章
255+
</button>
256+
</div>
257+
{% endif %}
118258
</section>
119259
</main>
120260

@@ -172,3 +312,28 @@ <h3>年度文章</h3>
172312
</aside>
173313
</div>
174314
</div>
315+
316+
<script>
317+
document.addEventListener('DOMContentLoaded', function () {
318+
var buttons = document.querySelectorAll('.js-load-more');
319+
320+
buttons.forEach(function (button) {
321+
button.addEventListener('click', function () {
322+
var selector = button.getAttribute('data-target');
323+
var list = selector ? document.querySelector(selector) : null;
324+
if (!list) return;
325+
326+
var batch = parseInt(list.getAttribute('data-batch') || '6', 10);
327+
var hidden = list.querySelectorAll('.paged-item.is-collapsed');
328+
329+
for (var i = 0; i < hidden.length && i < batch; i += 1) {
330+
hidden[i].classList.remove('is-collapsed');
331+
}
332+
333+
if (list.querySelectorAll('.paged-item.is-collapsed').length === 0) {
334+
button.style.display = 'none';
335+
}
336+
});
337+
});
338+
});
339+
</script>

my-site/assets/main.scss

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,73 @@ h5,
463463
line-height: 1.25;
464464
}
465465

466+
.section-actions {
467+
margin-top: 0.85rem;
468+
text-align: center;
469+
}
470+
471+
.load-more-btn {
472+
border: 1px solid color-mix(in srgb, var(--accent) 35%, white 65%);
473+
background: var(--accent-soft);
474+
color: var(--ink);
475+
padding: 0.45rem 0.8rem;
476+
border-radius: 999px;
477+
font-size: 0.86rem;
478+
font-weight: 600;
479+
cursor: pointer;
480+
}
481+
482+
.load-more-btn:hover {
483+
background: var(--accent);
484+
color: #fff;
485+
}
486+
487+
.paged-item.is-collapsed {
488+
display: none;
489+
}
490+
491+
.investing-series-list .series-badge {
492+
margin: 0.2rem 0 0.5rem;
493+
display: inline-block;
494+
border-radius: 999px;
495+
background: var(--accent-soft);
496+
border: 1px solid color-mix(in srgb, var(--accent) 22%, white 78%);
497+
padding: 0.18rem 0.58rem;
498+
font-size: 0.78rem;
499+
color: #3f3a33;
500+
}
501+
502+
.series-nav {
503+
margin-top: 0.7rem;
504+
display: flex;
505+
gap: 0.45rem;
506+
}
507+
508+
.series-nav-btn {
509+
display: inline-flex;
510+
align-items: center;
511+
justify-content: center;
512+
border-radius: 999px;
513+
border: 1px solid color-mix(in srgb, var(--accent) 28%, white 72%);
514+
background: var(--accent-soft);
515+
color: var(--ink);
516+
text-decoration: none;
517+
font-size: 0.8rem;
518+
font-weight: 600;
519+
padding: 0.24rem 0.6rem;
520+
min-width: 4.8rem;
521+
}
522+
523+
.series-nav-btn:hover {
524+
background: var(--accent);
525+
color: #fff;
526+
}
527+
528+
.series-nav-btn.is-disabled {
529+
opacity: 0.5;
530+
pointer-events: none;
531+
}
532+
466533
.category-index-list {
467534
list-style: none;
468535
margin: 0;

0 commit comments

Comments
 (0)