Skip to content

Conversation

@gocanto
Copy link
Collaborator

@gocanto gocanto commented Oct 14, 2025

Summary by CodeRabbit

  • New Features

    • Centralized site metadata model powering pages, URLs, colors, robots, and descriptions.
    • Slug-based page identifiers for Home, About, Projects, Resume, Posts, and Post Details.
    • Structured data and web manifest now draw from the centralized model for consistent output.
  • Refactor

    • Replaced scattered URL/name/branding constants with a unified, page-aware metadata source.
    • SEO outputs (titles, canonicals, descriptions, theme/color scheme) and manifests are now consistent across pages.

@coderabbitai
Copy link

coderabbitai bot commented Oct 14, 2025

Walkthrough

Replaces many exported SEO constants with a typed Web model and slug constants; introduces Web, WebPage, and WebPageUrls; wires a Web instance into Generator, Manifest, and JsonLD APIs; updates templates and tests to resolve page names/URLs via Web getters; NewManifest and NewJsonID now accept a Web.

Changes

Cohort / File(s) Summary
Defaults to Slugs and Author
metal/cli/seo/defaults.go
Removes numerous public URL/name/branding constants; adds AuthorName and page slug constants (HomeSlug, AboutSlug, ProjectsSlug, ResumeSlug, PostsSlug, PostDetailsSlug).
Web model & accessors
metal/cli/seo/web.go
Adds Web, WebPage, WebPageUrls types and NewWeb() constructor; initializes pages and Urls; provides GetHomePage, GetAboutPage, GetResumePage, GetProjectsPage, GetPostsPage, GetPostsDetailPage.
Generator wired to Web
metal/cli/seo/generator.go
Adds Generator.Web *Web; initializes with NewWeb(); replaces static constants with g.Web lookups; passes g.Web into NewJsonID and NewManifest; updates page-building logic to use Web getters.
Manifest uses Web
metal/cli/seo/manifest.go
Changes NewManifest(tmpl, data)NewManifest(tmpl, data, web); replaces static URL/name constants with values from web (page Url/Name/ShortName) for scope and shortcuts.
JSON‑LD uses Web
metal/cli/seo/jsonld.go
Changes NewJsonID(tmpl)NewJsonID(tmpl, web); sources FoundedYear and related metadata from web.
Tests updated for Web
metal/cli/seo/generator_test.go, metal/cli/seo/manifest_test.go
Tests now create/use NewWeb() and obtain page data via gen.Web.Get...(); constructor calls updated to pass a Web where required.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as CLI/Caller
  participant Gen as Generator
  participant Web as Web
  participant JLD as JsonLD
  participant Man as Manifest

  Note over Gen,Web: initialization
  Dev->>Gen: NewGenerator(...)
  Gen->>Web: NewWeb()
  Web-->>Gen: *Web instance*

  Note over Gen: page build flow
  Dev->>Gen: BuildForPage("home")
  Gen->>Web: GetHomePage()
  Web-->>Gen: WebPage{Name, Url, Title, Excerpt}

  Gen->>JLD: NewJsonID(Page, Web)
  JLD-->>Gen: Json-LD

  Gen->>Man: NewManifest(Page, TemplateData, Web)
  Man-->>Gen: Manifest

  Gen-->>Dev: Rendered assets (meta, manifest, json-ld)

  alt Post detail
    Dev->>Gen: BuildForPost(slug)
    Gen->>Web: GetPostsDetailPage()
    Web-->>Gen: WebPage
    Gen->>JLD: NewJsonID(Page, Web)
    Gen-->>Dev: Post SEO outputs
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

A rabbit hops through slug-lined rows,
Tidy pages where the wild data grows.
Generator hums, Web holds the map,
Manifest and JSON-LD take a nap.
Carrots of metadata, neat and bright — 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The title uses generic terms like “Better SEO info” and “refactor” which do not clearly describe the core change, which is the consolidation of static metadata into a dynamic Web model with slug-based page routing. It doesn’t mention the removal of numerous constants or the introduction of new Web and WebPage types for SEO. As a result, someone scanning the history wouldn’t immediately grasp that the PR centralizes SEO constants and updates generator and manifest functions to use the new Web object. The current title is too broad and lacks specificity about the main feature or refactor. Update the title to specifically reference the key changes in this PR, such as “refactor(seo): centralize metadata into Web model with slug-based routing,” to clearly communicate the introduction of the Web type, slug constants, and removal of static URL and metadata constants. This more precise phrasing helps teammates quickly understand the main impact of the PR when scanning the history.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/enrich-seo

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef10049 and 7e987a5.

