This is a viewer only at the moment see the article on how this works.
To update the preview hit Ctrl-Alt-R (or ⌘-Alt-R on Mac) or Enter to refresh. The Save icon lets you save the markdown file to disk
This is a preview from the server running through my markdig pipeline
Monday, 10 November 2025
पिछले कुछ दिनों के दौरान मैं नए ब्लॉग फ़िल्टर बार में बाहर जा रहा हूँ: भाषा चयन, आदेश, और एक तारीख चुनने की कोशिश कर रहे हैं कि स्मार्ट होने के लिए बहुत कठिन है।
यह पोस्ट जो मैंने बनाया था, वह मेरे लिए बहुत मायने रखता था, क्यों कुछ बातें ऐसी होती थीं (जो आगे नहीं बताती, तरोताज़ा नहीं करती थीं) और मैं ने उन्हें कैसे रखा ।
याद रखें कि इस साइट की प्रगति में एक काम है, सामान के इस प्रकार होगा जब आप अपने-अपने-छोटे भोजन खाना खाते हैं!
/blog/date-rangeतिथि सीमा अंत बिन्दु<clear-param>साफ करें: फिल्टरों को साफ करने का आसान तरीका
जिस तरह से मैंने कुछ बग बनाया था: तारीख सीमा को भाषा/क्रमित करने के लिए खो दिया जा रहा है, पंचांग समायोजन पर ताज़ा नहीं है, और एक मजेदार व्यक्ति जहां अंधेरा मोड स्टाइल टूटी क्योंकि storting फिर नहीं मिला था.
<div id="filters" hx-target="#content">
<select id="languageSelect">…</select>
<select id="orderSelect">
<option value="date_desc">Newest first</option>
<option value="date_asc">Oldest first</option>
<option value="title_asc">Title A–Z</option>
<option value="title_desc">Title Z–A</option>
</select>
<input id="dateRange" type="text" placeholder="YYYY-MM-DD → YYYY-MM-DD" />
<button id="clearDateFilter">Clear</button>
<div id="filterSummary"></div>
</div>
<div id="content"><!-- HTMX swaps blog list here --></div>
स्क्रिप्ट उम्मीद करता है कि यह समान संरचना है:Mostlylucid/src/js/blog-index.jsक्लाएंट: HMAX + समतल क़ौमज़िंग
function applyNavigation(u){
const target = document.querySelector('#content');
try{ window.history.pushState({}, '', u.toString()); }catch{}
if(window.htmx && target){
window.htmx.ajax('GET', u.toString(), {
target: '#content',
swap: 'outerHTML show:none',
headers: {'pagerequest': 'true'}
});
} else {
window.location.href = u.toString();
}
}
const url = new URL(window.location.href);
const existingStart = url.searchParams.get('startDate');
const existingEnd = url.searchParams.get('endDate');
const existingLang = url.searchParams.get('language') || 'en';
const existingOrderBy = (url.searchParams.get('orderBy') || 'date').toLowerCase();
const existingOrderDir = (url.searchParams.get('orderDir') || 'desc').toLowerCase();
langSelect.value = existingLang;
orderSelect.value = `${existingOrderBy}_${existingOrderDir}`;
updateSummary();
async function fetchMonth(year, month, language){
const res = await fetch(`/blog/calendar-days?year=${year}&month=${month}&language=${encodeURIComponent(language||'en')}`);
if(!res.ok) return new Set();
const j = await res.json();
return new Set(j.dates || []);
}
function formatYMD(d){ return d.toISOString().substring(0,10); }
let highlightDates = new Set();
const fp = window.flatpickr(input, {
mode: 'range',
dateFormat: 'Y-m-d',
defaultDate: [existingStart, existingEnd].filter(Boolean),
onDayCreate: function(_dObj,_dStr,fpInstance,dayElem){
const ymd = formatYMD(dayElem.dateObj);
if(highlightDates.has(ymd)){
dayElem.classList.add('has-post');
dayElem.style.background = 'rgba(76,175,80,0.35)';
dayElem.style.borderRadius = '6px';
}
},
onMonthChange: async function(_sd,_ds,fpInstance){
highlightDates = await fetchMonth(fpInstance.currentYear, fpInstance.currentMonth+1, langSelect.value);
fpInstance.redraw();
},
onOpen: async function(_sd,_ds,fpInstance){
highlightDates = await fetchMonth(fpInstance.currentYear, fpInstance.currentMonth+1, langSelect.value);
fpInstance.redraw();
},
onChange: function(selectedDates){
if(selectedDates.length === 2){
const [start,end] = selectedDates;
const u = new URL(window.location.href);
u.searchParams.set('startDate', formatYMD(start));
u.searchParams.set('endDate', formatYMD(end));
u.searchParams.set('page','1');
u.searchParams.set('language', langSelect.value);
const [ob,od] = orderSelect.value.split('_');
u.searchParams.set('orderBy', ob);
u.searchParams.set('orderDir', od);
updateSummary();
applyNavigation(u);
}
}
});
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', formatYMD(s));
u.searchParams.set('endDate', formatYMD(e));
}
// refresh calendar highlights for new language
if(input._flatpickr){
const fp = input._flatpickr;
highlightDates = await fetchMonth(fp.currentYear, fp.currentMonth+1, langSelect.value);
fp.redraw();
}
updateSummary();
applyNavigation(u);
});
const obs = new MutationObserver(() => {
const dr = root.querySelector('#dateRange');
const fp = dr && dr._flatpickr;
if(fp && typeof fp.redraw === 'function') fp.redraw();
});
obs.observe(document.documentElement, { attributes:true, attributeFilter:['class'] });
जब भाषा या क्रम बदलता है तो तिथि बचाए रखें
calendar-daysपृष्ठ पर तीन अंत- बिन्दुओं की शक्ति:date-rangeए// GET /blog
[HttpGet]
[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);
}
// GET /blog/calendar-days?year=2025&month=11&language=en
[HttpGet("calendar-days")]
[ResponseCache(Duration = 300, VaryByHeader = "hx-request", VaryByQueryKeys = new[] { nameof(year), nameof(month), nameof(language) }, Location = ResponseCacheLocation.Any)]
[OutputCache(Duration = 1800, VaryByHeaderNames = new[] { "hx-request" }, VaryByQueryKeys = new[] { nameof(year), nameof(month), nameof(language) })]
public async Task<IActionResult> CalendarDays(int year, int month, string language = MarkdownBaseService.EnglishLanguage)
{
if (year < 2000 || month < 1 || month > 12) return BadRequest("Invalid year or month");
var start = new DateTime(year, month, 1);
var end = start.AddMonths(1).AddDays(-1);
var posts = await blogViewService.GetPostsForRange(start, end, language: language);
if (posts is null) return Json("");
var dates = posts.Select(p => p.PublishedDate.Date).Distinct().OrderBy(d => d).Select(d => d.ToString("yyyy-MM-dd")).ToList();
return Json(new { dates });
}
// GET /blog/date-range?language=en
[HttpGet("date-range")]
[ResponseCache(Duration = 3600, VaryByHeader = "hx-request", VaryByQueryKeys = new[] { nameof(language) }, Location = ResponseCacheLocation.Any)]
[OutputCache(Duration = 7200, VaryByHeaderNames = new[] { "hx-request" }, VaryByQueryKeys = new[] { nameof(language) })]
public async Task<IActionResult> DateRange(string language = MarkdownBaseService.EnglishLanguage)
{
var allPosts = await blogViewService.GetAllPosts();
if (allPosts is null || !allPosts.Any())
{
return Json(new
{
minDate = DateTime.UtcNow.AddYears(-1).ToString("yyyy-MM-dd"),
maxDate = DateTime.UtcNow.ToString("yyyy-MM-dd")
});
}
var posts = allPosts;
if (!string.IsNullOrEmpty(language) && language != MarkdownBaseService.EnglishLanguage)
{
posts = allPosts.Where(p => p.Language.Equals(language, StringComparison.OrdinalIgnoreCase)).ToList();
}
if (!posts.Any()) posts = allPosts;
var minDate = posts.Min(p => p.PublishedDate.Date);
var maxDate = posts.Max(p => p.PublishedDate.Date);
return Json(new
{
minDate = minDate.ToString("yyyy-MM-dd"),
maxDate = maxDate.ToString("yyyy-MM-dd")
});
}
अंतिम बिन्दु जो दिए गए माह में दिन के सेट को लौटाता है, जिसके पोस्ट होते हैं ( विशेषताओं के लिए)LinkUrlए
public class BasePagingModel<T> : Interfaces.IPagingModel<T> where T : class
{
public int Page { get; set; }
public int TotalItems { get; set; } = 0;
public int PageSize { get; set; }
public ViewType ViewType { get; set; } = ViewType.TailwindAndDaisy;
public string LinkUrl { get; set; }
public List<T> Data { get; set; }
}
sequenceDiagram
participant U as User
participant FP as Flatpickr
participant JS as blog-index.js
participant HT as HTMX
participant C as BlogController
U->>FP: Selects 2025-11-01 → 2025-11-10
FP-->>JS: onChange([start,end])
JS->>JS: Update URLSearchParams (startDate, endDate, language, order)
JS->>HT: htmx.ajax('GET', /blog?...)
HT->>C: GET /blog with query
C-->>HT: Partial _BlogSummaryList
HT-->>U: Swap #content
JS->>FP: (after swap) ensure highlights + redraw
flowchart TD A[Open calendar / Month change] --> B[Fetch /blog/calendar-days] B -->|JSON dates: yyyy-mm-dd array| C[Set highlightDates] C --> D[flatpickr redraw] D --> E[onDayCreate adds .has-post]
प्रवाह: कैलेण्डर विशेष करता हैBlogPostEntity:
public class BlogPostEntity
{
// ... existing fields ...
public bool IsPinned { get; set; }
public bool IsHidden { get; set; }
public DateTimeOffset? ScheduledPublishDate { get; set; }
}
नयी विशेषताएँ: दृश्यता और सामग्री नियंत्रणBlogServiceपोस्ट दृश्यता फ़िल्टरName
// Filter out hidden posts and posts scheduled for the future
var now = DateTimeOffset.UtcNow;
postQuery = postQuery.Where(x =>
!x.IsHidden &&
(x.ScheduledPublishDate == null || x.ScheduledPublishDate <= now));
// For page 1, prioritize pinned posts
var isFirstPage = page == null || page.Value == 1;
if (isFirstPage)
{
postQuery = postQuery.OrderByDescending(x => x.IsPinned)
.ThenByDescending(x => x.PublishedDate.DateTime);
}
इस अद्यतन में सबसे बड़ा सुधार उचित प्रेस प्रबंधन है.
IsHidden = trueवहScheduledPublishDateIsPinned = true) लिस्ट्स में कभी नहीं प्रकट होतासिर्फ उनके बाद ही प्रकट हो जाते हैं
[HtmlTargetElement("clear-param")]
public class ClearParamTagHelper : TagHelper
{
[HtmlAttributeName("name")]
public string? Name { get; set; }
[HtmlAttributeName("all")]
public bool All { get; set; } = false;
[HtmlAttributeName("exclude")]
public string Exclude { get; set; } = "";
// ... styling and Alpine.js integration ...
}
पोस्ट- पोस्ट
<!-- Clear a specific parameter -->
<clear-param name="startDate">Clear Date</clear-param>
<!-- Clear all parameters except language -->
<clear-param all="true" exclude="language">Clear All Filters</clear-param>
) हमेशा प्रथम पृष्ठ १ पर आता है घोषणाओं या विशिष्ट सामग्री के लिएwindow.queryParamClearerपारम टैग सहायक
**एक नया. neNT टैग मदद को स्पष्ट क्वैरी पैरामीटर्स के लिए आसान बनाता है:**वर्व दृश्य में उपयोग:
यूआरएल का उपयोग कर तथा HMMMX ट्रैक्स को हैंडल करने के लिए घटक.
startDate/endDate.new URL(window.location.href)मैं पूरी कार्यान्वयन विवरण को कवर करूंगा, जिसमें Ajson घटक और टैग सहायक पैटर्न शामिल हैं, निर्माण के बारे में एक भावी पोस्ट मेंlanguage/orderबग मैं हिट (और फिक्सेस)भाषा/क्रम परिवर्तन पर तिथि सीमा गुम हो गई है
"और व्यर्थ बात और कठ-तुला में पड़े रहनेवालों के सिवा कुछ भी नहीं होता
<html class>HMMX साम्हने के बाद पंचांग को विशिष्ट किया गयाfp.redraw().कारण: प्लैटर उदाहरण पुराने डोम पर रहता था और रोंगटे खड़े हो जाता था ।
LinkUrlस्वेप के बाद फिर से दोबारा नज़रअंदाज़ करें (नीचे देखें)posts.LinkUrl = Url.Action("Index","Blog", new { startDate, endDate, language, orderBy, orderDir })कारण: शैली की क्लास बदल गयी, लेकिन समतल भू - दृश्य रंग के दिन फिर से नहीं निकाले गए ।परिवर्तन और कॉल
(function(){
function initFromRoot(root){ /* …the big function shown above… */ }
if(window.htmx){
document.body.addEventListener('htmx:afterSwap', function(ev){
const tgt = ev.detail.target;
// re-init if the content swapped includes the filters/content area
if(tgt && (tgt.id === 'content' || tgt.querySelector?.('#filters'))){
initFromRoot(document);
}
});
}
// also run on first load
initFromRoot(document);
})();
इस प्रकार पृष्ठ लिखना यूआरएल को सही तरह से वितरित करता है.
© 2026 Scott Galloway — Unlicense — All content and source code on this site is free to use, copy, modify, and sell.