@@ -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 >
0 commit comments