📒 Files selected for processing (2)
  • metal/cli/seo/generator.go (12 hunks)
  • metal/cli/seo/web.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • metal/cli/seo/web.go
  • metal/cli/seo/generator.go

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gocanto gocanto added testing and removed testing labels Oct 14, 2025
@gocanto gocanto added testing and removed testing labels Oct 14, 2025
@gocanto gocanto changed the title start working on structure feat: Better Seo info + refactor Oct 14, 2025
@gocanto gocanto marked this pull request as ready for review October 14, 2025 08:18
@gocanto gocanto changed the title feat: Better Seo info + refactor feat: Better SEO info + refactor Oct 14, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (5)
metal/cli/seo/jsonld.go (2)

27-41: Defensive nil check for web in NewJsonID

Passing a nil web will panic when accessing web.FoundedYear. Add a small guard with a safe fallback.

-func NewJsonID(tmpl Page, web *Web) *JsonID {
-	return &JsonID{
+func NewJsonID(tmpl Page, web *Web) *JsonID {
+	fy := ""
+	if web != nil {
+		fy = fmt.Sprintf("%d", web.FoundedYear)
+	}
+	return &JsonID{
 		Lang:        tmpl.Lang,
 		SiteURL:     tmpl.SiteURL,
 		LogoURL:     tmpl.LogoURL,
 		OrgName:     tmpl.SiteName,
 		WebName:     tmpl.SiteName,
 		APIName:     tmpl.SiteName,
 		SameAs:      tmpl.SameAsURL,
 		APIRepoURL:  tmpl.APIRepoURL,
 		WebRepoURL:  tmpl.WebRepoURL,
-		FoundedYear: fmt.Sprintf("%d", web.FoundedYear),
+		FoundedYear: fy,
 		Now:         func() time.Time { return time.Now().UTC() },
 	}
 }

49-60: Use schema.org-standard foundingDate

foundedYear isn’t a schema.org property. Prefer foundingDate (a year string is acceptable).

-            "foundedYear": j.FoundedYear,
+            "foundingDate": j.FoundedYear,
metal/cli/seo/manifest_test.go (1)

78-80: Strengthen assertion: validate shortcut contents

You already check presence. Consider asserting first shortcut URL/name to ensure Web is actually used.

   if got["shortcuts"] == nil {
     t.Fatalf("expected shortcuts in manifest")
   }
+  sc := got["shortcuts"].([]any)
+  first := sc[0].(map[string]any)
+  if first["url"] != "/" || first["name"] != "Home" {
+    t.Fatalf("unexpected first shortcut: %#v", first)
+  }
metal/cli/seo/manifest.go (1)

41-98: Guard against nil web and consider scope consistency

  • If web is nil, this will panic. Add a small guard to default to NewWeb() or document and enforce non-nil.
  • Optional: set Scope to an absolute URL (e.g., tmpl.SiteURL + "/") for consistency with StartURL.
  • Optional: store web.Get*Page() into locals to avoid repetitive lookups.

Example minimal guard:

-func NewManifest(tmpl Page, data TemplateData, web *Web) *Manifest {
+func NewManifest(tmpl Page, data TemplateData, web *Web) *Manifest {
+	if web == nil {
+		web = NewWeb()
+	}
metal/cli/seo/web.go (1)

20-26: Acronym casing consistency (URL vs Url)

Go style prefers consistent acronym casing (e.g., LogoURL, RepoAPIURL). Consider aligning new fields to that style in a future cleanup to reduce cognitive load. Non-blocking.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d7690ad and ef10049.

📒 Files selected for processing (7)
  • metal/cli/seo/defaults.go (1 hunks)
  • metal/cli/seo/generator.go (12 hunks)
  • metal/cli/seo/generator_test.go (4 hunks)
  • metal/cli/seo/jsonld.go (2 hunks)
  • metal/cli/seo/manifest.go (3 hunks)
  • metal/cli/seo/manifest_test.go (2 hunks)
  • metal/cli/seo/web.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (6)
metal/cli/seo/jsonld.go (2)
metal/cli/seo/data.go (1)
  • Page (5-18)
metal/cli/seo/web.go (1)
  • Web (3-11)
metal/cli/seo/manifest_test.go (2)
metal/cli/seo/manifest.go (1)
  • NewManifest (41-99)
metal/cli/seo/web.go (1)
  • NewWeb (28-104)
metal/cli/seo/manifest.go (2)
metal/cli/seo/data.go (2)
  • Page (5-18)
  • TemplateData (20-38)
metal/cli/seo/web.go (1)
  • Web (3-11)
metal/cli/seo/web.go (1)
metal/cli/seo/defaults.go (7)
  • AuthorName (4-4)
  • HomeSlug (5-5)
  • AboutSlug (6-6)
  • ProjectsSlug (7-7)
  • ResumeSlug (8-8)
  • PostsSlug (9-9)
  • PostDetailsSlug (10-10)
metal/cli/seo/generator_test.go (1)
metal/cli/seo/web.go (2)
  • Web (3-11)
  • NewWeb (28-104)
metal/cli/seo/generator.go (4)
metal/cli/seo/web.go (2)
  • Web (3-11)
  • NewWeb (28-104)
metal/cli/seo/data.go (1)
  • Page (5-18)
metal/cli/seo/jsonld.go (1)
  • NewJsonID (27-41)
metal/cli/seo/manifest.go (2)
  • Manifest (10-24)
  • NewManifest (41-99)
🔇 Additional comments (12)
metal/cli/seo/manifest_test.go (2)

58-60: LGTM: passing NewWeb() to NewManifest

Matches the new API and keeps test determinism via manifest.Now.


126-128: LGTM: updated NewManifest call

Refactor aligns with new constructor signature.

metal/cli/seo/generator_test.go (1)

56-62: LGTM: tests updated to use Web context

Injecting NewWeb() and sourcing home page data via GetHomePage() matches the refactor and keeps tests readable.

Also applies to: 119-124, 265-266, 347-348

metal/cli/seo/defaults.go (1)

4-10: LGTM: centralized author and slug constants

This reduces scattered URL/name constants and aligns with the new Web model.

metal/cli/seo/generator.go (8)

30-38: LGTM! Clean refactoring to centralize SEO configuration.

Adding the Web field centralizes SEO configuration data, which improves maintainability and reduces scattered constants throughout the codebase.


52-88: LGTM! Web initialization properly wired.

The Web instance is created and properly integrated into the Generator. Field population from web.Urls is consistent, and validation occurs at the right point (line 73).


377-383: LGTM! Web fields properly integrated.

The refactoring correctly replaces scattered constants with centralized g.Web fields for robots, theme color, color scheme, background color, and description. The updated NewJsonID signature with the g.Web parameter is also correctly applied.

Also applies to: 385-385


463-463: LGTM! Dynamic home page name comparison.

The comparison now uses g.Web.GetHomePage().Name instead of a static constant, which is consistent with the refactoring approach.


489-489: LGTM! Centralized description fallback.

Using g.Web.Description as the fallback ensures consistency across the application. Based on the NewWeb() implementation in the relevant code snippets, the Description field is always populated, so this is safe.


522-528: LGTM! Dynamic post detail URL generation.

The refactoring correctly replaces the static WebPostDetailUrl constant with g.Web.GetPostsDetailPage().Url, ensuring URLs are sourced from the centralized Web model.


405-405: Verified NewManifest signature update All call sites now pass the *Web parameter.


152-153: Ignore missing Web getters All referenced getter methods (GetHomePage, GetAboutPage, GetProjectsPage, GetResumePage) are implemented in metal/cli/seo/web.go; no action required.

Likely an incorrect or invalid review comment.

@gocanto gocanto merged commit 3aa306e into main Oct 14, 2025
1 check passed
@gocanto gocanto deleted the feat/enrich-seo branch October 14, 2025 08:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants