Fossil SCM

Add status=VALUE filter to /forumpost. There's no UI for it yet, so requires manual URL editing.

stephan 2026-05-26 16:32 UTC forum-statuses
Commit 52ac6bc1b2c720ff7d4533ecd1bc472467af7b940cbd8bd76abe41eeb696218e
1 file changed +33 -14
+33 -14
--- src/forum.c
+++ src/forum.c
@@ -2437,11 +2437,11 @@
24372437
void forum_main_page(void){
24382438
Stmt q;
24392439
int iLimit = 0, iOfst, iCnt;
24402440
int srchFlags;
24412441
const int isSearch = P("s")!=0;
2442
- const char *zStatus = P("status");
2442
+ const char *zStatusFilter = P("status");
24432443
char const *zLimit = 0;
24442444
24452445
login_check_credentials();
24462446
srchFlags = search_restrict(SRCH_FORUM);
24472447
if( !g.perm.RdForum ){
@@ -2486,10 +2486,11 @@
24862486
iLimit = 25;
24872487
}
24882488
style_submenu_entry("n","Max:",4,0);
24892489
iOfst = atoi(PD("x","0"));
24902490
iCnt = 0;
2491
+ if( zStatusFilter && !*zStatusFilter ) zStatusFilter = 0;
24912492
if( db_table_exists("repository","forumpost") ){
24922493
const int bHasStatus = forum_statuses()->n>1;
24932494
db_prepare(&q,
24942495
"WITH "
24952496
"root(id,pinned,status,statlbl) AS ("
@@ -2519,11 +2520,11 @@
25192520
" AND ref.value=fs.value"
25202521
" ORDER BY ref.mtime desc"
25212522
" ),"
25222523
" (SELECT label FROM forumstatus WHERE ord=1)"
25232524
" ) ELSE NULL END statlbl"
2524
- " FROM forumpost x WHERE firt IS NULL"
2525
+ " FROM forumpost x WHERE firt IS NULL AND fprev IS NULL"
25252526
"),"
25262527
" thread(age,duration,cnt,root,last,pinned,status,statlbl)"
25272528
" AS ("
25282529
" SELECT"
25292530
" julianday('now') - max(fmtime),"
@@ -2533,11 +2534,12 @@
25332534
" (SELECT fpid FROM forumpost AS y"
25342535
" WHERE y.froot=root.id %s"
25352536
" ORDER BY y.fmtime DESC LIMIT 1),"
25362537
" root.pinned, root.status, root.statlbl"
25372538
" FROM forumpost, root"
2538
- " WHERE root.id=froot AND %s"
2539
+ " WHERE root.id=froot AND %s/*ModForum*/"
2540
+ " AND CASE WHEN %d/*status filter*/ THEN root.status=%Q ELSE 1 END"
25392541
" GROUP BY froot"
25402542
" ORDER BY 6 DESC, 1 LIMIT %d OFFSET %d"
25412543
")"
25422544
"SELECT"
25432545
" thread.age," /* 0 */
@@ -2554,10 +2556,11 @@
25542556
" AND event.objid=thread.last"
25552557
" ORDER BY 7 DESC, 1;",
25562558
bHasStatus, bHasStatus,
25572559
g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/,
25582560
g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/,
2561
+ !!zStatusFilter, zStatusFilter,
25592562
iLimit+1, iOfst
25602563
);
25612564
while( db_step(&q)==SQLITE_ROW ){
25622565
char *zAge = human_readable_age(db_column_double(&q,0));
25632566
int nMsg = db_column_int(&q, 2);
@@ -2564,33 +2567,49 @@
25642567
int bPinned = db_column_int(&q, 6);
25652568
const char *zUuid = db_column_text(&q, 3);
25662569
const char *zTitle = db_column_text(&q, 4);
25672570
const char *zStatus = bHasStatus ? db_column_text(&q, 7) : NULL;
25682571
const char *zStatusLbl = bHasStatus ? db_column_text(&q, 8) : NULL;
2572
+ const int bShowStatus = bHasStatus && !zStatusFilter;
2573
+ const int nCols = bShowStatus ? 4 : 3;
25692574
if( iCnt==0 ){
2575
+ char * zTail = zStatusFilter
2576
+ ? mprintf(" with status=%Q", zStatusFilter)
2577
+ : 0;
25702578
if( iOfst>0 ){
2571
- @ <h1>Threads at least %s(zAge) old</h1>
2579
+ @ <h1>Threads at least %s(zAge) old%h(zTail ? zTail : "")</h1>
25722580
}else{
2573
- @ <h1>Most recent threads</h1>
2581
+ @ <h1>Most recent threads%h(zTail ? zTail : "")</h1>
25742582
}
2583
+ fossil_free(zTail);
25752584
@ <div class='forumPosts fileage'><table width="100%%">
25762585
if( iOfst>0 ){
25772586
if( iOfst>iLimit ){
2578
- @ <tr><td colspan="3">\
2579
- @ %z(href("%R/forum?x=%d&n=%d",iOfst-iLimit,iLimit))\
2580
- @ &uarr; Newer...</a></td></tr>
2587
+ @ <tr><td colspan="%d(nCols)">\
2588
+ @ <a href='%R/forum?x=%d(iOfst-iLimit)&n=%d(iLimit) \
2589
+ if( zStatusFilter ){
2590
+ @ &status=%T(zStatusFilter)\
2591
+ }
2592
+ @ '>&uarr; Newer...</a></td></tr>
25812593
}else{
2582
- @ <tr><td colspan="3">%z(href("%R/forum?n=%d",iLimit))\
2583
- @ &uarr; Newer...</a></td></tr>
2594
+ @ <tr><td colspan="%d(nCols)">\
2595
+ @ <a href='%R/forum?n=%d(iLimit)\
2596
+ if( zStatusFilter ){
2597
+ @ &status=%T(zStatusFilter) \
2598
+ }
2599
+ @ '>&uarr; Newer...</a></td></tr>
25842600
}
25852601
}
25862602
}
25872603
iCnt++;
25882604
if( iCnt>iLimit ){
2589
- @ <tr><td colspan="3">\
2590
- @ %z(href("%R/forum?x=%d&n=%d",iOfst+iLimit,iLimit))\
2591
- @ &darr; Older...</a></td></tr>
2605
+ @ <tr><td colspan="%d(nCols)">\
2606
+ @ <a href='%R/forum?x=%d(iOfst+iLimit)&n=%d(iLimit) \
2607
+ if( zStatusFilter ){
2608
+ @ &status=%T(zStatusFilter)\
2609
+ }
2610
+ @ '>&darr; Older...</a></td></tr>
25922611
fossil_free(zAge);
25932612
break;
25942613
}
25952614
@ <tr%s(bPinned ? " class='pinned'" : "")
25962615
if( bHasStatus ){
@@ -2609,11 +2628,11 @@
26092628
char *zDuration = human_readable_age(db_column_double(&q,1));
26102629
@ %d(nMsg) posts spanning %h(zDuration)\
26112630
fossil_free(zDuration);
26122631
}
26132632
@ </td>\
2614
- if( bHasStatus ){
2633
+ if( bShowStatus ){
26152634
@ <td class='status'>%h(zStatusLbl)</td>\
26162635
}
26172636
@</tr>
26182637
fossil_free(zAge);
26192638
}
26202639
--- src/forum.c
+++ src/forum.c
@@ -2437,11 +2437,11 @@
2437 void forum_main_page(void){
2438 Stmt q;
2439 int iLimit = 0, iOfst, iCnt;
2440 int srchFlags;
2441 const int isSearch = P("s")!=0;
2442 const char *zStatus = P("status");
2443 char const *zLimit = 0;
2444
2445 login_check_credentials();
2446 srchFlags = search_restrict(SRCH_FORUM);
2447 if( !g.perm.RdForum ){
@@ -2486,10 +2486,11 @@
2486 iLimit = 25;
2487 }
2488 style_submenu_entry("n","Max:",4,0);
2489 iOfst = atoi(PD("x","0"));
2490 iCnt = 0;
 
2491 if( db_table_exists("repository","forumpost") ){
2492 const int bHasStatus = forum_statuses()->n>1;
2493 db_prepare(&q,
2494 "WITH "
2495 "root(id,pinned,status,statlbl) AS ("
@@ -2519,11 +2520,11 @@
2519 " AND ref.value=fs.value"
2520 " ORDER BY ref.mtime desc"
2521 " ),"
2522 " (SELECT label FROM forumstatus WHERE ord=1)"
2523 " ) ELSE NULL END statlbl"
2524 " FROM forumpost x WHERE firt IS NULL"
2525 "),"
2526 " thread(age,duration,cnt,root,last,pinned,status,statlbl)"
2527 " AS ("
2528 " SELECT"
2529 " julianday('now') - max(fmtime),"
@@ -2533,11 +2534,12 @@
2533 " (SELECT fpid FROM forumpost AS y"
2534 " WHERE y.froot=root.id %s"
2535 " ORDER BY y.fmtime DESC LIMIT 1),"
2536 " root.pinned, root.status, root.statlbl"
2537 " FROM forumpost, root"
2538 " WHERE root.id=froot AND %s"
 
2539 " GROUP BY froot"
2540 " ORDER BY 6 DESC, 1 LIMIT %d OFFSET %d"
2541 ")"
2542 "SELECT"
2543 " thread.age," /* 0 */
@@ -2554,10 +2556,11 @@
2554 " AND event.objid=thread.last"
2555 " ORDER BY 7 DESC, 1;",
2556 bHasStatus, bHasStatus,
2557 g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/,
2558 g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/,
 
2559 iLimit+1, iOfst
2560 );
2561 while( db_step(&q)==SQLITE_ROW ){
2562 char *zAge = human_readable_age(db_column_double(&q,0));
2563 int nMsg = db_column_int(&q, 2);
@@ -2564,33 +2567,49 @@
2564 int bPinned = db_column_int(&q, 6);
2565 const char *zUuid = db_column_text(&q, 3);
2566 const char *zTitle = db_column_text(&q, 4);
2567 const char *zStatus = bHasStatus ? db_column_text(&q, 7) : NULL;
2568 const char *zStatusLbl = bHasStatus ? db_column_text(&q, 8) : NULL;
 
 
2569 if( iCnt==0 ){
 
 
 
2570 if( iOfst>0 ){
2571 @ <h1>Threads at least %s(zAge) old</h1>
2572 }else{
2573 @ <h1>Most recent threads</h1>
2574 }
 
2575 @ <div class='forumPosts fileage'><table width="100%%">
2576 if( iOfst>0 ){
2577 if( iOfst>iLimit ){
2578 @ <tr><td colspan="3">\
2579 @ %z(href("%R/forum?x=%d&n=%d",iOfst-iLimit,iLimit))\
2580 @ &uarr; Newer...</a></td></tr>
 
 
 
2581 }else{
2582 @ <tr><td colspan="3">%z(href("%R/forum?n=%d",iLimit))\
2583 @ &uarr; Newer...</a></td></tr>
 
 
 
 
2584 }
2585 }
2586 }
2587 iCnt++;
2588 if( iCnt>iLimit ){
2589 @ <tr><td colspan="3">\
2590 @ %z(href("%R/forum?x=%d&n=%d",iOfst+iLimit,iLimit))\
2591 @ &darr; Older...</a></td></tr>
 
 
 
2592 fossil_free(zAge);
2593 break;
2594 }
2595 @ <tr%s(bPinned ? " class='pinned'" : "")
2596 if( bHasStatus ){
@@ -2609,11 +2628,11 @@
2609 char *zDuration = human_readable_age(db_column_double(&q,1));
2610 @ %d(nMsg) posts spanning %h(zDuration)\
2611 fossil_free(zDuration);
2612 }
2613 @ </td>\
2614 if( bHasStatus ){
2615 @ <td class='status'>%h(zStatusLbl)</td>\
2616 }
2617 @</tr>
2618 fossil_free(zAge);
2619 }
2620
--- src/forum.c
+++ src/forum.c
@@ -2437,11 +2437,11 @@
2437 void forum_main_page(void){
2438 Stmt q;
2439 int iLimit = 0, iOfst, iCnt;
2440 int srchFlags;
2441 const int isSearch = P("s")!=0;
2442 const char *zStatusFilter = P("status");
2443 char const *zLimit = 0;
2444
2445 login_check_credentials();
2446 srchFlags = search_restrict(SRCH_FORUM);
2447 if( !g.perm.RdForum ){
@@ -2486,10 +2486,11 @@
2486 iLimit = 25;
2487 }
2488 style_submenu_entry("n","Max:",4,0);
2489 iOfst = atoi(PD("x","0"));
2490 iCnt = 0;
2491 if( zStatusFilter && !*zStatusFilter ) zStatusFilter = 0;
2492 if( db_table_exists("repository","forumpost") ){
2493 const int bHasStatus = forum_statuses()->n>1;
2494 db_prepare(&q,
2495 "WITH "
2496 "root(id,pinned,status,statlbl) AS ("
@@ -2519,11 +2520,11 @@
2520 " AND ref.value=fs.value"
2521 " ORDER BY ref.mtime desc"
2522 " ),"
2523 " (SELECT label FROM forumstatus WHERE ord=1)"
2524 " ) ELSE NULL END statlbl"
2525 " FROM forumpost x WHERE firt IS NULL AND fprev IS NULL"
2526 "),"
2527 " thread(age,duration,cnt,root,last,pinned,status,statlbl)"
2528 " AS ("
2529 " SELECT"
2530 " julianday('now') - max(fmtime),"
@@ -2533,11 +2534,12 @@
2534 " (SELECT fpid FROM forumpost AS y"
2535 " WHERE y.froot=root.id %s"
2536 " ORDER BY y.fmtime DESC LIMIT 1),"
2537 " root.pinned, root.status, root.statlbl"
2538 " FROM forumpost, root"
2539 " WHERE root.id=froot AND %s/*ModForum*/"
2540 " AND CASE WHEN %d/*status filter*/ THEN root.status=%Q ELSE 1 END"
2541 " GROUP BY froot"
2542 " ORDER BY 6 DESC, 1 LIMIT %d OFFSET %d"
2543 ")"
2544 "SELECT"
2545 " thread.age," /* 0 */
@@ -2554,10 +2556,11 @@
2556 " AND event.objid=thread.last"
2557 " ORDER BY 7 DESC, 1;",
2558 bHasStatus, bHasStatus,
2559 g.perm.ModForum ? "" : "AND y.fpid NOT IN private" /*safe-for-%s*/,
2560 g.perm.ModForum ? "true" : "fpid NOT IN private" /*safe-for-%s*/,
2561 !!zStatusFilter, zStatusFilter,
2562 iLimit+1, iOfst
2563 );
2564 while( db_step(&q)==SQLITE_ROW ){
2565 char *zAge = human_readable_age(db_column_double(&q,0));
2566 int nMsg = db_column_int(&q, 2);
@@ -2564,33 +2567,49 @@
2567 int bPinned = db_column_int(&q, 6);
2568 const char *zUuid = db_column_text(&q, 3);
2569 const char *zTitle = db_column_text(&q, 4);
2570 const char *zStatus = bHasStatus ? db_column_text(&q, 7) : NULL;
2571 const char *zStatusLbl = bHasStatus ? db_column_text(&q, 8) : NULL;
2572 const int bShowStatus = bHasStatus && !zStatusFilter;
2573 const int nCols = bShowStatus ? 4 : 3;
2574 if( iCnt==0 ){
2575 char * zTail = zStatusFilter
2576 ? mprintf(" with status=%Q", zStatusFilter)
2577 : 0;
2578 if( iOfst>0 ){
2579 @ <h1>Threads at least %s(zAge) old%h(zTail ? zTail : "")</h1>
2580 }else{
2581 @ <h1>Most recent threads%h(zTail ? zTail : "")</h1>
2582 }
2583 fossil_free(zTail);
2584 @ <div class='forumPosts fileage'><table width="100%%">
2585 if( iOfst>0 ){
2586 if( iOfst>iLimit ){
2587 @ <tr><td colspan="%d(nCols)">\
2588 @ <a href='%R/forum?x=%d(iOfst-iLimit)&n=%d(iLimit) \
2589 if( zStatusFilter ){
2590 @ &status=%T(zStatusFilter)\
2591 }
2592 @ '>&uarr; Newer...</a></td></tr>
2593 }else{
2594 @ <tr><td colspan="%d(nCols)">\
2595 @ <a href='%R/forum?n=%d(iLimit)\
2596 if( zStatusFilter ){
2597 @ &status=%T(zStatusFilter) \
2598 }
2599 @ '>&uarr; Newer...</a></td></tr>
2600 }
2601 }
2602 }
2603 iCnt++;
2604 if( iCnt>iLimit ){
2605 @ <tr><td colspan="%d(nCols)">\
2606 @ <a href='%R/forum?x=%d(iOfst+iLimit)&n=%d(iLimit) \
2607 if( zStatusFilter ){
2608 @ &status=%T(zStatusFilter)\
2609 }
2610 @ '>&darr; Older...</a></td></tr>
2611 fossil_free(zAge);
2612 break;
2613 }
2614 @ <tr%s(bPinned ? " class='pinned'" : "")
2615 if( bHasStatus ){
@@ -2609,11 +2628,11 @@
2628 char *zDuration = human_readable_age(db_column_double(&q,1));
2629 @ %d(nMsg) posts spanning %h(zDuration)\
2630 fossil_free(zDuration);
2631 }
2632 @ </td>\
2633 if( bShowStatus ){
2634 @ <td class='status'>%h(zStatusLbl)</td>\
2635 }
2636 @</tr>
2637 fossil_free(zAge);
2638 }
2639

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button