mirror of
https://gitlab.com/nullmax17/personal-website.git
synced 2025-03-14 13:11:12 +03:00
first commit
This commit is contained in:
commit
ab174b8de5
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
.env
|
||||
*.db
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 dixxe
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
23
README.md
Normal file
23
README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Personal web
|
||||
This website is a showcase of my skills and interests.
|
||||
|
||||
## Can I use this website?
|
||||
Yes you can! But you must follow MIT license if you doing so.
|
||||
|
||||
To start website you need to:
|
||||
- Create .env file and populate it with LOGIN, PASSWORD for admin panel.
|
||||
- Create blogs.db database and populate it with `initdb()` method.
|
||||
- run compiled binary with `./personal-website ""` to start HTTP website or `./personal-website domain.com subdomain.domain.com` to start HTTPS website
|
||||
|
||||
## How to contribute?
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a new branch (`git checkout -b feature/AmazingFeature`)
|
||||
3. Make your changes
|
||||
4. Commit your changes (`git commit -m 'Add some AmazingFeature'`)
|
||||
5. Push to the branch (`git push origin feature/AmazingFeature`)
|
||||
6. Open a Pull Request
|
||||
|
||||
## ToDo
|
||||
- [x] Comments and code refactoring
|
||||
- [ ] Comments and likes for blog
|
27
flake.lock
generated
Normal file
27
flake.lock
generated
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1736012469,
|
||||
"narHash": "sha256-/qlNWm/IEVVH7GfgAIyP6EsVZI6zjAx1cV5zNyrs+rI=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8f3e1f807051e32d8c95cd12b9b421623850a34d",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
29
flake.nix
Normal file
29
flake.nix
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
description = "A portable go dev flake!";
|
||||
|
||||
inputs = {
|
||||
nixpkgs.url = "github:nixos/nixpkgs?ref=nixos-unstable";
|
||||
};
|
||||
|
||||
outputs = { nixpkgs, ... }@inputs:
|
||||
let
|
||||
system = "x86_64-linux";
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
devShells.${system} = {
|
||||
default = pkgs.mkShell {
|
||||
nativeBuildInputs = with pkgs; [
|
||||
delve
|
||||
go
|
||||
gopls
|
||||
templ
|
||||
];
|
||||
|
||||
hardeningDisable = [ "fortify" ];
|
||||
|
||||
shellHook = "echo Welcome to go-backend environment";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
32
go.mod
Normal file
32
go.mod
Normal file
@ -0,0 +1,32 @@
|
||||
module github.com/dixxe/personal-website
|
||||
|
||||
go 1.23.2
|
||||
|
||||
require github.com/a-h/templ v0.3.819
|
||||
|
||||
require (
|
||||
github.com/go-chi/chi/v5 v5.2.0
|
||||
github.com/joho/godotenv v1.5.1
|
||||
golang.org/x/crypto v0.32.0
|
||||
modernc.org/sqlite v1.34.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect
|
||||
github.com/kaptinlin/jsonrepair v0.1.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/ncruces/go-strftime v0.1.9 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
|
||||
golang.org/x/net v0.33.0 // indirect
|
||||
golang.org/x/sys v0.29.0 // indirect
|
||||
golang.org/x/text v0.21.0 // indirect
|
||||
modernc.org/gc/v3 v3.0.0-20241223112719-96e2e1e4408d // indirect
|
||||
modernc.org/libc v1.61.6 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.8.0 // indirect
|
||||
modernc.org/strutil v1.2.1 // indirect
|
||||
modernc.org/token v1.1.0 // indirect
|
||||
)
|
69
go.sum
Normal file
69
go.sum
Normal file
@ -0,0 +1,69 @@
|
||||
github.com/a-h/templ v0.3.819 h1:KDJ5jTFN15FyJnmSmo2gNirIqt7hfvBD2VXVDTySckM=
|
||||
github.com/a-h/templ v0.3.819/go.mod h1:iDJKJktpttVKdWoTkRNNLcllRI+BlpopJc+8au3gOUo=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/go-chi/chi/v5 v5.2.0 h1:Aj1EtB0qR2Rdo2dG4O94RIU35w2lvQSj6BRA4+qwFL0=
|
||||
github.com/go-chi/chi/v5 v5.2.0/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo=
|
||||
github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kaptinlin/jsonrepair v0.1.0 h1:71Pwmyqan+fZPStHDSBTJngPhxtTkjEeWciZF3405cs=
|
||||
github.com/kaptinlin/jsonrepair v0.1.0/go.mod h1:hW2xIfVQwmskoVSv9g8g3ITOkEiOKKRj934dDCVW6aM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
|
||||
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc=
|
||||
golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc=
|
||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
|
||||
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
|
||||
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
|
||||
golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I=
|
||||
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
|
||||
golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ=
|
||||
golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo=
|
||||
golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=
|
||||
golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8=
|
||||
golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw=
|
||||
modernc.org/cc/v4 v4.24.2 h1:uektamHbSXU7egelXcyVpMaaAsrRH4/+uMKUQAQUdOw=
|
||||
modernc.org/cc/v4 v4.24.2/go.mod h1:T1lKJZhXIi2VSqGBiB4LIbKs9NsKTbUXj4IDrmGqtTI=
|
||||
modernc.org/ccgo/v4 v4.23.5 h1:6uAwu8u3pnla3l/+UVUrDDO1HIGxHTYmFH6w+X9nsyw=
|
||||
modernc.org/ccgo/v4 v4.23.5/go.mod h1:FogrWfBdzqLWm1ku6cfr4IzEFouq2fSAPf6aSAHdAJQ=
|
||||
modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE=
|
||||
modernc.org/fileutil v1.3.0/go.mod h1:XatxS8fZi3pS8/hKG2GH/ArUogfxjpEKs3Ku3aK4JyQ=
|
||||
modernc.org/gc/v2 v2.6.0 h1:Tiw3pezQj7PfV8k4Dzyu/vhRHR2e92kOXtTFU8pbCl4=
|
||||
modernc.org/gc/v2 v2.6.0/go.mod h1:wzN5dK1AzVGoH6XOzc3YZ+ey/jPgYHLuVckd62P0GYU=
|
||||
modernc.org/gc/v3 v3.0.0-20241223112719-96e2e1e4408d h1:d0JExN5U5FjUVHCP6L9DIlLJBZveR6KUM4AvfDUL3+k=
|
||||
modernc.org/gc/v3 v3.0.0-20241223112719-96e2e1e4408d/go.mod h1:qBSLm/exCqouT2hrfyTKikWKG9IPq8EoX5fS00l3jqk=
|
||||
modernc.org/libc v1.61.6 h1:L2jW0wxHPCyHK0YSHaGaVlY0WxjpG/TTVdg6gRJOPqw=
|
||||
modernc.org/libc v1.61.6/go.mod h1:G+DzuaCcReUYYg4nNSfigIfTDCENdj9EByglvaRx53A=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E=
|
||||
modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU=
|
||||
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
|
||||
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/sortutil v1.2.0 h1:jQiD3PfS2REGJNzNCMMaLSp/wdMNieTbKX920Cqdgqc=
|
||||
modernc.org/sortutil v1.2.0/go.mod h1:TKU2s7kJMf1AE84OoiGppNHJwvB753OYfNl2WRb++Ss=
|
||||
modernc.org/sqlite v1.34.4 h1:sjdARozcL5KJBvYQvLlZEmctRgW9xqIZc2ncN7PU0P8=
|
||||
modernc.org/sqlite v1.34.4/go.mod h1:3QQFCG2SEMtc2nv+Wq4cQCH7Hjcg+p/RMlS1XK+zwbk=
|
||||
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
|
||||
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
|
||||
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
|
||||
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
71
iternal/controllers/AdminController.go
Normal file
71
iternal/controllers/AdminController.go
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
This controller handles admin stuff and allows to redact databases.
|
||||
|
||||
It has some noodles in it but this is how it works.
|
||||
1. Users enters on "/admin" and this controller handles GetAdminLogin()
|
||||
2. Than frontend passes a form with login and password to PostAdminLogin()
|
||||
3. In PostAdminLogin() backend checks that login and password are equal to
|
||||
ones that defined in .env file (without it code will panic! I will rewrite this)
|
||||
4. If everything correct controller goes to GetAdminPanel() and shows admin-panel
|
||||
template
|
||||
|
||||
Currently page is vulnerable to bruteforce.
|
||||
I will try to implement JWT in future. -d1xxe
|
||||
Best practice is to move login to middleware- -TODO
|
||||
*/
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/dixxe/personal-website/iternal/pkg/repositories"
|
||||
"github.com/dixxe/personal-website/web/templates"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
// This controller has been written to control databases and blog. SECUIRITY-WARNING!
|
||||
func GetAdminPanel(w http.ResponseWriter, r *http.Request) {
|
||||
posts, err := repositories.Blog.GetAllValues()
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
component := templates.AdminPanelPage([]repositories.Post{})
|
||||
component.Render(context.Background(), w)
|
||||
return
|
||||
}
|
||||
|
||||
component := templates.AdminPanelPage(posts)
|
||||
component.Render(context.Background(), w)
|
||||
}
|
||||
|
||||
// This controller has been written to add protection for admin-panel.
|
||||
func GetAdminLogin(w http.ResponseWriter, r *http.Request) {
|
||||
// Respond with page that contains form for login and password.
|
||||
component := templates.LoginPage()
|
||||
component.Render(context.Background(), w)
|
||||
}
|
||||
|
||||
// This controller handles passed form and checks for its validity.
|
||||
// If everything right it passes to GetAdminPanel.
|
||||
func PostAdminLogin(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
login := r.FormValue("login")
|
||||
password := r.FormValue("password")
|
||||
|
||||
if err := godotenv.Load(); err != nil {
|
||||
// I better disable admin panel at all if .env not located.
|
||||
component := templates.ErrorPage(404, "Admin-panel not configured.")
|
||||
component.Render(context.Background(), w)
|
||||
return
|
||||
}
|
||||
|
||||
admin_login, _ := os.LookupEnv("LOGIN")
|
||||
admin_password, _ := os.LookupEnv("PASSWORD")
|
||||
if login == admin_login && password == admin_password {
|
||||
GetAdminPanel(w, r)
|
||||
}
|
||||
}
|
91
iternal/controllers/BlogController.go
Normal file
91
iternal/controllers/BlogController.go
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
Controller that handles everything d1xxe blog related features.
|
||||
Under the hood it operates with repositories.Blog to get all information from
|
||||
local database.
|
||||
|
||||
In a nutshell it's pretty simple.
|
||||
*/
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/dixxe/personal-website/iternal/pkg/repositories"
|
||||
"github.com/dixxe/personal-website/web/templates"
|
||||
"github.com/go-chi/chi/v5"
|
||||
)
|
||||
|
||||
// This controller passes all posts in database in template and responds with page with all size-reduced posts.
|
||||
func GetShowBlog(w http.ResponseWriter, r *http.Request) {
|
||||
posts, err := repositories.Blog.GetAllValues()
|
||||
if err != nil {
|
||||
component := templates.ErrorPage(500, "Ошибка при обработке базы данных.")
|
||||
// For some reason I can't set status code for request x-x
|
||||
log.Println(err)
|
||||
component.Render(context.Background(), w)
|
||||
return
|
||||
}
|
||||
|
||||
component := templates.ShowBlogPage(posts)
|
||||
component.Render(context.Background(), w)
|
||||
}
|
||||
|
||||
// This controller looks for specific post in database and handles all possible errors. Responds with page with post.
|
||||
func GetPost(w http.ResponseWriter, r *http.Request) {
|
||||
id, err := strconv.Atoi(chi.URLParam(r, "id"))
|
||||
|
||||
if err != nil {
|
||||
component := templates.ErrorPage(500, "Не удалось преобразовать id в целое число.")
|
||||
log.Println(err)
|
||||
component.Render(context.Background(), w)
|
||||
return
|
||||
}
|
||||
|
||||
post, err := repositories.Blog.GetValueByID(id)
|
||||
|
||||
if err != nil {
|
||||
component := templates.ErrorPage(404, "Не удалось найти нужный пост.")
|
||||
log.Println(err)
|
||||
component.Render(context.Background(), w)
|
||||
return
|
||||
|
||||
}
|
||||
component := templates.ShowPost(post)
|
||||
component.Render(context.Background(), w)
|
||||
|
||||
}
|
||||
|
||||
// Controller that handles post creation. Responds with 200 if everything OK
|
||||
func PostCreatePost(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm() // Populating form.
|
||||
header := r.FormValue("header") // To get value you need to specify name="header" in the form.
|
||||
content := r.FormValue("content")
|
||||
|
||||
// Creating a new post with 0 Id, don't worry database handles id assignment
|
||||
// itself. And in the InsertValue() method I don't use Post.Id value
|
||||
newPost := repositories.Post{Id: 0, Header: header, Content: content}
|
||||
|
||||
// Process database is async way. WARNING errors are NOT HANDLED
|
||||
go repositories.Blog.InsertValue(newPost)
|
||||
|
||||
fmt.Println("Created post")
|
||||
}
|
||||
|
||||
// Controller that handles post deletion. Responds with 200 if everything is OK
|
||||
func PostDeletePost(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
id, err := strconv.Atoi(r.FormValue("id"))
|
||||
|
||||
if err != nil {
|
||||
component := templates.ErrorPage(500, "Ошибка при переводе id (int) в string.")
|
||||
r.Response.StatusCode = 500
|
||||
log.Println(err)
|
||||
component.Render(context.Background(), w)
|
||||
}
|
||||
// Process database is async way. WARNING errors are NOT HANDLED
|
||||
go repositories.Blog.DeleteValueByID(id)
|
||||
}
|
74
iternal/controllers/CCTweakedController.go
Normal file
74
iternal/controllers/CCTweakedController.go
Normal file
@ -0,0 +1,74 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
|
||||
"github.com/kaptinlin/jsonrepair"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Content string `json:"content"`
|
||||
Msg_type int `json:"msg_type"`
|
||||
}
|
||||
|
||||
var message_queue = []Message{}
|
||||
|
||||
func preprocess_message(r *http.Request) []byte {
|
||||
message_bytes, _ := io.ReadAll(r.Body)
|
||||
message_body := string(message_bytes)
|
||||
|
||||
repaired, err := jsonrepair.JSONRepair(message_body)
|
||||
if err != nil {
|
||||
log.Printf("Failed to fix JSON: %v", err)
|
||||
}
|
||||
repaired_bytes := []byte(repaired)
|
||||
|
||||
return repaired_bytes
|
||||
}
|
||||
|
||||
func decodeMessage(r *http.Request) (Message, error) {
|
||||
var messageRC Message
|
||||
|
||||
processed_message := preprocess_message(r)
|
||||
|
||||
err := json.Unmarshal(processed_message, &messageRC)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return Message{}, err
|
||||
}
|
||||
return messageRC, nil
|
||||
}
|
||||
|
||||
func clearQueue() {
|
||||
if len(message_queue) <= 1 {
|
||||
return
|
||||
}
|
||||
message_queue = message_queue[1:]
|
||||
}
|
||||
|
||||
func PostSendMessage(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
decoded_message, err := decodeMessage(r)
|
||||
if err != nil {
|
||||
w.WriteHeader(400)
|
||||
fmt.Fprintf(w, "Failed to decode message %v", err)
|
||||
log.Printf("Failed to decode message %v", err)
|
||||
return
|
||||
}
|
||||
message_queue = append(message_queue, decoded_message)
|
||||
|
||||
clearQueue()
|
||||
|
||||
}
|
||||
|
||||
func GetMessage(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("content-type", "application/json")
|
||||
if len(message_queue) == 0 {
|
||||
message_queue = append(message_queue, Message{"no message accepted yet", 404})
|
||||
}
|
||||
fmt.Fprintln(w, message_queue[0])
|
||||
}
|
20
iternal/controllers/IndexController.go
Normal file
20
iternal/controllers/IndexController.go
Normal file
@ -0,0 +1,20 @@
|
||||
/*
|
||||
Controller that only shows index template! Simple as it is!
|
||||
*/
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/dixxe/personal-website/web/templates"
|
||||
)
|
||||
|
||||
// Controller that shows "/" root page.
|
||||
func GetIndexHandler(w http.ResponseWriter, r *http.Request) {
|
||||
// Templates are components and this is basic way to render them.
|
||||
// I use this way across all code
|
||||
component := templates.IndexPage()
|
||||
component.Render(context.Background(), w)
|
||||
}
|
26
iternal/pkg/RepositoryInterface.go
Normal file
26
iternal/pkg/RepositoryInterface.go
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
Special interface that I made to make system more reusable.
|
||||
So if you need in future another db it should satisfy this interface.
|
||||
Generic T represents field of database.
|
||||
In this approach DB must be open everytime.
|
||||
|
||||
Why interface? For example you create a function that executes something on database
|
||||
and you need to execute this command automaticly for any DB that contains service.Post passed.
|
||||
So you will define it like this
|
||||
func exec_fix_for_db(repo service.Repository[Post]) {
|
||||
repo.ExecSpecific("Very important fix!!")
|
||||
}
|
||||
*/
|
||||
|
||||
package pkg
|
||||
|
||||
import "database/sql"
|
||||
|
||||
type Repository[T any] interface {
|
||||
GetAllValues() ([]T, error)
|
||||
GetValueByID(id int) (T, error)
|
||||
InsertValue(T) (id int, err error)
|
||||
DeleteValueByID(id int) error
|
||||
ExecSpecific(SQL_command string) (sql.Result, error)
|
||||
QuerySpecific(SQL_command string) (*sql.Rows, error)
|
||||
}
|
116
iternal/pkg/repositories/BlogRepository.go
Normal file
116
iternal/pkg/repositories/BlogRepository.go
Normal file
@ -0,0 +1,116 @@
|
||||
/*
|
||||
Managing blogRepo database with a little bit awful execution.
|
||||
This can be considered as any-repository database example.
|
||||
In this realisation database is *always* stays open after xxxRepository intitialization.
|
||||
Because if something close it the struct will point to nothing and obviously this is bad.
|
||||
*/
|
||||
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
|
||||
_ "modernc.org/sqlite"
|
||||
)
|
||||
|
||||
var database_name = "blogs.db" // You can change it if you want.
|
||||
|
||||
// Defining it to use it later via repository.Blog
|
||||
// Why here? Because it's best place for anything blog related!
|
||||
var Blog blogRepository = blogRepository{Database: OpenDb(database_name)}
|
||||
|
||||
// Post structure for database field.
|
||||
type Post struct {
|
||||
Id int
|
||||
Header string
|
||||
Content string
|
||||
}
|
||||
|
||||
// This struct implemets Repository[Post]
|
||||
type blogRepository struct {
|
||||
Database *sql.DB
|
||||
}
|
||||
|
||||
func (blogRepo blogRepository) GetAllValues() ([]Post, error) {
|
||||
db := blogRepo.Database
|
||||
|
||||
rows, err := db.Query("SELECT * from blogs")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
posts := []Post{}
|
||||
|
||||
for rows.Next() {
|
||||
p := Post{}
|
||||
err := rows.Scan(&p.Id, &p.Header, &p.Content)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
continue
|
||||
}
|
||||
posts = append(posts, p)
|
||||
}
|
||||
fmt.Println("Readed all posts")
|
||||
|
||||
return posts, err
|
||||
}
|
||||
|
||||
func (blogRepo blogRepository) GetValueByID(id int) (Post, error) {
|
||||
db := blogRepo.Database
|
||||
|
||||
row := db.QueryRow("SELECT * from blogs where id = ?", id)
|
||||
p := Post{}
|
||||
err := row.Scan(&p.Id, &p.Header, &p.Content)
|
||||
if err != nil {
|
||||
return Post{}, err
|
||||
}
|
||||
fmt.Println("Get one post")
|
||||
|
||||
return p, err
|
||||
}
|
||||
|
||||
func (blogRepo blogRepository) DeleteValueByID(id int) error {
|
||||
db := blogRepo.Database
|
||||
//defer db.Close()
|
||||
|
||||
_, err := db.Exec("DELETE from blogs where id = ?", id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Println("Delete one post")
|
||||
return err
|
||||
}
|
||||
|
||||
// Returning last inserted id
|
||||
func (blogRepo blogRepository) InsertValue(postToInsert Post) (int, error) {
|
||||
db := blogRepo.Database
|
||||
|
||||
result, err := db.Exec("INSERT into blogs (header, content) values (?,?)",
|
||||
postToInsert.Header, postToInsert.Content)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
id, _ := result.LastInsertId()
|
||||
|
||||
return int(id), err
|
||||
}
|
||||
|
||||
func (blogRepo blogRepository) ExecSpecific(SQL_command string) (sql.Result, error) {
|
||||
result, err := blogRepo.Database.Exec(SQL_command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (blogRepo blogRepository) QuerySpecific(SQL_command string) (*sql.Rows, error) {
|
||||
result, err := blogRepo.Database.Query(SQL_command)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, err
|
||||
}
|
40
iternal/pkg/repositories/SQL-basic-functions.go
Normal file
40
iternal/pkg/repositories/SQL-basic-functions.go
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
Some SQL tools to reduce boilerplate.
|
||||
Probably will be rewritten in future.
|
||||
*/
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/dixxe/personal-website/iternal/pkg"
|
||||
)
|
||||
|
||||
func OpenDb(database_name string) *sql.DB {
|
||||
if _, err := os.Stat("./" + database_name); err != nil {
|
||||
panic(database_name + " not found!")
|
||||
}
|
||||
db, err := sql.Open("sqlite", database_name)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Database was openned")
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
// I don't know a way how to automate this process.
|
||||
func InitDb(repo pkg.Repository[Post]) {
|
||||
//defer db.Close()
|
||||
|
||||
repo.ExecSpecific(`
|
||||
CREATE TABLE blogs(
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
header TEXT,
|
||||
content TEXT
|
||||
);
|
||||
`)
|
||||
fmt.Println("Database was initiated.")
|
||||
}
|
75
main.go
Normal file
75
main.go
Normal file
@ -0,0 +1,75 @@
|
||||
package main
|
||||
|
||||
/*
|
||||
Main file with routes and nothing else.
|
||||
*/
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/dixxe/personal-website/iternal/controllers"
|
||||
"github.com/go-chi/chi/v5"
|
||||
"github.com/go-chi/chi/v5/middleware"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
)
|
||||
|
||||
var domains = os.Args[1:]
|
||||
|
||||
func main() {
|
||||
|
||||
log.Println(`
|
||||
____ _ ___ ____ _ _____ ____ ____ _____ _____
|
||||
/ _ \/ \\ \//\ \/// __/ / __\/ _ \/ __// __/
|
||||
| | \|| | \ / \ / | \ _____ | \/|| / \|| | _| \
|
||||
| |_/|| | / \ / \ | /_\____\| __/| |-||| |_//| /_
|
||||
\____/\_//__/\\/__/\\\____\ \_/ \_/ \|\____\\____\
|
||||
`)
|
||||
|
||||
r := chi.NewRouter()
|
||||
r.Use(middleware.Logger)
|
||||
r.Use(middleware.StripSlashes)
|
||||
|
||||
r.Get("/", controllers.GetIndexHandler)
|
||||
|
||||
r.Get("/blog", controllers.GetShowBlog)
|
||||
r.Get("/post/{id}", controllers.GetPost)
|
||||
r.Post("/post", controllers.PostCreatePost)
|
||||
r.Post("/post/delete", controllers.PostDeletePost)
|
||||
|
||||
r.Post("/admin/login", controllers.PostAdminLogin)
|
||||
r.Get("/admin", controllers.GetAdminLogin)
|
||||
|
||||
r.Post("/cctweaked", controllers.PostSendMessage)
|
||||
r.Get("/cctweaked", controllers.GetMessage)
|
||||
|
||||
fs := http.FileServer(http.Dir("web/static"))
|
||||
r.Handle("/static/*", http.StripPrefix("/static/", fs))
|
||||
|
||||
log.Println(domains)
|
||||
|
||||
if domains[0] == "" {
|
||||
|
||||
log.Println("HTTP website started")
|
||||
log.Fatal(http.ListenAndServe("localhost:8080", r))
|
||||
|
||||
} else {
|
||||
|
||||
log.Println("HTTPS website started with HTTP redirect.")
|
||||
go redirectHTTPServer()
|
||||
for _, domain := range domains {
|
||||
log.Fatal(http.Serve(autocert.NewListener(domain), r))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func redirectHTTPServer() {
|
||||
if err := http.ListenAndServe(":8080", http.HandlerFunc(redirectTLS)); err != nil {
|
||||
log.Fatalf("ListenAndServe error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func redirectTLS(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "https://"+domains[0]+":443"+r.RequestURI, http.StatusMovedPermanently)
|
||||
}
|
78
test/DecodeMessage_test.go
Normal file
78
test/DecodeMessage_test.go
Normal file
@ -0,0 +1,78 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/dixxe/personal-website/iternal/controllers"
|
||||
)
|
||||
|
||||
func TestPostMessage(t *testing.T) {
|
||||
|
||||
test_value := `{"content":"banan","msg_type":10}`
|
||||
|
||||
body := strings.NewReader(test_value)
|
||||
req, err := http.NewRequest("POST", "/cctweaked", body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
http.HandlerFunc(controllers.PostSendMessage).ServeHTTP(rr, req)
|
||||
|
||||
req, err = http.NewRequest("GET", "/cctweaked", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
http.HandlerFunc(controllers.GetMessage).ServeHTTP(rr, req)
|
||||
|
||||
expected := `{banan 10}`
|
||||
|
||||
if strings.Trim(rr.Body.String(), "\n ") != expected {
|
||||
t.Errorf("handler returned unexpected body: got %v want %v",
|
||||
rr.Body.String(), expected)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func FuzzPostMessage(f *testing.F) {
|
||||
f.Add(0, "banan")
|
||||
f.Fuzz(func(t *testing.T, msg_type int, content string) {
|
||||
|
||||
if !utf8.Valid([]byte(content)) {
|
||||
return
|
||||
}
|
||||
|
||||
body := strings.NewReader(fmt.Sprintf(`{"content":"%v","msg_type":%v}`,
|
||||
content, msg_type))
|
||||
|
||||
req, err := http.NewRequest("POST", "/cctweaked", body)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
http.HandlerFunc(controllers.PostSendMessage).ServeHTTP(rr, req)
|
||||
|
||||
req, err = http.NewRequest("GET", "/cctweaked", nil)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
http.HandlerFunc(controllers.GetMessage).ServeHTTP(rr, req)
|
||||
|
||||
expected := fmt.Sprintf(`{%v %v}`, content, msg_type)
|
||||
|
||||
if rr.Result().StatusCode == 400 {
|
||||
return
|
||||
}
|
||||
|
||||
if strings.Trim(rr.Body.String(), "\n ") != expected {
|
||||
t.Errorf("handler returned unexpected body: got %v want %v",
|
||||
rr.Body.String(), expected)
|
||||
}
|
||||
})
|
||||
}
|
18
test/readme_future_me.md
Normal file
18
test/readme_future_me.md
Normal file
@ -0,0 +1,18 @@
|
||||
# Dear future me.
|
||||
You can be proud of yourself that you have a very own backend and website. But please I BEG YOU
|
||||
|
||||
## WRITE THE DAMN TESTS
|
||||
|
||||
Not only you work with multi-directory project structure, but you test everything by **running website and look at endpoints!!**
|
||||
|
||||
### THIS CAN NOT CONTINUE
|
||||
|
||||
Please, dear future me. Have mercy to write better and modular code that *can be* tested by **UNIT-test** and **FUZZING-test**
|
||||
|
||||
At least do this for
|
||||
|
||||
- SQL-related stuff
|
||||
- Any IO operations (in future)
|
||||
- Any calculations/conversations/user-services
|
||||
|
||||
### THANK YOU!!
|
3
test/testdata/fuzz/FuzzPostMessage/46b16ae58246e7dc
vendored
Normal file
3
test/testdata/fuzz/FuzzPostMessage/46b16ae58246e7dc
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
go test fuzz v1
|
||||
int(34)
|
||||
string("\"+")
|
BIN
web/static/fonts/Disket-Mono-Bold.ttf
Normal file
BIN
web/static/fonts/Disket-Mono-Bold.ttf
Normal file
Binary file not shown.
BIN
web/static/fonts/Disket-Mono-Regular.ttf
Normal file
BIN
web/static/fonts/Disket-Mono-Regular.ttf
Normal file
Binary file not shown.
BIN
web/static/fonts/codec-pro.regular.ttf
Normal file
BIN
web/static/fonts/codec-pro.regular.ttf
Normal file
Binary file not shown.
103
web/static/styling/basic-styling.templ
Normal file
103
web/static/styling/basic-styling.templ
Normal file
@ -0,0 +1,103 @@
|
||||
package styling
|
||||
|
||||
/*
|
||||
In this file I write main CSS for all webpages.
|
||||
Also I store there some variables that I use a lot.
|
||||
Currently all elements are not sorted.
|
||||
Be aware that class names in final html page will be random.
|
||||
*/
|
||||
|
||||
|
||||
var mainColor = "#ffb37f"
|
||||
var bgColor = "#272727"
|
||||
var bgVariation = "#1f1f1f" // Color simmilar to bg
|
||||
var contrastColor = "#92ffd1" // Contrast to mainColor
|
||||
var textColor = "#FFFFFF";
|
||||
|
||||
css BlogFormInput() {
|
||||
width: 70%;
|
||||
height: 150px;
|
||||
padding: 12px 20px;
|
||||
box-sizing: border-box;
|
||||
border: 2px solid { bgVariation };
|
||||
border-radius: 4px;
|
||||
background-color: #f8f8f8;
|
||||
font-size: 13px;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
css FileHeader() {
|
||||
color: { mainColor };
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
css Header() {
|
||||
color: { mainColor };
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
css HighlightText() {
|
||||
color: { contrastColor };
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
css Textcontainer() {
|
||||
block-size: fit-content;
|
||||
padding: 5px;
|
||||
text-wrap: wrap;
|
||||
margin: 10px;
|
||||
color: { textColor };
|
||||
}
|
||||
|
||||
css BlogContainer() {
|
||||
border: 2px dashed gray;
|
||||
margin: 20px;
|
||||
}
|
||||
|
||||
css HelloContainer() {
|
||||
height: fit-content;
|
||||
padding: 50px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: { textColor };
|
||||
background: { bgVariation };
|
||||
}
|
||||
|
||||
css BlockContainer() {
|
||||
height: fit-content;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
background: { bgVariation };
|
||||
}
|
||||
|
||||
css PostScriptum() {
|
||||
text-align: center;
|
||||
font-size: 12px;
|
||||
color: { contrastColor };
|
||||
}
|
||||
|
||||
css DefaultTable() {
|
||||
border-collapse: collapse;
|
||||
border: 1px solid;
|
||||
color: { textColor };
|
||||
}
|
||||
|
||||
css CenterPageContainer() {
|
||||
padding: 15px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-ms-transform: translateX(-50%) translateY(-50%);
|
||||
-webkit-transform: translate(-50%,-50%);
|
||||
transform: translate(-50%,-50%);
|
||||
}
|
||||
|
||||
css CenterContainer() {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
184
web/static/styling/basic-styling_templ.go
Normal file
184
web/static/styling/basic-styling_templ.go
Normal file
@ -0,0 +1,184 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
package styling
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
/*
|
||||
In this file I write main CSS for all webpages.
|
||||
Also I store there some variables that I use a lot.
|
||||
Currently all elements are not sorted.
|
||||
Be aware that class names in final html page will be random.
|
||||
*/
|
||||
|
||||
var mainColor = "#ffb37f"
|
||||
var bgColor = "#272727"
|
||||
var bgVariation = "#1f1f1f" // Color simmilar to bg
|
||||
var contrastColor = "#92ffd1" // Contrast to mainColor
|
||||
var textColor = "#FFFFFF"
|
||||
|
||||
func BlogFormInput() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`width:70%;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`height:150px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`padding:12px 20px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`box-sizing:border-box;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`border:2px solid { bgVariation };`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`border-radius:4px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`background-color:#f8f8f8;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`font-size:13px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`resize:none;`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`BlogFormInput`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func FileHeader() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, mainColor)))
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`text-align:center;`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`FileHeader`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func Header() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, mainColor)))
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`text-align:left;`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`Header`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func HighlightText() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, contrastColor)))
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`font-weight:bold;`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`HighlightText`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func Textcontainer() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`block-size:fit-content;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`padding:5px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`text-wrap:wrap;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`margin:10px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, textColor)))
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`Textcontainer`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func BlogContainer() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`border:2px dashed gray;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`margin:20px;`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`BlogContainer`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func HelloContainer() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`height:fit-content;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`padding:50px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`display:flex;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`flex-direction:column;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`justify-content:center;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`align-items:center;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, textColor)))
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`background`, bgVariation)))
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`HelloContainer`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func BlockContainer() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`height:fit-content;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`display:flex;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`flex-direction:column;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`justify-content:center;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`background`, bgVariation)))
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`BlockContainer`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func PostScriptum() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`text-align:center;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`font-size:12px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, contrastColor)))
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`PostScriptum`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func DefaultTable() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`border-collapse:collapse;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`border:1px solid;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(string(templ.SanitizeCSS(`color`, textColor)))
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`DefaultTable`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func CenterPageContainer() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`padding:15px;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`position:absolute;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`top:50%;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`left:50%;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`-ms-transform:translateX(-50%) translateY(-50%);`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`-webkit-transform:translate(-50%,-50%);`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`transform:translate(-50%,-50%);`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`CenterPageContainer`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
func CenterContainer() templ.CSSClass {
|
||||
templ_7745c5c3_CSSBuilder := templruntime.GetBuilder()
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`display:flex;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`flex-direction:column;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`justify-content:center;`)
|
||||
templ_7745c5c3_CSSBuilder.WriteString(`align-items:center;`)
|
||||
templ_7745c5c3_CSSID := templ.CSSID(`CenterContainer`, templ_7745c5c3_CSSBuilder.String())
|
||||
return templ.ComponentCSSClass{
|
||||
ID: templ_7745c5c3_CSSID,
|
||||
Class: templ.SafeCSS(`.` + templ_7745c5c3_CSSID + `{` + templ_7745c5c3_CSSBuilder.String() + `}`),
|
||||
}
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
76
web/templates/admin.templ
Normal file
76
web/templates/admin.templ
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Collection of pages which handles everything admin-panel related.
|
||||
Login page collects information and passes it via post method to backend
|
||||
which processes passed form and shows templ AdminPanelPage().
|
||||
If form incorrected than it shows nothing.
|
||||
*/
|
||||
package templates
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
import "strconv"
|
||||
import "github.com/dixxe/personal-website/iternal/pkg/repositories"
|
||||
|
||||
// Template to reduce boilerplate and untie everything
|
||||
templ postsTable(blogPosts []repositories.Post) {
|
||||
if len(blogPosts) == 0 {
|
||||
<h1 class={ styling.Header() }>База данных блога не загрузилась.</h1>
|
||||
}
|
||||
<table class={ styling.DefaultTable() }>
|
||||
<thead>
|
||||
<tr>
|
||||
<th> ID </th>
|
||||
<th> Header </th>
|
||||
<th> Content </th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
for _, post := range blogPosts {
|
||||
<tr>
|
||||
<td><span> {strconv.Itoa(post.Id)} </span></td>
|
||||
<td><span> {post.Header} </span></td>
|
||||
<td><span> {post.Content} </span></td>
|
||||
</tr>
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
}
|
||||
|
||||
templ AdminPanelPage(blogPosts []repositories.Post) {
|
||||
@BasicPageBlock()
|
||||
|
||||
<h1 class={ styling.FileHeader() }>Очень защищенная админ-панель</h1>
|
||||
<hr>
|
||||
|
||||
<div class={ styling.Textcontainer() }>
|
||||
<h2 class={ styling.Header() }> Добавление новых постов </h2>
|
||||
<form action="/post" method="post">
|
||||
<p>Header: <input type="text" name="header" /> </p>
|
||||
<p>Content: <textarea class={ styling.BlogFormInput() } type="text" name="content" /> </p>
|
||||
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset"></p>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<h2 class={ styling.Header() }> Удаление постов </h2>
|
||||
<form action="/post/delete" method="post">
|
||||
<p>Please specify post ID: <input type="number" name="id" value="id"/></p>
|
||||
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset"></p>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
@postsTable(blogPosts)
|
||||
}
|
||||
|
||||
templ LoginPage() {
|
||||
@BasicPageBlock()
|
||||
|
||||
<div class={ styling.CenterPageContainer(), styling.Textcontainer() }>
|
||||
<form action="/admin/login" method="post">
|
||||
<p>Login: <input type="text" name="login" /> </p>
|
||||
<p>Password: <input type="password" name="password" /> </p>
|
||||
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset"></p>
|
||||
</form>
|
||||
</div>
|
||||
}
|
347
web/templates/admin_templ.go
Normal file
347
web/templates/admin_templ.go
Normal file
@ -0,0 +1,347 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
/*
|
||||
|
||||
|
||||
Collection of pages which handles everything admin-panel related.
|
||||
|
||||
|
||||
Login page collects information and passes it via post method to backend
|
||||
|
||||
|
||||
which processes passed form and shows templ AdminPanelPage().
|
||||
|
||||
|
||||
If form incorrected than it shows nothing.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
import "strconv"
|
||||
import "github.com/dixxe/personal-website/iternal/pkg/repositories"
|
||||
|
||||
// Template to reduce boilerplate and untie everything
|
||||
func postsTable(blogPosts []repositories.Post) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
if len(blogPosts) == 0 {
|
||||
var templ_7745c5c3_Var2 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">База данных блога не загрузилась.</h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{styling.DefaultTable()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<table class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\"><thead><tr><th>ID </th><th>Header </th><th>Content </th></tr></thead> <tbody>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for _, post := range blogPosts {
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<tr><td><span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(post.Id))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 29, Col: 41}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</span></td><td><span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(post.Header)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 30, Col: 31}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</span></td><td><span>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 string
|
||||
templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(post.Content)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 31, Col: 32}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "</span></td></tr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "</tbody></table>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func AdminPanelPage(blogPosts []repositories.Post) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var9 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var9 == nil {
|
||||
templ_7745c5c3_Var9 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 = []any{styling.FileHeader()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "\">Очень защищенная админ-панель</h1><hr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 = []any{styling.Textcontainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "<h2 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\">Добавление новых постов </h2><form action=\"/post\" method=\"post\"><p>Header: <input type=\"text\" name=\"header\"></p><p>Content: ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 = []any{styling.BlogFormInput()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "<textarea class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 string
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var16).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "\" type=\"text\" name=\"content\"></textarea></p><p><input type=\"submit\" value=\"Submit\"> <input type=\"reset\" value=\"Reset\"></p></form><hr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var18 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "<h2 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var19 string
|
||||
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var18).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\">Удаление постов </h2><form action=\"/post/delete\" method=\"post\"><p>Please specify post ID: <input type=\"number\" name=\"id\" value=\"id\"></p><p><input type=\"submit\" value=\"Submit\"> <input type=\"reset\" value=\"Reset\"></p></form></div><hr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = postsTable(blogPosts).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func LoginPage() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var20 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var20 == nil {
|
||||
templ_7745c5c3_Var20 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var21 = []any{styling.CenterPageContainer(), styling.Textcontainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var21...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var22 string
|
||||
templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var21).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/admin.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\"><form action=\"/admin/login\" method=\"post\"><p>Login: <input type=\"text\" name=\"login\"></p><p>Password: <input type=\"password\" name=\"password\"></p><p><input type=\"submit\" value=\"Submit\"> <input type=\"reset\" value=\"Reset\"></p></form></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
89
web/templates/blog.templ
Normal file
89
web/templates/blog.templ
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
Template that grew in complexity recently. It's was first template that supports JS.
|
||||
|
||||
1. Template contains local templ blocks their names starting with lowercase to make it DRY
|
||||
2. JS script is seperated and should be called *after* page construction.
|
||||
3. Templ ShowBlogPage contains some math to dynamicly reduce post size
|
||||
|
||||
TODO - make it more DRY and modular in general
|
||||
*/
|
||||
package templates
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
import "github.com/dixxe/personal-website/iternal/pkg/repositories"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
import "math"
|
||||
|
||||
var markedHandle = templ.NewOnceHandle()
|
||||
|
||||
templ runMarked(markdown string) {
|
||||
|
||||
@templ.JSONScript("md", markdown)
|
||||
|
||||
@markedHandle.Once() {
|
||||
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
const markdown = JSON.parse(document.getElementById('md').textContent);
|
||||
document.getElementById('post-content').innerHTML =
|
||||
marked.parse( markdown );
|
||||
|
||||
</script>
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
templ blogHeader() {
|
||||
<h1 class={ styling.FileHeader() } style="font-family: Disket-Mono;">Блог дихуса</h1>
|
||||
<p class={ styling.PostScriptum() }> Вернуться <a href="/">Домой</a> </p>
|
||||
<hr>
|
||||
}
|
||||
|
||||
templ ShowPost(post repositories.Post){
|
||||
@BasicPageBlock()
|
||||
@blogHeader()
|
||||
|
||||
<div class={ styling.BlogContainer(), styling.CenterContainer(), styling.Textcontainer() }>
|
||||
<h1 style="font-family: Disket-Mono" class={ styling.Header(), styling.HighlightText() }>
|
||||
{post.Header}
|
||||
</h1>
|
||||
<div id="post-content"></div>
|
||||
</div>
|
||||
|
||||
@runMarked(post.Content)
|
||||
}
|
||||
|
||||
|
||||
templ ShowBlogPage(posts []repositories.Post) {
|
||||
@BasicPageBlock()
|
||||
@blogHeader()
|
||||
|
||||
for i := len(posts) - 1; i>=0; i-- {
|
||||
<div class={ styling.Textcontainer(), styling.BlogContainer() }>
|
||||
<h1 style="font-family: Disket-Mono;">
|
||||
<a class={ styling.Header() } href={ templ.URL(fmt.Sprintf("/post/%v", posts[i].Id)) }>
|
||||
{posts[i].Header}
|
||||
</a>
|
||||
</h1>
|
||||
|
||||
{{
|
||||
// It's probably awfull practice, but here I calculate
|
||||
// post size and make it smaller.. In frontend! Magic!
|
||||
postWords := strings.Fields(posts[i].Content)
|
||||
postCap := int(math.Sqrt(float64(len(postWords))*5))
|
||||
shortStr := postWords[:postCap]
|
||||
|
||||
}}
|
||||
|
||||
<p id="post-content"> {strings.Join(shortStr, " ")}... </p>
|
||||
<a class={ styling.HighlightText() } href={ templ.URL(fmt.Sprintf("/post/%v", posts[i].Id)) }>
|
||||
Читать полностью...
|
||||
</a>
|
||||
</div>
|
||||
|
||||
}
|
||||
|
||||
@UsefulLinks()
|
||||
}
|
418
web/templates/blog_templ.go
Normal file
418
web/templates/blog_templ.go
Normal file
@ -0,0 +1,418 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
/*
|
||||
|
||||
|
||||
Template that grew in complexity recently. It's was first template that supports JS.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
1. Template contains local templ blocks their names starting with lowercase to make it DRY
|
||||
|
||||
|
||||
2. JS script is seperated and should be called *after* page construction.
|
||||
|
||||
|
||||
3. Templ ShowBlogPage contains some math to dynamicly reduce post size
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
TODO - make it more DRY and modular in general
|
||||
|
||||
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
import "github.com/dixxe/personal-website/iternal/pkg/repositories"
|
||||
import "fmt"
|
||||
import "strings"
|
||||
import "math"
|
||||
|
||||
var markedHandle = templ.NewOnceHandle()
|
||||
|
||||
func runMarked(markdown string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templ.JSONScript("md", markdown).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<script src=\"https://cdn.jsdelivr.net/npm/marked/marked.min.js\"></script> <script type=\"text/javascript\">\n\n const markdown = JSON.parse(document.getElementById('md').textContent);\n document.getElementById('post-content').innerHTML =\n marked.parse( markdown );\n\n </script>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
templ_7745c5c3_Err = markedHandle.Once().Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func blogHeader() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var3 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var3 == nil {
|
||||
templ_7745c5c3_Var3 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var4 = []any{styling.FileHeader()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\" style=\"font-family: Disket-Mono;\">Блог дихуса</h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{styling.PostScriptum()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<p class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "\">Вернуться <a href=\"/\">Домой</a></p><hr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ShowPost(post repositories.Post) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var8 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var8 == nil {
|
||||
templ_7745c5c3_Var8 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = blogHeader().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 = []any{styling.BlogContainer(), styling.CenterContainer(), styling.Textcontainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var9...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 string
|
||||
templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var9).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 = []any{styling.Header(), styling.HighlightText()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var11...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "<h1 style=\"font-family: Disket-Mono\" class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 string
|
||||
templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var11).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(post.Header)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 50, Col: 18}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</h1><div id=\"post-content\"></div></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = runMarked(post.Content).Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func ShowBlogPage(posts []repositories.Post) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var14 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var14 == nil {
|
||||
templ_7745c5c3_Var14 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = blogHeader().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
for i := len(posts) - 1; i >= 0; i-- {
|
||||
var templ_7745c5c3_Var15 = []any{styling.Textcontainer(), styling.BlogContainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var15...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 string
|
||||
templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var15).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\"><h1 style=\"font-family: Disket-Mono;\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var17...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<a class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var18 string
|
||||
templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var17).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\" href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var19 templ.SafeURL = templ.URL(fmt.Sprintf("/post/%v", posts[i].Id))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var19)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var20 string
|
||||
templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(posts[i].Header)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 67, Col: 36}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "</a></h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
|
||||
// It's probably awfull practice, but here I calculate
|
||||
// post size and make it smaller.. In frontend! Magic!
|
||||
postWords := strings.Fields(posts[i].Content)
|
||||
postCap := int(math.Sqrt(float64(len(postWords)) * 5))
|
||||
shortStr := postWords[:postCap]
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<p id=\"post-content\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var21 string
|
||||
templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(strings.Join(shortStr, " "))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 80, Col: 62}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "... </p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var22 = []any{styling.HighlightText()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "<a class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var23 string
|
||||
templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var22).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/blog.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "\" href=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var24 templ.SafeURL = templ.URL(fmt.Sprintf("/post/%v", posts[i].Id))
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(string(templ_7745c5c3_Var24)))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\">Читать полностью...</a></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
}
|
||||
templ_7745c5c3_Err = UsefulLinks().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
60
web/templates/constructionBlocks.templ
Normal file
60
web/templates/constructionBlocks.templ
Normal file
@ -0,0 +1,60 @@
|
||||
/*
|
||||
Small block that I write to reuse in other templates to remove boilerplate.
|
||||
Syntax to reuse templates: @BasicPageBlock()
|
||||
*/
|
||||
package templates
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
|
||||
// Use this block in every page. It contains dependecies and reduces boilerplate
|
||||
templ BasicPageBlock() {
|
||||
<!DOCTYPE HTML>
|
||||
<html style="background-color: #272727; ">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
|
||||
<link rel="icon" type="image/png" href="/static/icon.png" />
|
||||
|
||||
<style>
|
||||
|
||||
@font-face {
|
||||
font-family: Disket-Mono;
|
||||
src: url("/static/fonts/Disket-Mono-Bold.ttf");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Codec-pro;
|
||||
src: url("/static/fonts/codec-pro.regular.ttf");
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<title>dixxe's website</title>
|
||||
</head>
|
||||
<body style="padding: 0; margin: 0; font-family:Codec-pro">
|
||||
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
|
||||
// Small styled line of links to my friends and contact information.
|
||||
templ UsefulLinks() {
|
||||
<div class={ styling.BlockContainer(), styling.PostScriptum() }>
|
||||
|
||||
<p>
|
||||
You can find source code of this website
|
||||
<a href="https://github.com/dixxe/personal-website">here.</a>
|
||||
</p>
|
||||
|
||||
<p>Telegram - "@d1xxe"</p>
|
||||
<p>Matrix - "@d1xxe:matrix.org"</p>
|
||||
|
||||
<p>My friends:
|
||||
<a href="https://t.me/LunfQwak1">Lunf</a>
|
||||
<a href="https://t.me/Ovi4k">Madam_ovi</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
}
|
102
web/templates/constructionBlocks_templ.go
Normal file
102
web/templates/constructionBlocks_templ.go
Normal file
@ -0,0 +1,102 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
/*
|
||||
|
||||
|
||||
Small block that I write to reuse in other templates to remove boilerplate.
|
||||
|
||||
|
||||
Syntax to reuse templates: @BasicPageBlock()
|
||||
|
||||
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
|
||||
// Use this block in every page. It contains dependecies and reduces boilerplate
|
||||
func BasicPageBlock() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!doctype HTML><html style=\"background-color: #272727; \"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><link rel=\"icon\" type=\"image/png\" href=\"/static/icon.png\"><style>\n\n @font-face {\n font-family: Disket-Mono;\n src: url(\"/static/fonts/Disket-Mono-Bold.ttf\");\n }\n\n @font-face {\n font-family: Codec-pro;\n src: url(\"/static/fonts/codec-pro.regular.ttf\");\n }\n\n </style><title>dixxe's website</title></head><body style=\"padding: 0; margin: 0; font-family:Codec-pro\"></body></html>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// Small styled line of links to my friends and contact information.
|
||||
func UsefulLinks() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var2 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var2 == nil {
|
||||
templ_7745c5c3_Var2 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
var templ_7745c5c3_Var3 = []any{styling.BlockContainer(), styling.PostScriptum()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var3...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 string
|
||||
templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var3).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/constructionBlocks.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "\"><p>You can find source code of this website <a href=\"https://github.com/dixxe/personal-website\">here.</a></p><p>Telegram - \"@d1xxe\"</p><p>Matrix - \"@d1xxe:matrix.org\"</p><p>My friends: <a href=\"https://t.me/LunfQwak1\">Lunf</a> <a href=\"https://t.me/Ovi4k\">Madam_ovi</a></p></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
14
web/templates/errorPage.templ
Normal file
14
web/templates/errorPage.templ
Normal file
@ -0,0 +1,14 @@
|
||||
package templates
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
import "strconv"
|
||||
|
||||
templ ErrorPage(code int, additional_info string) {
|
||||
@BasicPageBlock()
|
||||
|
||||
<div class={ styling.Textcontainer(), styling.CenterPageContainer() }>
|
||||
<h1 class={ styling.Header() }>Error { strconv.Itoa(code) }</h1>
|
||||
<p> Something went wrong. {additional_info} </p>
|
||||
<p class={ styling.PostScriptum() }> Go <a href="/">home</a> </p>
|
||||
</div>
|
||||
}
|
135
web/templates/errorPage_templ.go
Normal file
135
web/templates/errorPage_templ.go
Normal file
@ -0,0 +1,135 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
package templates
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
import "strconv"
|
||||
|
||||
func ErrorPage(code int, additional_info string) templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 = []any{styling.Textcontainer(), styling.CenterPageContainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/errorPage.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/errorPage.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\">Error ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 string
|
||||
templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(strconv.Itoa(code))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/errorPage.templ`, Line: 10, Col: 65}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "</h1><p>Something went wrong. ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(additional_info)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/errorPage.templ`, Line: 11, Col: 50}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "</p>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 = []any{styling.PostScriptum()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<p class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/errorPage.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\">Go <a href=\"/\">home</a></p></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
71
web/templates/index.templ
Normal file
71
web/templates/index.templ
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
Main page of website that shows on root.
|
||||
Contains useful information and links to other pages
|
||||
*/
|
||||
package templates
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
|
||||
templ IndexPage() {
|
||||
@BasicPageBlock()
|
||||
|
||||
<div class={ styling.HelloContainer() }>
|
||||
<p style="font-family: Disket-Mono; ">
|
||||
<span>Greetings! I'm </span>
|
||||
<br>
|
||||
<span style="font-size: 60px; color: #ffb37f">d1xxe</span>
|
||||
<br>
|
||||
<span>and this is my </span>
|
||||
<br>
|
||||
<span style="font-size: 40px;">personal</span>
|
||||
<span style="font-size: 40px;"> website</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class={ styling.Textcontainer(), styling.CenterContainer() } style="font-size: 20px;">
|
||||
|
||||
<h2 class={ styling.Header() } style="font-family: Disket-Mono;">
|
||||
About me
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
<span>I'm </span>
|
||||
<span class={ styling.HighlightText() }> 16 </span>
|
||||
<span>years old junior software engineer.</span>
|
||||
<br>
|
||||
<span>Born & live in Russia 🇷🇺 </span>
|
||||
<br>
|
||||
<span> I speak native Russian and English(B2)</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span> I have skills in </span>
|
||||
<span class={ styling.HighlightText() }>Go, Java, Rust, Nix</span>
|
||||
<span>and</span>
|
||||
<span class={ styling.HighlightText() }>Linux</span>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span>I have a passion to learn new, complex things.</span>
|
||||
<br>
|
||||
<span>Currently I'm learning SQL, DBMS</span>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class={ styling.CenterContainer(), styling.Textcontainer() } style="font-size: 20px;">
|
||||
<p>I don't have any finished project yet :P</p>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
|
||||
<div class={ styling.CenterContainer(), styling.Textcontainer() }>
|
||||
<h1 class={ styling.Header() } style="font-family: Disket-Mono;">More stuff from me</h1>
|
||||
|
||||
<a href="/blog">Personal blog</a>
|
||||
|
||||
</div>
|
||||
|
||||
@UsefulLinks()
|
||||
}
|
255
web/templates/index_templ.go
Normal file
255
web/templates/index_templ.go
Normal file
@ -0,0 +1,255 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
/*
|
||||
|
||||
|
||||
Main page of website that shows on root.
|
||||
|
||||
|
||||
Contains useful information and links to other pages
|
||||
|
||||
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
|
||||
func IndexPage() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 = []any{styling.HelloContainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\"><p style=\"font-family: Disket-Mono; \"><span>Greetings! I'm </span><br><span style=\"font-size: 60px; color: #ffb37f\">d1xxe</span><br><span>and this is my </span><br><span style=\"font-size: 40px;\">personal</span> <span style=\"font-size: 40px;\">website</span></p></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{styling.Textcontainer(), styling.CenterContainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\" style=\"font-size: 20px;\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<h2 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\" style=\"font-family: Disket-Mono;\">About me</h2><p><span>I'm </span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var8 = []any{styling.HighlightText()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var8...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "<span class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var9 string
|
||||
templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var8).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "\">16 </span> <span>years old junior software engineer.</span><br><span>Born & live in Russia 🇷🇺 </span><br><span>I speak native Russian and English(B2)</span></p><p><span>I have skills in </span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var10 = []any{styling.HighlightText()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var10...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "<span class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var11 string
|
||||
templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var10).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "\">Go, Java, Rust, Nix</span> <span>and</span> ")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var12 = []any{styling.HighlightText()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var12...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "<span class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var13 string
|
||||
templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var12).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "\">Linux</span></p><p><span>I have a passion to learn new, complex things.</span><br><span>Currently I'm learning SQL, DBMS</span></p></div><hr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var14 = []any{styling.CenterContainer(), styling.Textcontainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var14...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var15 string
|
||||
templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var14).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "\" style=\"font-size: 20px;\"><p>I don't have any finished project yet :P</p></div><hr>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var16 = []any{styling.CenterContainer(), styling.Textcontainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var16...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var17 string
|
||||
templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var16).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var18 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var18...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var19 string
|
||||
templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var18).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/index.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 18, "\" style=\"font-family: Disket-Mono;\">More stuff from me</h1><a href=\"/blog\">Personal blog</a></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = UsefulLinks().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
16
web/templates/wip.templ
Normal file
16
web/templates/wip.templ
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
Placeholder webpage for not-implemented functional.
|
||||
Links back to root (index).
|
||||
*/
|
||||
package templates
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
|
||||
templ WIPPage() {
|
||||
@BasicPageBlock()
|
||||
|
||||
<div class={ styling.Textcontainer(), styling.CenterPageContainer() }>
|
||||
<h1 class={ styling.Header() }>Page is under construction</h1>
|
||||
<p class={ styling.PostScriptum() }> Вернуться <a href="/">Домой</a> </p>
|
||||
</div>
|
||||
}
|
119
web/templates/wip_templ.go
Normal file
119
web/templates/wip_templ.go
Normal file
@ -0,0 +1,119 @@
|
||||
// Code generated by templ - DO NOT EDIT.
|
||||
|
||||
// templ: version: v0.3.819
|
||||
/*
|
||||
|
||||
|
||||
Placeholder webpage for not-implemented functional.
|
||||
|
||||
|
||||
Links back to root (index).
|
||||
|
||||
|
||||
*/
|
||||
|
||||
package templates
|
||||
|
||||
//lint:file-ignore SA4006 This context is only used if a nested component is present.
|
||||
|
||||
import "github.com/a-h/templ"
|
||||
import templruntime "github.com/a-h/templ/runtime"
|
||||
|
||||
import "github.com/dixxe/personal-website/web/static/styling"
|
||||
|
||||
func WIPPage() templ.Component {
|
||||
return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
|
||||
templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
|
||||
if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
|
||||
return templ_7745c5c3_CtxErr
|
||||
}
|
||||
templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
|
||||
if !templ_7745c5c3_IsBuffer {
|
||||
defer func() {
|
||||
templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err == nil {
|
||||
templ_7745c5c3_Err = templ_7745c5c3_BufErr
|
||||
}
|
||||
}()
|
||||
}
|
||||
ctx = templ.InitializeContext(ctx)
|
||||
templ_7745c5c3_Var1 := templ.GetChildren(ctx)
|
||||
if templ_7745c5c3_Var1 == nil {
|
||||
templ_7745c5c3_Var1 = templ.NopComponent
|
||||
}
|
||||
ctx = templ.ClearChildren(ctx)
|
||||
templ_7745c5c3_Err = BasicPageBlock().Render(ctx, templ_7745c5c3_Buffer)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var2 = []any{styling.Textcontainer(), styling.CenterPageContainer()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var2...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var3 string
|
||||
templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var2).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/wip.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "\">")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var4 = []any{styling.Header()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var4...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "<h1 class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var5 string
|
||||
templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var4).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/wip.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "\">Page is under construction</h1>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var6 = []any{styling.PostScriptum()}
|
||||
templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var6...)
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "<p class=\"")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
var templ_7745c5c3_Var7 string
|
||||
templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var6).String())
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ.Error{Err: templ_7745c5c3_Err, FileName: `web/templates/wip.templ`, Line: 1, Col: 0}
|
||||
}
|
||||
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "\">Вернуться <a href=\"/\">Домой</a></p></div>")
|
||||
if templ_7745c5c3_Err != nil {
|
||||
return templ_7745c5c3_Err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
var _ = templruntime.GeneratedTemplate
|
Loading…
x
Reference in New Issue
Block a user