Barre de filtrage : Progrès, bugs et petites victoires (Français (French))

Barre de filtrage : Progrès, bugs et petites victoires

Monday, 10 November 2025

//

6 minute read

Présentation

J'ai mis en place une barre de filtre appropriée pour la liste des blogs : la langue, la portée de la date, le tri et la pagination qui reste écailleuse avec HTMX.

Il est proche maintenant—mais comme toujours, le dernier 20% est le bit épicé: dates, caches, et pourquoi cela fonctionne-t-il localement mais pas après un échange?Si vous voulez la plongée profonde avec beaucoup de code et de diagrammes, voir:

/blog/filterbarprogressandissues

Rappelez-vous que ce site est un travail en cours, ce genre de choses va se produire lorsque vous mangez-votre-dogfood!

  • TL;DR
  • Nouvelle barre de filtre : Langue + Tri + Gamme de date
  • Les swaps partiels HTMX permettent de garder la page rapidement; back/forward fonctionne parce que j'appuie toujours sur l'URL mise à jour/blog/calendar-daysLes faits saillants du calendrier proviennent d'une minuscule
  • critère d' évaluation
  • Correction : les plages de dates sont supprimées lors du changement de langue/ordre
  • Correction : calendrier non rafraîchissant après les swaps HTMX ou les changements de thème

La mise en cache du serveur varie désormais selon toutes les touches de requête pertinentes

  • Ce qui fonctionne bien
  • Comportement URL-first: Toutes les interactions mettent à jour l'URL; vous pouvez créer un lien profond vers un état de filtreLinkUrlPagination préserve les filtres actuels (
  • est réglé sur le serveur)
// Server: cache and vary for index
[ResponseCache(Duration = 300, VaryByHeader = "hx-request",
  VaryByQueryKeys = new[] { "page", "pageSize", nameof(startDate), nameof(endDate), nameof(language), nameof(orderBy), nameof(orderDir) },
  Location = ResponseCacheLocation.Any)]
[OutputCache(Duration = 3600, VaryByHeaderNames = new[] { "hx-request" },
  VaryByQueryKeys = new[] { nameof(page), nameof(pageSize), nameof(startDate), nameof(endDate), nameof(language), nameof(orderBy), nameof(orderDir) })]
public async Task<IActionResult> Index(int page = 1, int pageSize = 20, DateTime? startDate = null, DateTime? endDate = null,
  string language = MarkdownBaseService.EnglishLanguage, string orderBy = "date", string orderDir = "desc")
{
    var posts = await blogViewService.GetPagedPosts(page, pageSize, language: language, startDate: startDate, endDate: endDate);
    posts.LinkUrl = Url.Action("Index", "Blog", new { startDate, endDate, language, orderBy, orderDir });
    if (Request.IsHtmx()) return PartialView("_BlogSummaryList", posts);
    return View("Index", posts);
}

Flatpickr range par défaut aux valeurs de requête actuelles si présent et met en évidence jours avec les messages

Les bogues que j'ai corrigés (et les nouvelles fonctionnalités !)

Visibilité et contrôle du contenu

  • **Le plus grand ajout: une bonne gestion de la visibilité post-visibilité:**Postes cachésIsHidden: Les messages peuvent maintenant être marqués comme cachés (
  • drapeau) et n'apparaîtra pas dans les listesPublication programméeScheduledPublishDate: Les messages peuvent avoir un
  • et n'apparaissent qu'après cette périodePostes épinglésIsPinned: Postes marqués d'un
// BlogService now filters appropriately
var now = DateTimeOffset.UtcNow;
postQuery = postQuery.Where(x =>
    !x.IsHidden &&
    (x.ScheduledPublishDate == null || x.ScheduledPublishDate <= now));

// Pinned posts sorted first on page 1
if (isFirstPage)
{
    postQuery = postQuery.OrderByDescending(x => x.IsPinned)
                         .ThenByDescending(x => x.PublishedDate.DateTime);
}

apparaissent toujours en premier à la page 1 (grand pour les annonces)

  • Amélioration de la portée des dates/blog/date-rangeNouveaucritère d' évaluation
  • : Renvoie les dates min/max sur tous les messages (language-aware) afin que le sélectionneur de dates puisse définir des limites senséesEffacer l'aide de la balise param<clear-param>: Ajouté
<clear-param name="startDate">Clear Date</clear-param>
<clear-param all="true" exclude="language">Clear All Filters</clear-param>

tag helper pour effacer facilement les paramètres de la requête

  • Corrections des bogues
    • Perdre la plage de dates lors du changement de langue ou de commandenew URL(window.location.href)Correction : Commencer à partir de
langSelect.addEventListener('change', async function(){
  const u = new URL(window.location.href);
  u.searchParams.set('language', langSelect.value);
  u.searchParams.set('page','1');
  const [ob,od] = (orderSelect.value||'date_desc').split('_');
  u.searchParams.set('orderBy', ob);
  u.searchParams.set('orderDir', od);
  if(input._flatpickr && input._flatpickr.selectedDates.length===2){
    const [s,e] = input._flatpickr.selectedDates;
    u.searchParams.set('startDate', s.toISOString().substring(0,10));
    u.searchParams.set('endDate',   e.toISOString().substring(0,10));
  }
  applyNavigation(u);
});
  • et ne remplace que les paramètres changeants; si Flatpickr a une sélection, l'appliquer de nouveau.

    • Points saillants du calendrier non rafraîchissants après les swaps HTMXfp.redraw()Correction: Détruire/recréer Flatpickr sur init, puis récupérer les points forts pour le mois visible et appelerhtmx:afterSwap.
  • ; également re-run init sur

    • Styles de mode sombres ne s'appliquant pas au calendrier<html class>Correction: observerfp.redraw()et appeler

quand ça change.

sequenceDiagram
  participant User
  participant JS as blog-index.js
  participant HT as HTMX
  participant S as Server

  User->>JS: Change language/order or pick a date range
  JS->>JS: Update URLSearchParams, pushState
  JS->>HT: htmx.ajax('GET', /blog?...)
  HT->>S: GET /blog
  S-->>HT: HTML partial (_BlogSummaryList)
  HT-->>User: Swap #content

Comment les morceaux parlent

Détection de la demande de page HTMXpagerequestLa barre de filtre utilise une fonction personnalisée

public static bool IsPageRequest(this HttpRequest request)
{
    return request.Headers.ContainsKey("pagerequest") &&
           request.Headers["pagerequest"] == "true";
}

l'en-tête pour aider le serveur à distinguer les chargements de pages entières des swaps HTMX partiels:

**Cela permet au contrôleur de retourner simplement la vue partielle pour les requêtes HTMX et les vues pleines de page pour la navigation directe.**Remarque

: L'extension de la balise d'aide à la recherche et le paramètre de requête plus clair Alpine.js composants méritent leur propre plongée profonde – je vais les couvrir en détail dans un futur post sur la construction réutilisable composants HTMX/Alpine.

  • Encore à faire
  • Préréglages de date rapide (7/30 derniers jours, cette année)
  • Semences locales de stockage pour la langue

Prise en charge du clavier sur le sélectionneur de portée

Finding related posts...
logo

© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.