The darfk.net website
This website is static HTML generated using a single Rust source file and the maud crate. I chose this method because it allows me to quickly create content, learn rust and have a good time. I also do not really like writing XML. While I see the value in learning a static HTML framework, they're a bit overkill for what I need. At some point I might integrate markdown into this. Some pages are read from markdown files and rendered using this application.
the source?
here it is:
use std::fs; use std::path::Path; use chrono::Datelike; use maud::{html, Markup, DOCTYPE}; fn projects_index(pages: &Vec<Page>) -> Markup { struct PageLink { title: String, path: String, description: String, } let project_links = pages .iter() .filter(|page| page.typ == PageType::Project) .map(|page| PageLink { title: page.title.to_owned(), path: page.path.to_owned(), description: page.description.to_owned(), }) .collect::<Vec<_>>(); html!( h2 {"Projects"} p {"A list of completed works or works in progress."} @for project in project_links { hr; h3 { a href=(project.path) { (project.title) } } p { (project.description) } } ) } fn this_source_file() -> Markup { html!((fs::read_to_string("src/main.rs").unwrap())) } fn projects_website() -> Markup { html!( h2 {("The darfk.net website")} p { ("This website is static HTML generated using a single Rust source file and the ") a href="https://maud.lambda.xyz/" {("maud crate")} (".") (" I chose this method because it allows me to quickly create content, learn rust and have a good time.") (" I also do not really like writing XML.") (" While I see the value in learning a static HTML framework, they're a bit overkill for what I need. ") s {"At some point I might integrate markdown into this."} (" Some pages are read from markdown files and rendered using this application.") } h3 { ("the source?") } p { ("here it is:") } pre { (this_source_file()) } ) } // this is the original content for my site // I see no reason to change it fn index() -> Markup { html!( h1 { ("Greetings!") } p { (" I'm Thomas, a ") a href="https://en.wikipedia.org/wiki/Wollongong" { "Wollongong" } (" based software engineer with experience in interactive entertainment and embedded systems. I enjoy programming, electronics, video games and spending time with my friends and family. ") }; p { ("I've operated a ") a href="ts3server:teamspeak.darfk.net" {("teamspeak server")} (" since 2007, it's a place in which my friends and I hang out.")} p { ("If you would like to contact me:") } ul { li { ("email ") a href="mailto:tom@darfk.net" {("tom@darfk.net") } } li { ("telephone ") a href="tel:+61 4 0321 4411" {("+61 4 0321 4411") } } } p { em { ("Thank you for visiting!" )}} ) } fn resume() -> Markup { let role = |role: &str, from: &str, to: &str| html!((role) (" ") span class="lowlight" {("from ")} (from) (" ") span class="lowlight" {("to ")} (to)); html!( h1 {"Thomas Payne"} h2 { "Software and Electrical Engineer"} h4 id="resume-contact" { div { "mail: " a href="mailto:tom@darfk.net" { "tom@darfk.net" } }; div { "phone: " a href="tel:+61403214411" { "+61 4 0321 4411" } }; div class="hide-on-web" { "web: " a href="https://darfk.net" { "https://darfk.net" } }; } h2 { "About" } p { "I am a technical, logical and reasonable individual with a passion for computer science, interactive entertainment and emerging technologies. I have a strong appreciation for solid, concise software; taking inspiration from the likes of Carmack and Torvalds."} h2 { "Work Experience" } h3 {a href="https://bigtincan.com" {"Bigtincan"}} h4 {(role("Senior Developer", "Feb 2020", "present"))} ul { li { "Technical lead for microservice projects used to augment " a href="https://www.bigtincan.com/content/" {"BTC's core platforms"}; br; "written in "; a href="https://golang.org/" {"Go"} " and " a href="https://dotnet.microsoft.com" {".NET"} } li { "Develop and maintain software platform for integrating 3rd party Digital Asset Management systems into core platform; written in "; a href="https://www.java.com" {"Java"} ", " a href="https://dotnet.microsoft.com" {"C#/.NET"} " and " a href="https://www.typescriptlang.org/" {"Typescript"} } li { "Build in-house GUI tools for automation and monitoring using " a href="https://react.dev/" {"React.JS"} ", " a href="https://golang.org/" {"Go"} " and " a href="https://htmx.org/" {"HTMX"} } li {"Develop and maintain front end user applications written using " a href="https://react.dev/" {"React.JS"}} li { "Developed a lean CI/CD pipeline, optimised for responsiveness and zero downtime"; br; "leveraging "; a href="https://www.docker.com/" {"Docker"} ", " a href="https://kubernetes.io/" {"Kubernetes"} " and " a href="https://jenkins.io/" {"Jenkins"} } } h3 {a href="https://silabs.com" {"Silicon Labs (Sydney)"}} h4 {(role("Embedded Systems Developer", "2018", "closure, 2019"))} ul { li { "Extend functionality of cloud based IoT fleet management system"; br; "written in " a href="https://nodejs.org/" {"Node.js"} " and " a href="https://golang.org/" {"Go"} } li { "Development of sample 'apps' on Silabs' in-house embedded RTOS (" a href="https://docs.silabs.com/gecko-os/4/standard/latest/" { "Gecko OS 4"} "). Deployed for various platforms based on ARM Cortex-M4" } li { "Completed a rewrite of previous OTA firmware bundling software."; br; "Ported from Python 2 and C to Go"} li { "Development and maintenance of an automated regression testing system for embedded platforms, written using Python/Shell/C"} li { "Conducted employee training seminars on topics including: git, bash, unix philosophy"} } div class="page-break-after" {} h3 { "As a private contractor" } h4 { (role("", "Jan 2009", "Aug 2011")) ", " (role(" ", "Jan 2016", "Aug 2017")) } ul { li { "Develop a social network platform for a retirement village; using the Laravel framework" } li { "Designed and developed small websites for local businesses" } li { "Computer diagnosis and repair, NAS and backup systems installation for local businesses." } } h3 { "Modus Corporation" } h4 {(role("Developer", "Aug 2011", "Dec 2014"))} ul { li { "Extend functionality of cloud based IoT fleet management system"; br; "written in " a href="https://nodejs.org/" {"Node.js"} " and " a href="https://golang.org/" {"Go"} } li { "Maintain and develop in-house CMS and email/SMS broadcast system built in PHP" } li { "Responsive, mobile first website template builds using React"} li { "Develop tools to maintain full Linux server stack including continuous integration and deployment"} } h3 { "redzWeb digital marketing" } h4 {(role("Developer", "Jan 2008", "Feb 2009"))} ul { li { "Developed components for the " a href="https://www.joomla.org" { "Joomla!" } " CMS"; } li { "Managed media streaming services for live online broadcasts" } } hr class="page-break-after"; h2 {("Education")} h3 {("Bachelor of Engineering (Honors) - Electrical Engineering")} h4 {("2023 - University of Wollongong")} p {("Electives: Wireless Communication Systems, Network Engineering, Embedded Systems.")} p {("Extra curricula activities: Participated in and organised events within the UOW maker space. Designed and developed software platform for robotics experiments. Placed in several annual innovation fair showcases.")} h3 {("Advanced Diploma of Professional Game Development (Programming)")} h4 {("2010 - Academy of Interactive Entertainment Canberra")} hr; h2 {("Technical Skills")} ul { li { "Server side scripting and applications with a variety of tools and languages; Go, Rust, NodeJS, C#, PHP, Python, and more" } li { "Thorough knowledge of Linux server environment and web hosting environment configuration, skills relating to sysops/devops" } li { "Cloud service provision, management and deployment of applications to cloud platforms, CI/CD, Cloud orchestration using Kubernetes/Docker"} li { "Creating technical documentation"} li { "Relational database design"} li { "Modern game development practices; shader languages, engine design, optimisation for real-time rendering pipelines"} li { "Archaic game development practices; interfacing with systems on a hardware level, efficiency and optimisation for limited capacity"} li { "Digital electronics, microcontroller software, digital and analog circuit design and analysis" } li { "PCB design and fabrication"} } hr; h2 { "Referees" } p { "Referees can be provided upon inquiry."} div class="hide-on-print" { hr; p { "This document has been designed to be viewable in print and on the web."} } div class="hide-on-web" { hr; p { "This is a living document." br; "The latest version can be viewed on the web at " a href="https://darfk.net/resume/" { "https://darfk.net/resume/"} " ." } } ) } fn banner_links() -> Markup { html!(ul { // nothing here yet // li { a href="/about" {("about")} } li { a href="/" {("home")} } li { a href="/projects" {("projects")} } // li { a href="/notes" {("notes")} } li { a href="/resume" {("résumé")} } li { a href="/links" {("links")} } li { a href="ts3server:teamspeak.darfk.net" {("teamspeak")}} li { a href="https://mastodon.social/@daafuku" {("mastodon")}} }) } fn layout(title: Option<&str>, content: Markup) -> Markup { let year = chrono::Utc::now().year().to_string(); html!( (DOCTYPE) html { head { meta charset="utf-8"; meta name="viewport" content="width=device-width, initial-scale=1"; link rel="stylesheet" href="/main.css"; link rel="icon" href="/logo.svg"; title { ("darfk.net - Thomas Payne") @if let Some(title) = title { (" - ") (title) } } } body { div id="container" class="center" { header { div id="banner" { h1 { ("Thomas Payne") @if let Some(title) = title { (" - ") (title) } }} (banner_links()) } div id="content" { (content) } footer { ("© ") (year) (" - Thomas Payne") } } } } ) } #[derive(PartialEq, Eq)] enum PageType { Project, Other, } struct Page { path: String, title: String, description: String, markup: Markup, typ: PageType, } impl Page { fn new(path: &str, title: &str, description: &str, markup: Markup, typ: PageType) -> Self { Page { path: path.to_string(), title: title.to_string(), description: description.to_string(), markup: markup, typ: typ, } } } fn markup_from_markdown_file(path: &str) -> Markup { maud::PreEscaped(markdown::to_html(&fs::read_to_string(path).unwrap())) } fn main() { let mut static_resources = Vec::<&str>::new(); static_resources.push("main.css"); static_resources.push("robots.txt"); static_resources.push("logo.svg"); let mut pages = Vec::<Page>::new(); pages.push(Page::new( "index", "Home Page", "", layout(None, index()), PageType::Other, )); pages.push(Page::new( "/resume", "résumé", "résumé of Thomas Payne", layout(Some("résumé"), resume()), PageType::Other, )); pages.push(Page::new( "/projects/website", "This website", "How this website is made", layout(Some("This website"), projects_website()), PageType::Project, )); pages.push(Page::new( "/links", "Links", "Links which I recommend taking a look at", layout(Some("Links"), markup_from_markdown_file("pages/links.md")), PageType::Other, )); pages.push(Page::new( "/projects/coles", "Coles Barcode Generator", "Getting free parking at my local mall", layout( Some("Coles Barcode Generator"), markup_from_markdown_file("projects/coles-barcode.md"), ), PageType::Project, )); // pages.push(Page::new( // "/projects/saving-saving-ky", // "Saving 'Saving KY'", // "Finding a C64 SID track from a clip in a YouTube Video", // layout( // Some("Saving 'Saving KY'"), // markup_from_markdown_file("projects/saving-saving-ky.md"), // ), // PageType::Project, // )); pages.push(Page::new( "/projects", "Projects", "list of projects", layout(Some("Projects"), projects_index(&pages)), PageType::Other, )); pages.into_iter().for_each(|page| { let page_file_path_string = match page.path.as_str() { "index" => format!("output/index.html"), _ => format!("output/{}/index.html", page.path), }; let page_file_path = Path::new(page_file_path_string.as_str()); fs::create_dir_all(page_file_path.parent().unwrap()).unwrap(); fs::write(page_file_path, page.markup.into_string()).unwrap(); }); static_resources.into_iter().for_each(|static_resource| { fs::copy( format!("static/{}", static_resource), format!("output/{}", static_resource), ) .unwrap(); }) }