Refactor blog section (/blog/)#253
Conversation
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
WalkthroughThe PR reorganizes how blog posts are discovered and displayed by introducing a ChangesBlog categorization and TOC enhancement for article discovery
🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
layouts/blog/list.html (1)
10-15:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftLocalize the new list-page UI copy via i18n keys.
The new section titles, descriptions, CTA text, and action labels are hardcoded. Please move these literals to localization keys and update translation files alongside this template change.
As per coding guidelines, "Localize all strings using string keys; remove any orphaned string keys."
Also applies to: 38-40, 77-79, 98-99, 117-119, 138-139, 152-154, 164-171
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@layouts/blog/list.html` around lines 10 - 15, The template hardcodes UI copy (e.g., "Knowledge Base", the .hero-title "Blog Posts", .hero-description paragraph and other CTA/action labels referenced at lines 38-40, 77-79, 98-99, 117-119, 138-139, 152-154, 164-171); replace each literal with an i18n key lookup using the project's template translation helper (same pattern as other localized templates), add corresponding keys to the translation files for all supported locales, and remove/rename any orphaned string keys so keys and template usage remain synchronized.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@assets/js/main.js`:
- Around line 368-370: initTocHighlight currently resolves TOC targets with
document.querySelector(link.getAttribute("href")) and then assumes headings[0]
and current.id exist; fix by robustly resolving hrefs: for hash-only hrefs use
the id lookup path (extract href.slice(1), decodeURIComponent and call
document.getElementById) to avoid CSS selector escaping issues, and for other
hrefs fall back to querySelector inside a try/catch to ignore invalid selectors;
then filter out falsy results into headings and guard uses of headings[0] and
current (e.g., check headings.length > 0 and current != null before accessing
current.id) so no throws occur when headings is empty or selectors are invalid
(referencing initTocHighlight, tocLinks, headings, and current.id).
In `@content/blog/create-an-article.en.md`:
- Line 6: Add a new entry to CHANGELOG.md under the "Unreleased" section
documenting the blog metadata change (dsc_family: "Community") and the updated
TOC behavior introduced by this PR; mention the affected file
content/blog/create-an-article.en.md and briefly summarize the change (metadata
addition and TOC behavior change) so the Unreleased section records the PR
impact.
In `@layouts/blog/list.html`:
- Around line 109-123: Merged collection $generalPages (created by append
$communityPages $uncategorized) is not re-sorted so posts from both sources
aren’t in global chronological order; after you create $generalPages, run Hugo’s
sort on the Date (e.g., sort $generalPages "Date" "desc") and use that sorted
value in the subsequent range. Locate the $generalPages assignment and the range
that iterates it, replace the range source with the sorted collection (or
reassign $generalPages to the sorted result) so items are globally ordered by
Date descending.
In `@layouts/blog/single.html`:
- Around line 8-11: The "Back to Blog" anchor and other hardcoded UI texts
(e.g., the anchor with class "btn btn-ghost" containing the literal "Back to
Blog" and the other literals noted at the same template) must be replaced with
Hugo i18n string keys and the corresponding translations added to the site's
i18n files; update the template to call the i18n helper (use a key like
"back_to_blog") instead of the literal, and add that key and translations to
your i18n JSON/TOML/YAML so the UI is translatable and consistent with the repo
policy.
In `@layouts/community/maintainers.html`:
- Around line 70-78: Wrap the resources.GetRemote call in try and check the
returned error object instead of relying on .Err on the raw call: call try
resources.GetRemote with $path and $opts, capture the result (e.g., assign to a
variable), then test that variable's .Err before proceeding to
transform.Unmarshal and set $data; ensure you still use transform.Unmarshal and
assign to $data only when the try result has no error and contains Content.
---
Outside diff comments:
In `@layouts/blog/list.html`:
- Around line 10-15: The template hardcodes UI copy (e.g., "Knowledge Base", the
.hero-title "Blog Posts", .hero-description paragraph and other CTA/action
labels referenced at lines 38-40, 77-79, 98-99, 117-119, 138-139, 152-154,
164-171); replace each literal with an i18n key lookup using the project's
template translation helper (same pattern as other localized templates), add
corresponding keys to the translation files for all supported locales, and
remove/rename any orphaned string keys so keys and template usage remain
synchronized.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 8ec9e247-f6b3-4ccc-a3c3-f24018fe0a32
📒 Files selected for processing (21)
archetypes/blog.mdassets/css/futuristic.cssassets/js/main.jsconfig.tomlcontent/blog/DSC-is-dead-long-live-dsc.en.mdcontent/blog/add-codecov-support-to-repository.mdcontent/blog/class-based-dsc-resources.mdcontent/blog/convert-a-module-for-continuous-delivery.en.mdcontent/blog/convert-master-to-main.en.mdcontent/blog/convert-tests-to-pester5-for-dsc-community-repository.mdcontent/blog/converting-tests-to-pester5.mdcontent/blog/create-an-article.en.mdcontent/blog/dsc-maintenance-windows.en.mdcontent/blog/how-to-use-dsc-logging.en.mdcontent/blog/updating-sampler-github-tasks.mdcontent/blog/use-dscresource-common-functions-in-module.en.mdcontent/blog/what-is-microsoft-dscv3.mdcontent/blog/your-first-class-based-microsoft-dsc-v3-resource.mdlayouts/blog/list.htmllayouts/blog/single.htmllayouts/community/maintainers.html
| const headings = tocLinks | ||
| .map((link) => document.querySelector(link.getAttribute("href"))) | ||
| .filter(Boolean); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Show the relevant region around the referenced lines
nl -ba assets/js/main.js | sed -n '330,430p'
# Also locate initTocHighlight definition and any reference to "current.id"
rg -n "function initTocHighlight|initTocHighlight|current\\.id|tocLinks|headings" assets/js/main.jsRepository: dsccommunity/dsccommunity.org
Length of output: 116
🏁 Script executed:
#!/bin/bash
set -euo pipefail
nl -ba assets/js/main.js | sed -n '330,430p'
rg -n "function initTocHighlight|initTocHighlight|current\\.id|tocLinks|headings" assets/js/main.jsRepository: dsccommunity/dsccommunity.org
Length of output: 116
🏁 Script executed:
#!/bin/bash
set -euo pipefail
nl -ba assets/js/main.js | sed -n '330,430p'
rg -n "function initTocHighlight|initTocHighlight|current\\.id|tocLinks|headings" assets/js/main.jsRepository: dsccommunity/dsccommunity.org
Length of output: 116
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== initTocHighlight + related identifiers ==="
rg -n "function initTocHighlight|initTocHighlight|current\\.id|tocLinks|headings" assets/js/main.js || true
echo
echo "=== Lines 340-420 ==="
sed -n '340,420p' assets/js/main.jsRepository: dsccommunity/dsccommunity.org
Length of output: 2554
Harden TOC highlighting against invalid hash selectors and empty headings
initTocHighlight() resolves TOC targets with document.querySelector(link.getAttribute("href")), treating the hash as a raw CSS selector (can throw for valid HTML ids needing escaping). It also assumes headings[0] exists; when headings is empty, current.id will throw.
Proposed fix
- const headings = tocLinks
- .map((link) => document.querySelector(link.getAttribute("href")))
- .filter(Boolean);
+ const headings = tocLinks
+ .map((link) => decodeURIComponent(link.getAttribute("href").slice(1)))
+ .map((id) => document.getElementById(id))
+ .filter(Boolean);
+ if (headings.length === 0) return;📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const headings = tocLinks | |
| .map((link) => document.querySelector(link.getAttribute("href"))) | |
| .filter(Boolean); | |
| const headings = tocLinks | |
| .map((link) => decodeURIComponent(link.getAttribute("href").slice(1))) | |
| .map((id) => document.getElementById(id)) | |
| .filter(Boolean); | |
| if (headings.length === 0) return; |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@assets/js/main.js` around lines 368 - 370, initTocHighlight currently
resolves TOC targets with document.querySelector(link.getAttribute("href")) and
then assumes headings[0] and current.id exist; fix by robustly resolving hrefs:
for hash-only hrefs use the id lookup path (extract href.slice(1),
decodeURIComponent and call document.getElementById) to avoid CSS selector
escaping issues, and for other hrefs fall back to querySelector inside a
try/catch to ignore invalid selectors; then filter out falsy results into
headings and guard uses of headings[0] and current (e.g., check headings.length
> 0 and current != null before accessing current.id) so no throws occur when
headings is empty or selectors are invalid (referencing initTocHighlight,
tocLinks, headings, and current.id).
| type: "post" | ||
| weight: 1 | ||
| draft: false | ||
| dsc_family: "Community" |
There was a problem hiding this comment.
Missing required CHANGELOG update for this PR.
Please add an entry to CHANGELOG.md under the Unreleased section to document the
blog metadata and TOC behavior changes.
As per coding guidelines, "Always update CHANGELOG.md Unreleased section".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@content/blog/create-an-article.en.md` at line 6, Add a new entry to
CHANGELOG.md under the "Unreleased" section documenting the blog metadata change
(dsc_family: "Community") and the updated TOC behavior introduced by this PR;
mention the affected file content/blog/create-an-article.en.md and briefly
summarize the change (metadata addition and TOC behavior change) so the
Unreleased section records the PR impact.
| {{ $generalPages := $communityPages | append $uncategorized }} | ||
| {{ if gt (len $generalPages) 0 }} | ||
| <div class="blog-section" style="margin-bottom: var(--space-16);"> | ||
| <div class="blog-section-header"> | ||
| <span class="blog-section-icon" style="background: linear-gradient(135deg, #7c3aed 0%, #a78bfa 100%);"> | ||
| <i class="ri-community-line"></i> | ||
| </span> | ||
| <div> | ||
| <h2 class="blog-section-title">Community</h2> | ||
| <p class="blog-section-description">News, guides, and how-tos from the DSC Community</p> | ||
| </div> | ||
| </a> | ||
| {{ end }} | ||
| </div> | ||
| <div class="grid-auto stagger"> | ||
| {{ range $generalPages }} | ||
| <a href="{{ .Permalink }}" class="card blog-card card-link"> |
There was a problem hiding this comment.
Re-sort merged Community + uncategorized posts by Date
$generalPages is built by append-ing $communityPages and $uncategorized, but the merged collection is never re-sorted—so dates won’t be globally chronological across both groups.
Proposed fix
- {{ $generalPages := $communityPages | append $uncategorized }}
+ {{ $generalPages := sort ($communityPages | append $uncategorized) "Date" "desc" }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {{ $generalPages := $communityPages | append $uncategorized }} | |
| {{ if gt (len $generalPages) 0 }} | |
| <div class="blog-section" style="margin-bottom: var(--space-16);"> | |
| <div class="blog-section-header"> | |
| <span class="blog-section-icon" style="background: linear-gradient(135deg, #7c3aed 0%, #a78bfa 100%);"> | |
| <i class="ri-community-line"></i> | |
| </span> | |
| <div> | |
| <h2 class="blog-section-title">Community</h2> | |
| <p class="blog-section-description">News, guides, and how-tos from the DSC Community</p> | |
| </div> | |
| </a> | |
| {{ end }} | |
| </div> | |
| <div class="grid-auto stagger"> | |
| {{ range $generalPages }} | |
| <a href="{{ .Permalink }}" class="card blog-card card-link"> | |
| {{ $generalPages := sort ($communityPages | append $uncategorized) "Date" "desc" }} | |
| {{ if gt (len $generalPages) 0 }} | |
| <div class="blog-section" style="margin-bottom: var(--space-16);"> | |
| <div class="blog-section-header"> | |
| <span class="blog-section-icon" style="background: linear-gradient(135deg, `#7c3aed` 0%, `#a78bfa` 100%);"> | |
| <i class="ri-community-line"></i> | |
| </span> | |
| <div> | |
| <h2 class="blog-section-title">Community</h2> | |
| <p class="blog-section-description">News, guides, and how-tos from the DSC Community</p> | |
| </div> | |
| </div> | |
| <div class="grid-auto stagger"> | |
| {{ range $generalPages }} | |
| <a href="{{ .Permalink }}" class="card blog-card card-link"> |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@layouts/blog/list.html` around lines 109 - 123, Merged collection
$generalPages (created by append $communityPages $uncategorized) is not
re-sorted so posts from both sources aren’t in global chronological order; after
you create $generalPages, run Hugo’s sort on the Date (e.g., sort $generalPages
"Date" "desc") and use that sorted value in the subsequent range. Locate the
$generalPages assignment and the range that iterates it, replace the range
source with the sorted collection (or reassign $generalPages to the sorted
result) so items are globally ordered by Date descending.
| <a href="/blog" class="btn btn-ghost" style="margin-bottom: var(--space-6); color: rgba(255,255,255,0.75); border-color: rgba(255,255,255,0.2);"> | ||
| <i class="ri-arrow-left-line"></i> | ||
| Back to Blog | ||
| </a> |
There was a problem hiding this comment.
Localize newly added UI strings instead of hardcoded literals.
This template introduces new user-facing text directly in markup. Please move these to localization keys (for example via Hugo i18n) so the blog UI stays translatable and consistent with repo policy.
Suggested direction
- Back to Blog
+ {{ i18n "blogBackToBlog" }}
- <div style="font-size: var(--text-xs); color: rgba(255,255,255,0.5);">Author</div>
+ <div style="font-size: var(--text-xs); color: rgba(255,255,255,0.5);">{{ i18n "authorLabel" }}</div>
- <h4 class="toc-heading"> ... On this page ... </h4>
+ <h4 class="toc-heading"> ... {{ i18n "onThisPage" }} ... </h4>As per coding guidelines, "Localize all strings using string keys; remove any orphaned string keys."
Also applies to: 41-42, 74-75, 89-90, 113-114
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@layouts/blog/single.html` around lines 8 - 11, The "Back to Blog" anchor and
other hardcoded UI texts (e.g., the anchor with class "btn btn-ghost" containing
the literal "Back to Blog" and the other literals noted at the same template)
must be replaced with Hugo i18n string keys and the corresponding translations
added to the site's i18n files; update the template to call the i18n helper (use
a key like "back_to_blog") instead of the literal, and add that key and
translations to your i18n JSON/TOML/YAML so the UI is translatable and
consistent with the repo policy.
This pull request redesigns the
/blog/listing page and individual blog post layout by reducing clutter, adding structure (PSDSC, Microsoft DSC, and Community), and improving readability (TOC).Each section now has a distinct icon, title, and description header seen at local runtime:
The blog post is more narrow with a TOC added:
With the new frontmatter (
dsc_family), it gets controlled on which section posts are added. Lastly, there was a small template fix as this was from older Hugo versions (type: "post") e.g. Hugo's template lookup uses the type field to pick a layouts subfolder — withtype: "post"it searchedlayouts/post/(non-existent), skipped blog, and fell back tosingle.html` (which rendered the "all blog posts" sidebar). Without an explicit type, Hugo defaults to the section name (blog) and correctly resolves to single.html.This change is