it works!
initial build that basically replicates my old HTML site
This commit is contained in:
parent
0d809bfea8
commit
a7f6bb35e7
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
bin/
|
31
cmd/web/main.go
Normal file
31
cmd/web/main.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
// Main entry point for the web app. Does all
|
||||
// the setup, then runs the http server.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.burning.moe/celediel/burning.moe/internal/config"
|
||||
"git.burning.moe/celediel/burning.moe/internal/handlers"
|
||||
"git.burning.moe/celediel/burning.moe/internal/render"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Initialise app and config
|
||||
app := config.Initialise()
|
||||
|
||||
// Initialise handlers and renderer
|
||||
handlers.Initialise(&app)
|
||||
render.Initialise(&app)
|
||||
|
||||
// Initialise the webserver
|
||||
srv := &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", app.ListenPort),
|
||||
Handler: routes(&app),
|
||||
}
|
||||
|
||||
// and finally, start the server
|
||||
app.Logger.Printf("Listening on port %d", app.ListenPort)
|
||||
srv.ListenAndServe()
|
||||
}
|
31
cmd/web/routes.go
Normal file
31
cmd/web/routes.go
Normal file
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.burning.moe/celediel/burning.moe/internal/config"
|
||||
"git.burning.moe/celediel/burning.moe/internal/handlers"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
)
|
||||
|
||||
// routes handles all of the HTTP setup. Middleware is enabled,
|
||||
// static fileserver is setup, and handlers are ... handled
|
||||
func routes(app *config.AppConfig) http.Handler {
|
||||
mux := chi.NewRouter()
|
||||
|
||||
// Import some middleware
|
||||
mux.Use(middleware.Recoverer)
|
||||
|
||||
// Setup static file server
|
||||
app.Logger.Debug("Setting up /static file server")
|
||||
mux.Handle("/static/*", http.StripPrefix("/static", http.FileServer(http.Dir("./static"))))
|
||||
|
||||
// Setup routes for handlers
|
||||
for _, handler := range handlers.Handlers {
|
||||
app.Logger.Info("Setting up handler for " + handler.Handles)
|
||||
mux.Get(handler.Handles, handler.Handler)
|
||||
}
|
||||
|
||||
return mux
|
||||
}
|
25
go.mod
25
go.mod
|
@ -1,3 +1,28 @@
|
|||
module git.burning.moe/celediel/burning.moe
|
||||
|
||||
go 1.21.5
|
||||
|
||||
require (
|
||||
github.com/go-chi/chi/v5 v5.0.11
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0
|
||||
github.com/magefile/mage v1.15.0
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/BurntSushi/toml v1.3.2 // indirect
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/charmbracelet/lipgloss v0.9.1 // indirect
|
||||
github.com/charmbracelet/log v0.3.1 // indirect
|
||||
github.com/go-logfmt/logfmt v0.6.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.18 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.15 // indirect
|
||||
github.com/muesli/reflow v0.3.0 // indirect
|
||||
github.com/muesli/termenv v0.15.2 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect
|
||||
golang.org/x/sys v0.13.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 // indirect
|
||||
)
|
||||
|
|
43
go.sum
Normal file
43
go.sum
Normal file
|
@ -0,0 +1,43 @@
|
|||
github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/charmbracelet/lipgloss v0.9.1 h1:PNyd3jvaJbg4jRHKWXnCj1akQm4rh8dbEzN1p/u1KWg=
|
||||
github.com/charmbracelet/lipgloss v0.9.1/go.mod h1:1mPmG4cxScwUQALAAnacHaigiiHB9Pmr+v1VEawJl6I=
|
||||
github.com/charmbracelet/log v0.3.1 h1:TjuY4OBNbxmHWSwO3tosgqs5I3biyY8sQPny/eCMTYw=
|
||||
github.com/charmbracelet/log v0.3.1/go.mod h1:OR4E1hutLsax3ZKpXbgUqPtTjQfrh1pG3zwHGWuuq8g=
|
||||
github.com/go-chi/chi/v5 v5.0.11 h1:BnpYbFZ3T3S1WMpD79r7R5ThWX40TaFB7L31Y8xqSwA=
|
||||
github.com/go-chi/chi/v5 v5.0.11/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4=
|
||||
github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0 h1:0VNZXggJE2OYdXE87bfSSwGxeiGt9moSR2lOrsHHvr4=
|
||||
github.com/ilyakaznacheev/cleanenv v1.5.0/go.mod h1:a5aDzaJrLCQZsazHol1w8InnDcOX0OColm64SlIi6gk=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg=
|
||||
github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
|
||||
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
|
||||
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
|
||||
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
|
||||
github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
|
||||
github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
|
||||
github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI=
|
||||
golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3 h1:slmdOY3vp8a7KQbHkL+FLbvbkgMqmXojpFUO/jENuqQ=
|
||||
olympos.io/encoding/edn v0.0.0-20201019073823-d3554ca0b0a3/go.mod h1:oVgVk4OWVDi43qWBEyGhXgYxt7+ED4iYNpTngSLX2Iw=
|
83
internal/config/config.go
Normal file
83
internal/config/config.go
Normal file
|
@ -0,0 +1,83 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"math"
|
||||
"os"
|
||||
|
||||
"git.burning.moe/celediel/burning.moe/internal/models"
|
||||
"github.com/charmbracelet/log"
|
||||
"github.com/ilyakaznacheev/cleanenv"
|
||||
)
|
||||
|
||||
// AppConfig contains data to be accessed across the app.
|
||||
type AppConfig struct {
|
||||
ListenPort uint16
|
||||
TemplateCache models.TemplateCache
|
||||
UseCache bool
|
||||
Logger *log.Logger
|
||||
LogLevel log.Level
|
||||
}
|
||||
|
||||
// defaluts contains default settings that are used if no environmental variables are set
|
||||
var defaults = &AppConfig{
|
||||
ListenPort: 9001,
|
||||
UseCache: true,
|
||||
LogLevel: log.InfoLevel,
|
||||
}
|
||||
|
||||
// ConfigDatabase contains data to be loaded from environmental variables
|
||||
type ConfigDatabase struct {
|
||||
Port uint16 `env:"PORT" env-default:"9001" env-description:"server port"`
|
||||
LogLevel string `env:"LOGLEVEL" env-default:"warn" env-description:"Logging level. Default: warn, Possible values: debug info warn error fatal none"`
|
||||
UseCache bool `env:"CACHE" env-default:"true" env-description:"Use template cache"`
|
||||
}
|
||||
|
||||
// Initialises the app wide AppConfig, loads values from environment, and set up the Logger
|
||||
func Initialise() AppConfig {
|
||||
app := *defaults
|
||||
app.Logger = log.New(os.Stderr)
|
||||
|
||||
// load values from config
|
||||
if cfg, err := loadConfig(); err == nil {
|
||||
app.ListenPort = cfg.Port
|
||||
app.UseCache = cfg.UseCache
|
||||
app.LogLevel = logLevelFromString(cfg.LogLevel)
|
||||
} else {
|
||||
app.Logger.Print("Failed loading config from environment", "err", err)
|
||||
}
|
||||
|
||||
app.Logger.SetLevel(app.LogLevel)
|
||||
app.Logger.Debug("Loaded config from environment:", "port", app.ListenPort, "useCache", app.UseCache, "log_level", app.LogLevel)
|
||||
|
||||
return app
|
||||
}
|
||||
|
||||
// loadConfig utilises cleanenv to load config values from the environment
|
||||
func loadConfig() (ConfigDatabase, error) {
|
||||
var cfg ConfigDatabase
|
||||
if err := cleanenv.ReadEnv(&cfg); err != nil {
|
||||
return ConfigDatabase{}, err
|
||||
} else {
|
||||
return cfg, nil
|
||||
}
|
||||
}
|
||||
|
||||
// logLevelFromString turns a string like "warn" into a log.Level like log.WarnLevel
|
||||
func logLevelFromString(level string) log.Level {
|
||||
switch level {
|
||||
case "debug":
|
||||
return log.DebugLevel
|
||||
case "info":
|
||||
return log.InfoLevel
|
||||
case "warn":
|
||||
return log.WarnLevel
|
||||
case "error":
|
||||
return log.ErrorLevel
|
||||
case "fatal":
|
||||
return log.FatalLevel
|
||||
case "none":
|
||||
return math.MaxInt32
|
||||
default:
|
||||
return defaults.LogLevel
|
||||
}
|
||||
}
|
42
internal/handlers/handlers.go
Normal file
42
internal/handlers/handlers.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package handlers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"git.burning.moe/celediel/burning.moe/internal/config"
|
||||
"git.burning.moe/celediel/burning.moe/internal/models"
|
||||
"git.burning.moe/celediel/burning.moe/internal/render"
|
||||
)
|
||||
|
||||
// Handler holds data required for handlers.
|
||||
type Handler struct {
|
||||
Handles string
|
||||
Handler func(w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
|
||||
var app *config.AppConfig
|
||||
|
||||
// The actual handlers
|
||||
var Handlers = []Handler{
|
||||
// /about
|
||||
{
|
||||
Handles: "/about",
|
||||
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||
app.Logger.Info("Got request for about page.")
|
||||
render.RenderTemplate(w, "about.page", &models.TemplateData{})
|
||||
},
|
||||
},
|
||||
// / comes last
|
||||
{
|
||||
Handles: "/",
|
||||
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||
app.Logger.Info("Got request for homepage.")
|
||||
render.RenderTemplate(w, "home.page", &models.TemplateData{})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Initialise the handlers package.
|
||||
func Initialise(a *config.AppConfig) {
|
||||
app = a
|
||||
}
|
18
internal/models/templatecache.go
Normal file
18
internal/models/templatecache.go
Normal file
|
@ -0,0 +1,18 @@
|
|||
package models
|
||||
|
||||
import (
|
||||
"html/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TemplateCache holds the template cache as map of TemplateCacheItem
|
||||
type TemplateCache struct {
|
||||
Cache map[string]TemplateCacheItem
|
||||
}
|
||||
|
||||
// TemplateCacheItem holds a pointer to a generated
|
||||
// template, and the time it was generated at.
|
||||
type TemplateCacheItem struct {
|
||||
Template *template.Template
|
||||
GeneratedAt time.Time
|
||||
}
|
14
internal/models/templatedata.go
Normal file
14
internal/models/templatedata.go
Normal file
|
@ -0,0 +1,14 @@
|
|||
package models
|
||||
|
||||
// TemplateData holds data sent from handlers to templates.
|
||||
type TemplateData struct {
|
||||
StringMap map[string]string
|
||||
IntMap map[string]int
|
||||
FloatMap map[string]float32
|
||||
Data map[string]interface{}
|
||||
CSRFToken string
|
||||
Flash string
|
||||
Warning string
|
||||
Error string
|
||||
}
|
||||
|
111
internal/render/render.go
Normal file
111
internal/render/render.go
Normal file
|
@ -0,0 +1,111 @@
|
|||
package render
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"git.burning.moe/celediel/burning.moe/internal/config"
|
||||
"git.burning.moe/celediel/burning.moe/internal/models"
|
||||
)
|
||||
|
||||
const (
|
||||
templatesDir string = "./templates/"
|
||||
layoutGlob string = "*.layout.tmpl"
|
||||
pageGlob string = "*.page.tmpl"
|
||||
)
|
||||
|
||||
var app *config.AppConfig
|
||||
|
||||
// Initialise the render package.
|
||||
func Initialise(a *config.AppConfig) {
|
||||
var err error
|
||||
app = a
|
||||
app.TemplateCache, err = GenerateNewTemplateCache()
|
||||
if err != nil {
|
||||
app.Logger.Fatal("Error generating template cache, bailing out!")
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateNewTemplateCache generates a new template cache.
|
||||
func GenerateNewTemplateCache() (models.TemplateCache, error) {
|
||||
// start with an empty map
|
||||
cache := models.TemplateCache{}
|
||||
cache.Cache = map[string]models.TemplateCacheItem{}
|
||||
|
||||
// Generate a list of pages based on globs
|
||||
pages, err := filepath.Glob(templatesDir + pageGlob)
|
||||
|
||||
// a nice try catch would be pretty cool right about here
|
||||
if err != nil {
|
||||
return cache, err
|
||||
}
|
||||
|
||||
// Iterate each page, parsing the file and adding it to the cache
|
||||
for _, page := range pages {
|
||||
name := filepath.Base(page)
|
||||
app.Logger.Info("Generating template " + name)
|
||||
|
||||
templateSet, err := template.New(name).ParseFiles(page)
|
||||
if err != nil {
|
||||
return cache, err
|
||||
}
|
||||
|
||||
// Glob and parse any layouts found
|
||||
layouts, err := filepath.Glob(templatesDir + layoutGlob)
|
||||
if err != nil {
|
||||
return cache, err
|
||||
}
|
||||
|
||||
if len(layouts) > 0 {
|
||||
templateSet, err = templateSet.ParseGlob(templatesDir + layoutGlob)
|
||||
if err != nil {
|
||||
return cache, err
|
||||
}
|
||||
}
|
||||
cache.Cache[name] = models.TemplateCacheItem{
|
||||
Template: templateSet,
|
||||
GeneratedAt: time.Now(),
|
||||
}
|
||||
}
|
||||
|
||||
// All was good, so return the cache, and no error
|
||||
return cache, nil
|
||||
}
|
||||
|
||||
// RenderTemplate renders requested template (t), pulling from cache.
|
||||
func RenderTemplate(w http.ResponseWriter, t string, data *models.TemplateData) {
|
||||
filename := t + ".tmpl"
|
||||
var cache models.TemplateCache
|
||||
if app.UseCache {
|
||||
cache = app.TemplateCache
|
||||
} else {
|
||||
var err error
|
||||
cache, err = GenerateNewTemplateCache()
|
||||
if err != nil {
|
||||
app.Logger.Fatal("Error generating template cache, bailing out!")
|
||||
}
|
||||
}
|
||||
|
||||
// Get templates from cache
|
||||
template, ok := cache.Cache[filename]
|
||||
if !ok {
|
||||
app.Logger.Fatal(fmt.Sprintf("Couldn't get %s from template cache, bailing out!", filename))
|
||||
}
|
||||
|
||||
// Execute templates in a new buffer
|
||||
buf := new(bytes.Buffer)
|
||||
err := template.Template.Execute(buf, data)
|
||||
|
||||
if err != nil {
|
||||
app.Logger.Fatal("Error executing template %s! Goodbye!", "err", err)
|
||||
}
|
||||
|
||||
_, err = buf.WriteTo(w)
|
||||
if err != nil {
|
||||
app.Logger.Error("Error writing template %s!\n", "err", err)
|
||||
}
|
||||
}
|
38
magefile.go
Normal file
38
magefile.go
Normal file
|
@ -0,0 +1,38 @@
|
|||
//go:build mage
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/magefile/mage/sh"
|
||||
)
|
||||
|
||||
var (
|
||||
binaryName string = "burningmoe"
|
||||
buildDir string = "bin"
|
||||
cmd string = fmt.Sprintf(".%[1]ccmd%[1]cweb", os.PathSeparator)
|
||||
output string = fmt.Sprintf(".%[1]c%[2]s%[1]c%[3]s", os.PathSeparator, buildDir, binaryName)
|
||||
)
|
||||
|
||||
func Build() error {
|
||||
fmt.Println("Building...")
|
||||
return sh.Run("go", "build", "-o", output, cmd)
|
||||
}
|
||||
|
||||
func Run() error {
|
||||
fmt.Println("Running...")
|
||||
return sh.Run("go", "run", cmd)
|
||||
}
|
||||
|
||||
func RunBinary() error {
|
||||
Build()
|
||||
fmt.Println("Running binary...")
|
||||
return sh.Run(output)
|
||||
}
|
||||
|
||||
func Clean() error {
|
||||
fmt.Println("Cleaning...")
|
||||
return os.Remove(output)
|
||||
}
|
71
static/css/style.css
Normal file
71
static/css/style.css
Normal file
|
@ -0,0 +1,71 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Gloria+Hallelujah&display=swap');
|
||||
|
||||
body {
|
||||
background: #FFF;
|
||||
color: #121212;
|
||||
text-align: center;
|
||||
font-family: 'Gloria Hallelujah', cursive;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #333;
|
||||
text-decoration: none;
|
||||
-o-transition: .5s;
|
||||
-ms-transition: .5s;
|
||||
-moz-transition: .5s;
|
||||
-webkit-transition: .5s;
|
||||
/* ...and now for the proper property */
|
||||
transition: .5s;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #999;
|
||||
}
|
||||
|
||||
a.back {
|
||||
color: #111;
|
||||
}
|
||||
|
||||
#stuff {
|
||||
margin: 55px 150px 25px 150px;
|
||||
}
|
||||
|
||||
#words {
|
||||
font-size: 1.0em;
|
||||
margin-top: -10px;
|
||||
}
|
||||
|
||||
#bigwords {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
#leftfooter {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
font-size: 0.75em;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
#rightfooter {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
font-size: 0.75em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#header {
|
||||
margin: 0px;
|
||||
margin-top: -20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 1.7em;
|
||||
font-family: "ヒラギノ角ゴ Pro W3", "Hiragino Kaku Gothic Pro", Osaka, "メイリオ", Meiryo, "MS Pゴシック", "MS PGothic", sans-serif;
|
||||
}
|
||||
|
||||
h2 {
|
||||
padding-top: 0px;
|
||||
font-size: 1.4em;
|
||||
}
|
BIN
static/img/burningmoe.jpg
Normal file
BIN
static/img/burningmoe.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 243 KiB |
BIN
static/img/moemoe.png
Normal file
BIN
static/img/moemoe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
53
templates/about.page.tmpl
Normal file
53
templates/about.page.tmpl
Normal file
|
@ -0,0 +1,53 @@
|
|||
{{- template "base" . -}}
|
||||
|
||||
{{- define "content" }}
|
||||
<span id="words">
|
||||
<h4>celediel</h4>
|
||||
<span id="bigwords">
|
||||
she/her, 1989, queer anarchist, self-taught aspiring developer
|
||||
</span>
|
||||
<h4>links</h4>
|
||||
|
||||
<!-- personal links -->
|
||||
<a href="https://matrix.to/#/@celediel:burning.moe">
|
||||
<span class="iconify" data-icon="tabler:brand-matrix"></span>
|
||||
matrix
|
||||
</a><br />
|
||||
|
||||
<a href="https://slrpnk.net/u/Celediel">
|
||||
<span class="iconify" data-icon="simple-icons:lemmy"></span>
|
||||
lemmy
|
||||
</a><br />
|
||||
|
||||
<a href="https://git.burning.moe/celediel">
|
||||
<span class="iconify" data-icon="mdi:git"></span>
|
||||
self-hosted git
|
||||
</a><br />
|
||||
|
||||
<a href="https://github.com/celediel">
|
||||
<span class="iconify" data-icon="bi:github"></span>
|
||||
github
|
||||
</a><br />
|
||||
|
||||
<!-- web app links -->
|
||||
<h4>hosted apps</h4>
|
||||
<a href="https://git.burning.moe/">
|
||||
<span class="iconify" data-icon="mdi:git"></span>
|
||||
self-hosted git
|
||||
</a><br />
|
||||
<a href="https://bin.burning.moe/">
|
||||
<span class="iconify" data-icon="fluent:bin-recycle-20-filled"></span>
|
||||
wastebin
|
||||
</a><br />
|
||||
<a href="https://gist.burning.moe/">
|
||||
<span class="iconify" data-icon="carbon:paste"></span>
|
||||
gist
|
||||
</a>
|
||||
<br /><br />
|
||||
<a href="/">back</a>
|
||||
</span>
|
||||
{{ end -}}
|
||||
|
||||
{{- define "js" }}
|
||||
<script src="https://code.iconify.design/3/3.1.0/iconify.min.js"></script>
|
||||
{{ end -}}
|
37
templates/base.layout.tmpl
Normal file
37
templates/base.layout.tmpl
Normal file
|
@ -0,0 +1,37 @@
|
|||
{{- define "base" -}}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport"
|
||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||
<title>burning.moe</title>
|
||||
<link rel="stylesheet" href="static/css/style.css">
|
||||
{{- block "css" . }}
|
||||
{{- end }}
|
||||
</head>
|
||||
<body>
|
||||
<div id="stuff">
|
||||
{{- block "content" . }}
|
||||
{{ end -}}
|
||||
</div>
|
||||
|
||||
{{- block "js" . }}
|
||||
{{ end -}}
|
||||
<div id="leftfooter">
|
||||
note: please do not set fire to cute girls
|
||||
</div>
|
||||
<div id="rightfooter">
|
||||
powered by
|
||||
<a href="https://www.debian.org/">debian</a>
|
||||
and
|
||||
<a href="https://go.dev/">go</a>,
|
||||
proxied by
|
||||
<a href="https://caddyserver.com/">caddy</a>
|
||||
-
|
||||
<a href="https://git.burning.moe/celediel/burning.moe">source</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{ end -}}
|
16
templates/home.page.tmpl
Normal file
16
templates/home.page.tmpl
Normal file
|
@ -0,0 +1,16 @@
|
|||
{{- template "base" . -}}
|
||||
|
||||
{{- define "content" }}
|
||||
<img src="static/img/moemoe.png">
|
||||
<div id="header">
|
||||
<!-- <h1>燃え 萌え</h1> -->
|
||||
<h2>burning.moe</h2>
|
||||
</div>
|
||||
<a href="http://www.pixiv.net/member_illust.php?mode=medium&illust_id=22647957">
|
||||
<img src="static/img/burningmoe.jpg" style="max-width:400px;" />
|
||||
</a>
|
||||
<br />
|
||||
<span id="words">
|
||||
<a href="about">about</a>
|
||||
</span>
|
||||
{{ end -}}
|
Loading…
Reference in a new issue