diff --git a/.gitignore b/.gitignore index f2bfcf4..7e17006 100644 --- a/.gitignore +++ b/.gitignore @@ -172,3 +172,10 @@ dist .svelte-kit # End of https://www.toptal.com/developers/gitignore/api/node + +# Test files +public/ +config.json +legal.html +test.html +test.json diff --git a/README.md b/README.md index 4b43725..383372f 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,7 @@ # Now +Self-hostable bio page website, like carrd, guns.lol and many more! -Self-hostable bio page website! - -Lightweight and heavily customizable Go application! +Lightweight and heavily customizable Go application. ![Screenshot of the main page](./example.jpg) @@ -11,8 +10,139 @@ Lightweight and heavily customizable Go application! ![Screenshot of a custom page](./games.webp) ## Config +You must have a `public` directory. +Everything located inside will be available at the path `/static/PATH` where `PATH` is the relative path inside the +`public` directory. -Coming soon +You can change the font by adding a file named `font.woff2` inside the `public` directory. +This font must be compressed by [Woff2](https://en.wikipedia.org/wiki/Web_Open_Font_Format). +(You can compress them with the command `woff2_compress` available in the package `woff2` of many Linux distributions.) + +### Main config +You can create a sample config with the flag `-generate-json-config` (which generates a JSON config) or with +`-generate-toml-config` (which generates a TOML config). +A JSON schema is available for JSON configs. + +The config does not depend on the markup language: a field `foo` will being named `foo` for JSON and TOML. +The TOML format is used in this section. + +The root is defining the background image, the description, the file's path to the legal pages, the path to +the configs of custom pages and a list of all your ["rel-me"](https://microformats.org/wiki/rel-me) links. +(The "rel-me" links are required to +[verify a link on your Mastodon account](https://docs.joinmastodon.org/user/profile/#verification), for example.) +```toml +image = "wallpaper.webp" +description = "I am a beautiful description!" +legal = "legal.html" +custom_pages = ["custom.toml"] +rel_me_links = ["https://foo.example.org/@bar"] +``` +The path is relative to the execution of the binary. +If you are using Docker, please use a static path. + +The first section is defining who you are. +`image` is your pfp. +It must be placed inside the `public` directory. +```toml +[person] + name = "John Doe" + pronouns = "any" + image = "pfp.webp" + + [[person.tags]] + name = "Hello" + description = "World" + link = "" + + [[person.tags]] + name = "I am" + description = "a tag" + link = "" +``` + +Then, you define the colors of the main page. +`text` is the text's color. +`tag_hover` is the background's color of a tag when someone hover it. +`colors.background` defines the card's background (check the CSS property `gradiant` on +[MDN](https://developer.mozilla.org/en-US/docs/Web/CSS/gradient) to have more information). +`colors.buttons` defines buttons' colors. +```toml +[colors] + text = "#fff" + tag_hover = "#000" + [colors.background] + type = "linear" + angle = 141 + + [[colors.background.colors]] + color = "#a4a2b8" + position = 0 + + [[colors.background.colors]] + color = "#3b3860" + position = 40 + + [[colors.background.colors]] + color = "#0f0c2c" + position = 80 + [colors.buttons] + text = "#4c0850" + text_hover = "#57145b" + background = "#f399d0" + background_hover = "#f5c0e0" +``` + +Finally, you define the link at the bottom of your card. +You can have as much of these as you want. +```toml +[[links]] + link = "/foo" + content = "Blog" + +[[links]] + link = "https://www.youtube.com/@anhgelus" + content = "YouTube" +``` + +### Custom page config +You can create custom pages with a new config. +It can also be a JSON or a TOML file. + +The root defines the title of the page, the uri (must be unique!), the image and the description. +`content` is the file's path containing the content of your custom page. +```toml +title = "Foo" +uri = "/bar" +image = "wallpaper.webp" +description = "I am a beautiful description!" +content = "foo-bar.html" +``` + +Then, you can define custom colors. +Check _Main config_'s colors section for more information. +The `tag_hover` field is useless here. + +### HTML content files +When you define a custom page or when you have to set the legal information, you have to specify the path of an HTML +file. +It contains the content that would be displayed in the page. +You can use all HTML common tags like `h2`, `p` and `a`. +(`h1` is already used by the title.) + +If you want to use buttons, you must follow this structure: +```html + +``` +Their style is defined by the config. +You can change their style by defining these CSS variables `--text-color`, `--text-color-hover`, `--background` and +`--background-hover`. ## Technologies used diff --git a/config.schema.json b/config.schema.json index 2e8a7c1..f2a2600 100644 --- a/config.schema.json +++ b/config.schema.json @@ -160,6 +160,9 @@ }, "custom_pages": { "type": "array" + }, + "rel_me_links": { + "type": "array" } }, "additionalProperties": false, diff --git a/data.go b/data.go index de58d99..f95289a 100644 --- a/data.go +++ b/data.go @@ -7,17 +7,13 @@ import ( "github.com/anhgelus/golatt" "html/template" "os" + "regexp" "strconv" "strings" ) -const ( - TitleContentType = "title" - SubtitleContentType = "subtitle" - ParagraphContentType = "paragraph" - ListContentType = "list" - OrderedListContentType = "ordered_list" - ButtonsContentType = "links" +var ( + regexExternalLink = regexp.MustCompile(`https?://`) ) type ConfigData interface { @@ -34,6 +30,7 @@ type Config struct { Color *Color `json:"colors" toml:"colors"` Links []*Link `json:"links" toml:"links"` Legal string `json:"legal" toml:"legal"` + RelMeLinks []string `json:"rel_me_links" toml:"rel_me_links"` CustomPages []string `json:"custom_pages" toml:"custom_pages"` } @@ -78,12 +75,19 @@ type Link struct { Content string `json:"content" toml:"content"` } +func getImage(s string) string { + if regexExternalLink.MatchString(s) { + return s + } + return golatt.GetStaticPath(s) +} + func (c *Config) GetBackground() template.CSS { return c.Color.GetBackground() } func (c *Config) GetBackgroundImage() template.CSS { - return template.CSS("--background-image: url(" + golatt.GetStaticPath(c.Image) + ");") + return template.CSS("--background-image: url(" + getImage(c.Image) + ");") } func (c *Config) GetTextColor() template.CSS { @@ -176,7 +180,7 @@ func (p *CustomPage) GetTextColor() template.CSS { } func (p *CustomPage) GetBackgroundImage() template.CSS { - return template.CSS("--background-image: url(" + golatt.GetStaticPath(p.Image) + ");") + return template.CSS("--background-image: url(" + getImage(p.Image) + ");") } func (p *CustomPage) GetBackground() template.CSS { diff --git a/games.webp b/games.webp deleted file mode 100644 index f2eadab..0000000 Binary files a/games.webp and /dev/null differ diff --git a/main.go b/main.go index bf5905e..23c3f69 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "fmt" "github.com/BurntSushi/toml" "github.com/anhgelus/golatt" + "html/template" "log/slog" "net/http" "os" @@ -23,17 +24,19 @@ var ( var ( domain string configPath string - dev bool + dev bool = false generateToml bool generateJson bool + port int = 80 ) func init() { flag.StringVar(&domain, "domain", "", "domain to use") flag.StringVar(&configPath, "config", "", "config to use") - flag.BoolVar(&dev, "dev", false, "dev mode enabled") + flag.BoolVar(&dev, "dev", dev, "dev mode enabled") flag.BoolVar(&generateJson, "generate-json-config", false, "generate a config example") flag.BoolVar(&generateToml, "generate-toml-config", false, "generate a config example") + flag.IntVar(&port, "port", port, "set the port to use") } func main() { @@ -125,11 +128,19 @@ func main() { http.Redirect(w, r, "/", http.StatusTemporaryRedirect) } + g.TemplateFuncMap = template.FuncMap{ + "getImage": getImage, + } + + host := fmt.Sprintf(":%d", port) if dev { - slog.Info("Starting on http://localhost:8000/") - g.StartServer(":8000") + if port != 80 { + g.StartServer(host) + } else { + g.StartServer(":8000") + } } else { - g.StartServer(":80") + g.StartServer(host) } } @@ -174,6 +185,7 @@ func generateConfigFile(isToml bool) { }, Legal: "legal.html", CustomPages: []string{"custom.json"}, + RelMeLinks: []string{"https://foo.example.org/@bar"}, } var b []byte var err error diff --git a/music.webp b/music.webp deleted file mode 100644 index 43da11f..0000000 Binary files a/music.webp and /dev/null differ diff --git a/scss/main.scss b/scss/main.scss index ac9b340..2759576 100644 --- a/scss/main.scss +++ b/scss/main.scss @@ -4,6 +4,7 @@ :root { --text-color: #000; + font-size: 18px; } @font-face { @@ -13,13 +14,12 @@ body { --background-image: ; - font-size: 18px; - font-family: "custom", "serif"; - background: var(--background-image) center fixed no-repeat; + font-family: "custom", Raveo, Inter, Roboto, sans-serif; + background: #000; background-size: cover; color: var(--text-color); - @media only screen and (max-width: vars.$bp-little) { - background: #000; + @media only screen and (min-width: vars.$bp-little) { + background: var(--background-image) center fixed no-repeat black; } } @@ -101,23 +101,23 @@ p { } h1 { - font-size: 3rem; + font-size: 1.75rem; } h2 { - font-size: 2rem; + font-size: 1.5rem; font-weight: bold; @media only screen and (max-width: vars.$bp-little) { - font-size: 1.75rem; + font-size: 1.425rem; } } h3 { - font-size: 1.5rem; + font-size: 1.35rem; } h4 { - font-size: 1.35rem; + font-size: 1.25rem; } ul, ol { diff --git a/templates/base/base.gohtml b/templates/base/base.gohtml index 3b1e37c..fced948 100644 --- a/templates/base/base.gohtml +++ b/templates/base/base.gohtml @@ -12,6 +12,10 @@ + {{ else }} + {{ range .Data.RelMeLinks }} + + {{ end }} {{ end }} @@ -24,4 +28,4 @@ -{{end}} \ No newline at end of file +{{end}} diff --git a/templates/page/custom_page.gohtml b/templates/page/custom_page.gohtml index 4e53d4b..5b4de00 100644 --- a/templates/page/custom_page.gohtml +++ b/templates/page/custom_page.gohtml @@ -1,7 +1,7 @@ {{define "body"}}
-

{{ .Title }}

+

{{ .Title }}