Skip to content

Repository files navigation

opendesign-site-generator

A data-driven, dependency-free Go static-site generator for the OpenDesign design system. It renders product, portfolio, and home pages from plain data — portfolio.json, product markdown, and a per-site home.json — and emits production-grade SEO for every page: <title>/meta, canonical, Open Graph, Twitter Card, reciprocal hreflang, JSON-LD (Organization/Person, WebSite, SoftwareApplication), plus sitemap.xml and robots.txt.

No page is hardcoded. Go holds only layout and templates; every product name, status, tech chip, repository link, and copy string comes from data. Point it at a different data root and it renders a different site.

  • Zero third-party dependencies — standard library only (go.mod has no require block).
  • Deterministic output — the same data always produces byte-identical HTML, which makes diffing and evidence-based QA practical.
  • i18n-aware — hreflang alternates are generated for every _content_<lang>/ directory found on disk; per-language page output is a single flag.
  • Durable asset sync — a companion script copies every design-system asset a page needs into <site>/assets/od/ so deployed pages are fully self-contained and never link back into the source tree (see USAGE.md).

Why

Hand-maintained marketing/portfolio sites drift: a product ships, its status, license, or repo list changes, and three HTML pages silently go stale. This tool makes the data the single source of truth. Update portfolio.json once and every product card, product page, JSON-LD node, and sitemap entry regenerates consistently. A page is only "done" when it renders from real data.

Install / build

Requires Go 1.26+. No network access is needed to build (no external modules).

git clone https://github.com/vasic-digital/opendesign-site-generator.git
cd opendesign-site-generator
go build -o gen .        # builds the `gen` command
go build ./...           # or: build every package

Usage

gen -site <key> [-lang en] [-what all|products|portfolio|home] [-root <dir>] [-out <dir>]
Flag Default Meaning
-site (required) Site key selecting a built-in site definition (brand, domain, CSS name, OG image, JSON-LD identity). See DATA-CONTRACT.md.
-lang en Language code. en is canonical (unprefixed output); any other code writes localized paths (products/<lang>/…, <lang>/…).
-what all What to render: all, products, portfolio, or home.
-root . Data/repository root. The generator reads <root>/_content/** and <root>/design-system/** (optional diagrams) from here.
-out <root>/<site.Dir> Output base directory for generated HTML.

sitemap.xml + robots.txt are written on a full -what all English build, walking the actual output tree so every sitemap URL resolves to a real file.

Quickstart (runnable example)

The examples/ directory ships a complete, self-contained data set and the output it produces:

go build -o gen .
./gen -site vasic.digital -root examples/data -out /tmp/site-out
# [gen] site=vasic.digital lang=en what=all out=/tmp/site-out products=2
find /tmp/site-out -type f
#   index.html  portfolio/index.html
#   products/helixtrack.html  products/sampleutil.html
#   robots.txt  sitemap.xml

The committed sample of that exact output lives in examples/output/. See examples/README.md.

Data contract

The full JSON / markdown / frontmatter schema the generator consumes — so another project can supply its own data — is documented in DATA-CONTRACT.md. Per-language generation, the durable asset-sync workflow, and the exact SEO output are documented in USAGE.md.

Tests

26 standard-library unit tests cover escaping, frontmatter parsing, markdown rendering, portfolio cards, language discovery, hreflang reciprocity, JSON-LD, the SEO head, and sitemap/robots generation. They read fixtures from testdata/, so they pass in a clean checkout with no external data:

$ go build ./...
$ go test ./...
ok  	github.com/vasic-digital/opendesign-site-generator	0.595s

Verbose (all 26):

$ go test -v ./...
=== RUN   TestEscEscapesQuotes
--- PASS: TestEscEscapesQuotes (0.00s)
=== RUN   TestParseFrontmatter
--- PASS: TestParseFrontmatter (0.00s)
=== RUN   TestParseFrontmatterNoFrontmatter
--- PASS: TestParseFrontmatterNoFrontmatter (0.00s)
=== RUN   TestLoadPortfolioAndBySlug
--- PASS: TestLoadPortfolioAndBySlug (0.00s)
=== RUN   TestPortfolioDataHasNoPrivateLeak
--- PASS: TestPortfolioDataHasNoPrivateLeak (0.00s)
=== RUN   TestEscText
--- PASS: TestEscText (0.00s)
=== RUN   TestInline
--- PASS: TestInline (0.00s)
=== RUN   TestRenderBody
--- PASS: TestRenderBody (0.00s)
=== RUN   TestRenderBodyIndentation
--- PASS: TestRenderBodyIndentation (0.00s)
=== RUN   TestRenderBodyEmpty
--- PASS: TestRenderBodyEmpty (0.00s)
=== RUN   TestRepoLabel
--- PASS: TestRepoLabel (0.00s)
=== RUN   TestLicHideRe
--- PASS: TestLicHideRe (0.00s)
=== RUN   TestPortfolioCardChipCap
--- PASS: TestPortfolioCardChipCap (0.00s)
=== RUN   TestPortfolioCardHidesTBDLicense
--- PASS: TestPortfolioCardHidesTBDLicense (0.00s)
=== RUN   TestFirstNonEmpty
--- PASS: TestFirstNonEmpty (0.00s)
=== RUN   TestXMLDeclStripped
--- PASS: TestXMLDeclStripped (0.00s)
=== RUN   TestProductHref
--- PASS: TestProductHref (0.00s)
=== RUN   TestI18nAttr
--- PASS: TestI18nAttr (0.00s)
=== RUN   TestSiteURL
--- PASS: TestSiteURL (0.00s)
=== RUN   TestLangPath
--- PASS: TestLangPath (0.00s)
=== RUN   TestAvailableLangs
--- PASS: TestAvailableLangs (0.00s)
=== RUN   TestHreflangLinksReciprocal
--- PASS: TestHreflangLinksReciprocal (0.00s)
=== RUN   TestJSONLDScriptHasType
--- PASS: TestJSONLDScriptHasType (0.00s)
=== RUN   TestSoftwareApplicationNodeHidesTBDLicense
--- PASS: TestSoftwareApplicationNodeHidesTBDLicense (0.00s)
=== RUN   TestSeoHeadSingletons
--- PASS: TestSeoHeadSingletons (0.00s)
=== RUN   TestWriteSitemapRobots
--- PASS: TestWriteSitemapRobots (0.02s)
PASS
ok  	github.com/vasic-digital/opendesign-site-generator	0.595s

Project layout

main.go         command entry, flag parsing, site definitions (the `sites` map)
data.go         portfolio + home data models, JSON loaders, frontmatter parser
portfolio.go    portfolio index page renderer
product.go      product detail page renderer
home.go         home page renderer (standalone + Jekyll shells)
markdown.go     minimal markdown -> HTML (headings, lists, bold, code)
seo.go          SEO head, hreflang, JSON-LD graph, sitemap.xml + robots.txt
shells.go       shared layout chrome (SVG symbols, inline styles, theme toggle)
build.sh        reference site-integration script: asset sync + per-site generation
testdata/       fixtures the unit tests read (self-contained)
examples/       runnable data set + committed sample output

License

MIT.

About

Data-driven Go static-site generator for the OpenDesign system: product/portfolio/home pages, SEO (JSON-LD/hreflang/sitemap), i18n, durable asset sync

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages