From 7d5e3368683549245c4360c5ef1b1cb6af92e1ad Mon Sep 17 00:00:00 2001 From: thek4n Date: Wed, 3 Jun 2026 00:40:13 +0300 Subject: [PATCH] feat: implement prototype --- Cargo.lock | 194 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + docs/config_example.toml | 67 +++++++++---- index.html | 82 +++++++++++++++ src/main.rs | 152 +++++++++++++++++++++++++++- templates/html_index.jinja2 | 81 +++++++++++++++ templates/index.tmpl | 58 ----------- templates/text_index.jinja2 | 24 +++++ 8 files changed, 579 insertions(+), 80 deletions(-) create mode 100644 Cargo.lock create mode 100644 index.html create mode 100644 templates/html_index.jinja2 delete mode 100644 templates/index.tmpl create mode 100644 templates/text_index.jinja2 diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..1685542 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,194 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "askama" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bf825125edd887a019d0a3a837dcc5499a68b0d034cc3eb594070c3e18addc" +dependencies = [ + "askama_macros", + "itoa", + "percent-encoding", + "serde", + "serde_json", +] + +[[package]] +name = "askama_derive" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1c7065972a130eafa84215f21352ae15b4a7393da48c1f5e103904490736738" +dependencies = [ + "askama_parser", + "basic-toml", + "glob", + "memchr", + "proc-macro2", + "quote", + "rustc-hash", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "askama_macros" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e23b1d2c4bd39a41971f6124cef4cc6fd0540913ecb90919b69ab3bbe44ae1a" +dependencies = [ + "askama_derive", +] + +[[package]] +name = "askama_parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7db09fde9143e7ac4513358fb32ee32847125b63b18ea715afd487956da715da" +dependencies = [ + "rustc-hash", + "serde", + "serde_derive", + "unicode-ident", + "winnow", +] + +[[package]] +name = "basic-toml" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba62675e8242a4c4e806d12f11d136e626e6c8361d6b829310732241652a178a" +dependencies = [ + "serde", +] + +[[package]] +name = "glob" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustc-hash" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thek4n-ru" +version = "0.1.0" +dependencies = [ + "askama", +] + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "winnow" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml index 1a9778b..6587f94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,4 @@ edition = "2024" authors = ["Vladislav Kan "] [dependencies] +askama = "0.16.0" diff --git a/docs/config_example.toml b/docs/config_example.toml index 7b0fe8b..83b6dd9 100644 --- a/docs/config_example.toml +++ b/docs/config_example.toml @@ -1,22 +1,30 @@ [page] -page-title = "thek4n" -page-meta-desc = "thek4n - developer" -copyright-author = "thek4n" +title = "Hi, I'm Vlad" +meta_title = "thek4n" +meta_description = "thek4n - developer" +description = "Developer" +copyright_author = "thek4n" # --- # Site registered languages -[languages] -en = "english" -ru = "russian" +[[languages]] +key = "en" +title = "english" + +[[languages]] +key = "ru" +title = "russian" # --- -[aboutme] +[page.aboutme] +title.en = "About Me" +title.ru = "Обо Мне" text.en = ''' ''' @@ -29,16 +37,22 @@ text.ru = ''' # --- -[gpg] +[page.gpg] +title.en = "GPG Public Key" +title.ru = "Публичный ключ GPG" url = "/gpgkey.txt" -showkey-text.en = "Show key" -showkey-text.ru = "Показать ключ" +url_title = "thek4n.ru/gpgkey.txt" +showkey_title.en = "Show key" +showkey_title.ru = "Показать ключ" -availat-text.en = "Available at" -availat-text.ru = "Доступен по" +availat_title.en = "Available at" +availat_title.ru = "Доступен по" -copied-text.en = "Copied!" -copied-text.ru = "Скопировано!" +copy_title.en = "Show key" +copy_title.ru = "Показать ключ" + +copied_title.en = "Copied!" +copied_title.ru = "Скопировано!" value = ''' asdfasdf @@ -49,22 +63,31 @@ asdfasdf # --- +[page.projects] +title.en = "Projects" +title.ru = "Проекты" [[projects]] title = "ip.thek4n.ru" url = "https://ip.thek4n.ru" +source_url = "https://gitea.thek4n.ru/thek4n/ip.thek4n.ru" +source_url_title = "thek4n/ip.thek4n.ru" description.en = "check my ip service" description.ru = "сервис определения ip" [[projects]] title = "paste.thek4n.ru" url = "https://paste.thek4n.ru" +source_url = "https://gitea.thek4n.ru/thek4n/paste.thek4n.ru" +source_url_title = "thek4n/paste.thek4n.ru" description.en = "copy/paste and url shortener service" description.ru = "укоротитель ссылок" [[projects]] title = "thek4n.ru" url = "https://thek4n.ru" +source_url = "https://gitea.thek4n.ru/thek4n/thek4n.ru" +source_url_title = "thek4n/thek4n.ru" description.en = "this site source" description.ru = "исходники этого сайта" @@ -72,20 +95,24 @@ description.ru = "исходники этого сайта" # --- +[page.contacts] +title.en = "Contacts" +title.ru = "Контакты" + [[contacts]] -name.en = "Telegram" -name.ru = "Телеграм" +site_name.en = "Telegram" +site_name.ru = "Телеграм" title = "@thek4n" url = "https://t.me/thek4n" [[contacts]] -name.en = "Github" -name.ru = "Github" +site_name.en = "Github" +site_name.ru = "Github" title = "github.com/thek4n" url = "https://github.com/thek4n" [[contacts]] -name.en = "Email" -name.ru = "Почта" +site_name.en = "Email" +site_name.ru = "Почта" title = "thek4n@yandex.ru" url = "mailto:thek4n@yandex.ru" diff --git a/index.html b/index.html new file mode 100644 index 0000000..2292244 --- /dev/null +++ b/index.html @@ -0,0 +1,82 @@ + + + + + + thek4n + + + + + +
+
+
+ + English + +
+
+ +
+

TheK4n

+

Developer

+
+ +
+

Projects

+ +

+ project + : + thek4n/paste.thek4n.ru + (copy/paste service) +

+ +
+ +
+

About Me

+

About me text

+
+ +
+

GPG

+ +

+ Available at + thek4n.ru/gpgkey.txt +

+ +
+ + ::marker + + Show key + Copy + + key.... + +
+ +
+ +
+

Contacts

+ +

+ Telegram + : + @thek4n +

+ +
+ +
+

© 2026 Vladislav Kan <thek4n@yandex.ru>

+
+
+ + + + diff --git a/src/main.rs b/src/main.rs index e7a11a9..a793ef2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,151 @@ -fn main() { - println!("Hello, world!"); +use askama::Template; + +#[derive(Template)] +#[template(path = "html_index.jinja2")] +struct HtmlPageTemplate<'a> { + title: &'a str, + description: &'a str, + copyright_author: &'a str, + base_url: &'a str, + meta: PageMeta<'a>, + year: &'a str, + aboutme: AboutMeSection<'a>, + gpg_section: GPGSection<'a>, + contacts_section: ContactsSection<'a>, + projects_section: ProjectsSection<'a>, + languages: Vec>, +} + +#[derive(Template)] +#[template(path = "text_index.jinja2", escape = "none")] +struct TextPageTemplate<'a> { + title: &'a str, + description: &'a str, + copyright_author: &'a str, + base_url: &'a str, + meta: PageMeta<'a>, + year: &'a str, + aboutme_section: AboutMeSection<'a>, + gpg_section: GPGSection<'a>, + contacts_section: ContactsSection<'a>, + projects_section: ProjectsSection<'a>, + languages: Vec>, +} + +struct PageMeta<'a> { + title: &'a str, + description: &'a str, +} + +struct AboutMeSection<'a> { + title: &'a str, + text: &'a str, +} + +struct GPGSection<'a> { + title: &'a str, + availat_title: &'a str, + url: &'a str, + url_title: &'a str, + showkey_title: &'a str, + copy_title: &'a str, + value: &'a str, +} + +struct ContactsSection<'a> { + title: &'a str, + contacts: Vec>, +} + +struct Contact<'a> { + site_name: &'a str, + url: &'a str, + title: &'a str, +} + +struct ProjectsSection<'a> { + title: &'a str, + projects: Vec>, +} + +struct Project<'a> { + title: &'a str, + url: &'a str, + source_url: &'a str, + source_url_title: &'a str, + description: &'a str, +} + +struct Language<'a> { + key: &'a str, + current: bool, + value: &'a str, +} + +fn main() { + let meta = PageMeta{ + title: "thek4n", + description: "thek4n - developer", + }; + + let aboutme_section = AboutMeSection{ + title: "About Me", + text: "About me text", + }; + + let gpg_section = GPGSection{ + title: "GPG Key", + availat_title: "Available at", + url: "/gpgkey.txt", + url_title: "thek4n.ru/gpgkey.txt", + showkey_title: "Show key", + copy_title: "Copy", + value: "key....", + }; + + let contacts = vec![Contact{ + site_name: "Telegram", + url: "https://t.me/thek4n", + title: "@thek4n", + }]; + + let contacts_section = ContactsSection{ + title: "Contacts", + contacts, + }; + + let projects = vec![Project{ + title: "project", + url: "https://paste.thek4n.ru", + source_url: "https://gitea.thek4n.ru/thek4n/paste.thek4n.ru", + source_url_title: "thek4n/paste.thek4n.ru", + description: "copy/paste service", + }]; + + let projects_section = ProjectsSection{ + title: "Projects", + projects, + }; + + let languages = vec![Language{ + key: "en", + current: true, + value: "English", + }]; + + let index = TextPageTemplate{ + title: "TheK4n", + description: "Developer", + copyright_author: "Vladislav Kan ", + base_url: "https://thek4n.ru", + meta, + year: "2026", // todo: get current year + aboutme_section, + gpg_section, + projects_section, + contacts_section, + languages, + }; + + println!("{}", index.render().unwrap()); } diff --git a/templates/html_index.jinja2 b/templates/html_index.jinja2 new file mode 100644 index 0000000..496e174 --- /dev/null +++ b/templates/html_index.jinja2 @@ -0,0 +1,81 @@ + + + + + + {{ meta.title }} + + + + + +
+
+
+ {% for lang in languages %} + {{ lang.value }} + {% endfor %} +
+
+ +
+

{{ title }}

+

{{ description }}

+
+ +
+

{{ projects_section.title }}

+ {% for project in projects_section.projects %} +

+ {{ project.title }} + : + {{ project.source_url_title }} + ({{ project.description }}) +

+ {% endfor %} +
+ +
+

{{ aboutme.title }}

+

{{ aboutme.text }}

+
+ +
+

{{ gpg_section.title }}

+ +

+ {{ gpg_section.availat_title }} + {{ gpg_section.url_title }} +

+ +
+ + + {{ gpg_section.showkey_title }} + {{ gpg_section.copy_title }} + + {{ gpg_section.value }} + +
+ +
+ +
+

{{ contacts_section.title }}

+ {% for contact in contacts_section.contacts %} +

+ {{ contact.site_name }} + : + {{ contact.title }} +

+ {% endfor %} +
+ +
+

© {{ year }} {{ copyright_author }}

+
+
+ + + + diff --git a/templates/index.tmpl b/templates/index.tmpl deleted file mode 100644 index 0e94b2e..0000000 --- a/templates/index.tmpl +++ /dev/null @@ -1,58 +0,0 @@ - - - - - - {{ PAGE TITLE }} - - - - - -
-
-
- en - ru - {{ LANGUAGES }} -
-
- -
-

{{ PAGE_TITLE }}

-

{{ PAGE_DESCRIPTION }}

-
- -
-

Projects

-

service desc

-
- -
-

GPG Public Key

- -

- Available at: - {{ GPG KEY URL }} -

- -
- - ::marker - - Show key - copy to clipboard - - -
- -
- -
-

© {{ YEAR }} {{ COPYRIGHT_AUTHOR }}

-
-
- - - - diff --git a/templates/text_index.jinja2 b/templates/text_index.jinja2 new file mode 100644 index 0000000..19f8db5 --- /dev/null +++ b/templates/text_index.jinja2 @@ -0,0 +1,24 @@ +{{ title }} - {{ description }} + + +{{ projects_section.title }}: +{%- for project in projects_section.projects %} + > {{ project.title }} ({{project.description}}) - {{ project.url }} +{%- endfor %} + + +{{ contacts_section.title }}: +{%- for contact in contacts_section.contacts %} + > {{ contact.site_name }}: {{ contact.title }} +{%- endfor %} + + +{{ gpg_section.title }}: {{ base_url }}{{ gpg_section.url }} + + +{{ aboutme_section.title }}: + {{ aboutme_section.text }} + + + +© {{ year }} {{ copyright_author }}