@@ -158,12 +158,16 @@ <h2 class="project-group-title">{{ category.title }}</h2>
158158 {%- if _badges -%} data-badges ='{{ _badges | jsonify }} '{%- endif -%}
159159 data-url-rel ='{{ _nav_url_rel }} '>
160160
161- < header class ="project-header ">
162- < a class ="project-title " href ="{{ _nav_url }} "> {{ _child.title }}</ a >
163- {%- if _badges -%}
164- {% include badges.html items=_badges %}
165- {%- endif -%}
166- </ header >
161+ < header class ="project-header ">
162+ < a class ="project-title " href ="{{ _nav_url }} "> {{ _child.title }}</ a >
163+
164+ {%- if _badges -%}
165+ < div class ="project-badges ">
166+ {% include badges.html items=_badges %}
167+ </ div >
168+ {%- endif -%}
169+ </ header >
170+
167171
168172 < p class ="project-desc ">
169173 {{ _child.description }}
@@ -174,33 +178,68 @@ <h2 class="project-group-title">{{ category.title }}</h2>
174178 {%- endfor -%}
175179 </ div >
176180
177- <!-- 3) Filtering script (unchanged) -->
178- < script >
179- function filterProjects ( ) {
180- const checks = Array . from ( document . querySelectorAll ( '.filter-checkbox:checked' ) ) ;
181- if ( checks . length === 0 ) {
182- document . querySelectorAll ( '.project-item' ) . forEach ( el => el . style . display = '' ) ;
183- return ;
184- }
185- const activeFilters = checks . map ( cb => ( { cat : cb . dataset . category , val : cb . value } ) ) ;
186- document . querySelectorAll ( '.project-item' ) . forEach ( li => {
187- const plats = JSON . parse ( li . dataset . platforms || '[]' ) ;
188- const subs = JSON . parse ( li . dataset . subjects || '[]' ) ;
189- const swhws = JSON . parse ( li . dataset . swhw || '[]' ) ;
190- const levels = JSON . parse ( li . dataset . supportLevel || '[]' ) ;
191- const ok = activeFilters . every ( f => {
192- switch ( f . cat ) {
193- case 'platform' : return plats . includes ( f . val ) ;
194- case 'subject' : return subs . includes ( f . val ) ;
195- case 'sw-hw' : return swhws . includes ( f . val ) ;
196- case 'support-level' : return levels . includes ( f . val ) ;
197- default : return true ;
198- }
199- } ) ;
200- li . style . display = ok ? '' : 'none' ;
201- } ) ;
181+ < script >
182+ // Put projects with badge key "recently_added" first (per category list)
183+ function hasRecentlyAddedBadge ( li ) {
184+ let badges = [ ] ;
185+ try {
186+ badges = JSON . parse ( li . dataset . badges || '[]' ) ;
187+ } catch ( e ) {
188+ badges = [ ] ;
189+ }
190+ return Array . isArray ( badges ) && badges . includes ( 'recently_added' ) ;
191+ }
192+
193+ function sortProjectsRecentlyAddedFirst ( ) {
194+ document . querySelectorAll ( '.project-list' ) . forEach ( ul => {
195+ const items = Array . from ( ul . querySelectorAll ( ':scope > .project-item' ) ) ;
196+
197+ // stable sort: decorate with original index
198+ const decorated = items . map ( ( el , idx ) => ( {
199+ el,
200+ idx,
201+ isRecent : hasRecentlyAddedBadge ( el )
202+ } ) ) ;
203+
204+ decorated . sort ( ( a , b ) => {
205+ if ( a . isRecent !== b . isRecent ) return a . isRecent ? - 1 : 1 ; // recent first
206+ return a . idx - b . idx ; // preserve original order otherwise
207+ } ) ;
208+
209+ decorated . forEach ( d => ul . appendChild ( d . el ) ) ;
210+ } ) ;
211+ }
212+
213+ document . addEventListener ( 'DOMContentLoaded' , ( ) => {
214+ sortProjectsRecentlyAddedFirst ( ) ;
215+ } ) ;
216+
217+ // --- Existing filtering (unchanged) ---
218+ function filterProjects ( ) {
219+ const checks = Array . from ( document . querySelectorAll ( '.filter-checkbox:checked' ) ) ;
220+ if ( checks . length === 0 ) {
221+ document . querySelectorAll ( '.project-item' ) . forEach ( el => el . style . display = '' ) ;
222+ return ;
223+ }
224+ const activeFilters = checks . map ( cb => ( { cat : cb . dataset . category , val : cb . value } ) ) ;
225+ document . querySelectorAll ( '.project-item' ) . forEach ( li => {
226+ const plats = JSON . parse ( li . dataset . platforms || '[]' ) ;
227+ const subs = JSON . parse ( li . dataset . subjects || '[]' ) ;
228+ const swhws = JSON . parse ( li . dataset . swhw || '[]' ) ;
229+ const levels = JSON . parse ( li . dataset . supportLevel || '[]' ) ;
230+ const ok = activeFilters . every ( f => {
231+ switch ( f . cat ) {
232+ case 'platform' : return plats . includes ( f . val ) ;
233+ case 'subject' : return subs . includes ( f . val ) ;
234+ case 'sw-hw' : return swhws . includes ( f . val ) ;
235+ case 'support-level' : return levels . includes ( f . val ) ;
236+ default : return true ;
202237 }
203- </ script >
238+ } ) ;
239+ li . style . display = ok ? '' : 'none' ;
240+ } ) ;
241+ }
242+ </ script >
204243 {%- endif -%}
205244 </ div >
206245
@@ -212,3 +251,5 @@ <h2 class="project-group-title">{{ category.title }}</h2>
212251 {%- include article-footer.html -%}
213252 </ div >
214253</ div >
254+
255+
0 commit comments