Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ jobs:
- name: Build example - multi-page
run: go run ./cmd/inkssg build ./examples/multi-page

- name: Build example - bio
run: go run ./cmd/inkssg build ./examples/bio

- name: Build example - library
working-directory: examples/library
run: |
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ Build output goes to `public/`.

## Themes

inkssg ships with two themes: `minimal` and `devtool`. Pick one in `ink.yaml`:
inkssg ships with three themes: `minimal`, `devtool`, and `bio`. Pick one in `ink.yaml`:

```yaml
default_theme: devtool
Expand Down
31 changes: 31 additions & 0 deletions examples/bio/ink.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: snowz.ai
avatar: /assets/img/avatar.png
bio: Open Source Engineer · AI workflows and tools
status: currently building vikusha
default_theme: bio
output_dir: public

meta:
lang: en
title: snowz.ai
description: AI workflows and developer tools.
siteUrl: https://snowz.ai

projects:
- name: vikusha
description: framework for AI assistants
url: https://github.com/snowztech/vikusha
badge: go · wip
- name: nevinho
description: my personal AI assistant
url: https://github.com/lucasnevespereira/nevinho
badge: go

contact:
socials:
- name: github
url: https://github.com/snowztech
- name: youtube
url: https://www.youtube.com/c/lucaasnp
- name: tiktok
url: https://www.tiktok.com/@snowz.ai
4 changes: 4 additions & 0 deletions examples/bio/pages/index/content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
---
title: snowz.ai
description: AI workflows and developer tools
---
28 changes: 19 additions & 9 deletions inkssg.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,25 @@ type Page struct {
}

type SiteConfig struct {
Name string `yaml:"name"`
Avatar string `yaml:"avatar"`
Bio string `yaml:"bio"`
Install string `yaml:"install"`
DefaultTheme string `yaml:"default_theme"`
OutputDir string `yaml:"output_dir"`
Links []Link `yaml:"links"`
Meta Meta `yaml:"meta"`
Contact Contact `yaml:"contact"`
Name string `yaml:"name"`
Avatar string `yaml:"avatar"`
Bio string `yaml:"bio"`
Status string `yaml:"status"`
Install string `yaml:"install"`
DefaultTheme string `yaml:"default_theme"`
OutputDir string `yaml:"output_dir"`
Links []Link `yaml:"links"`
Projects []Project `yaml:"projects"`
Meta Meta `yaml:"meta"`
Contact Contact `yaml:"contact"`
}

type Project struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
URL string `yaml:"url"`
Image string `yaml:"image"`
Badge string `yaml:"badge"`
}

type Link struct {
Expand Down
88 changes: 88 additions & 0 deletions themes/bio/layout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<!DOCTYPE html>
<html lang="{{if .Site.Meta.Lang}}{{.Site.Meta.Lang}}{{else}}en{{end}}">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="{{if .Site.Meta.Description}}{{.Site.Meta.Description}}{{else}}{{.Page.Description}}{{end}}" />
<title>{{if .Site.Meta.Title}}{{.Site.Meta.Title}}{{else}}{{.Page.Title}}{{end}}</title>
{{if .Site.Meta.Author}}<meta name="author" content="{{.Site.Meta.Author}}" />{{end}}
{{if .Site.Meta.SiteUrl}}<link rel="canonical" href="{{.Site.Meta.SiteUrl}}" />{{end}}

<link rel="icon" type="image/png" href="/assets/icons/favicon.png" sizes="96x96" />
<link rel="icon" type="image/svg+xml" href="/assets/icons/favicon.svg" />
<link rel="shortcut icon" href="/assets/icons/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
<link rel="manifest" href="/assets/icons/site.webmanifest" />

<link rel="stylesheet" href="/themes/bio/styles.css" />

{{if .Site.Meta.Title}}
<meta property="og:title" content="{{.Site.Meta.Title}}" />
<meta property="og:site_name" content="{{.Site.Meta.Title}}" />
{{end}}
{{if .Site.Meta.Description}}<meta property="og:description" content="{{.Site.Meta.Description}}" />{{end}}
{{if .Site.Meta.Lang}}<meta property="og:locale" content="{{.Site.Meta.Lang}}" />{{end}}
{{if .Site.Avatar}}
<meta property="og:image" content="{{.Site.Meta.SiteUrl}}{{.Site.Avatar}}" />
<meta name="twitter:image" content="{{.Site.Avatar}}" />
<meta name="twitter:card" content="summary" />
{{end}}
</head>
<body>
<main>
<header>
{{if .Site.Avatar}}
<img src="{{.Site.Avatar}}" alt="{{.Site.Name}}" class="avatar" />
{{end}}
<div class="header-actions">
<button id="theme-toggle" class="theme-toggle" aria-label="Toggle theme">
<span class="theme-icon">○</span>
</button>
</div>
</header>

<div class="hero">
{{if .Site.Name}}<div class="hero-name">{{.Site.Name}}</div>{{end}}
{{if .Site.Bio}}<div class="hero-tagline">{{.Site.Bio}}</div>{{end}}
{{if .Site.Status}}
<div class="status">
<span class="status-dot"></span>
<span>{{.Site.Status}}</span>
</div>
{{end}}
</div>

{{if .Content}}<div class="content">{{.Content}}</div>{{end}}

{{if .Site.Projects}}
<div class="projects">
<div class="section-label">// projects</div>
<ul>
{{range .Site.Projects}}
<li class="project">
{{if .Image}}<img src="{{.Image}}" class="project-icon" alt="" />{{end}}
<div class="project-body">
<span class="project-name">{{if .URL}}<a href="{{.URL}}">{{.Name}}</a>{{else}}{{.Name}}{{end}}</span>
{{if .Description}}<span class="project-desc">{{.Description}}</span>{{end}}
</div>
{{if .Badge}}<span class="project-meta">{{.Badge}}</span>{{end}}
</li>
{{end}}
</ul>
</div>
{{end}}

<footer>
<div class="links">
{{if .Site.Contact.Socials}}
{{range .Site.Contact.Socials}}<a href="{{.URL}}" target="_blank" rel="noopener noreferrer">{{.Name}}</a>{{end}}
{{else if .Site.Links}}
{{range .Site.Links}}<a href="{{.URL}}" target="_blank" rel="noopener noreferrer">{{.Name}}</a>{{end}}
{{end}}
</div>
<span class="copyright">© <span class="year"></span></span>
</footer>
</main>
<script src="/themes/bio/script.js"></script>
</body>
</html>
46 changes: 46 additions & 0 deletions themes/bio/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
(function () {
const toggle = document.getElementById("theme-toggle");
const icon = toggle?.querySelector(".theme-icon");
const body = document.body;

let savedTheme;
try {
savedTheme = localStorage.getItem("theme");
} catch (err) {}

const prefersDark = window.matchMedia("(prefers-color-scheme: dark)").matches;
const currentTheme = savedTheme || (prefersDark ? "dark" : "light");

if (currentTheme === "dark") {
body.classList.add("dark");
document.documentElement.classList.remove("light");
if (icon) icon.textContent = "●";
} else {
body.classList.remove("dark");
document.documentElement.classList.add("light");
if (icon) icon.textContent = "○";
}

if (toggle) {
const handleToggle = (e) => {
e.preventDefault();
e.stopPropagation();
const isDark = body.classList.toggle("dark");
if (isDark) {
document.documentElement.classList.remove("light");
} else {
document.documentElement.classList.add("light");
}
try {
localStorage.setItem("theme", isDark ? "dark" : "light");
} catch (err) {}
if (icon) icon.textContent = isDark ? "●" : "○";
};

toggle.addEventListener("click", handleToggle);
toggle.addEventListener("touchend", handleToggle, { passive: false });
}

const yearEl = document.querySelector(".year");
if (yearEl) yearEl.textContent = new Date().getFullYear();
})();
Loading
Loading