first commit

This commit is contained in:
Max Chaev 2025-01-28 18:43:37 +03:00
commit ab174b8de5
35 changed files with 2804 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.env
*.db

21
LICENSE Normal file
View 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
View 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
View 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
View 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
View 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
View 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=

View 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)
}
}

View 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)
}

View 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])
}

View 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)
}

View 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)
}

View 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
}

View 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
View 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)
}

View 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
View 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!!

View File

@ -0,0 +1,3 @@
go test fuzz v1
int(34)
string("\"+")

Binary file not shown.

Binary file not shown.

Binary file not shown.

View 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;
}

View 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
View 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>
}

View 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
View 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
View 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

View 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>
}

View 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

View 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>
}

View 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
View 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()
}

View 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
View 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
View 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