diff --git a/Cargo.lock b/Cargo.lock index c21579cf..b58b740d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.2" +version = "4.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a13b88d2c62ff462f88e4a121f17a82c1af05693a2f192b5c38d14de73c19f6" +checksum = "824956d0dca8334758a5b7f7e50518d66ea319330cbceedcf76905c2f6ab30e3" dependencies = [ "clap_builder", "clap_derive", @@ -282,9 +282,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.2" +version = "4.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb9faaa7c2ef94b2743a21f5a29e6f0010dff4caa69ac8e9d6cf8b6fa74da08" +checksum = "122ec64120a49b4563ccaedcbea7818d069ed8e9aa6d829b82d8a4128936b2ab" dependencies = [ "anstream", "anstyle", @@ -332,7 +332,7 @@ version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "482aa5695bca086022be453c700a40c02893f1ba7098a2c88351de55341ae894" dependencies = [ - "clap 4.4.2", + "clap 4.4.5", "entities", "memchr", "once_cell", @@ -398,7 +398,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.2", + "clap 4.4.5", "criterion-plot", "is-terminal", "itertools", @@ -969,17 +969,6 @@ dependencies = [ "hashbrown 0.14.0", ] -[[package]] -name = "io-lifetimes" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" -dependencies = [ - "hermit-abi 0.3.2", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "ipnet" version = "2.8.0" @@ -993,7 +982,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.11", + "rustix", "windows-sys 0.48.0", ] @@ -1048,12 +1037,6 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" -[[package]] -name = "linux-raw-sys" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" - [[package]] name = "linux-raw-sys" version = "0.4.5" @@ -1261,9 +1244,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.1.3+3.1.2" +version = "300.1.5+3.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd2c101a165fff9935e34def4669595ab1c7847943c42be86e21503e482be107" +checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" dependencies = [ "cc", ] @@ -1592,20 +1575,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.37.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d69718bf81c6127a49dc64e44a742e8bb9213c0ff8869a22c308f84c1d4ab06" -dependencies = [ - "bitflags 1.3.2", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", -] - [[package]] name = "rustix" version = "0.38.11" @@ -1615,7 +1584,7 @@ dependencies = [ "bitflags 2.4.0", "errno", "libc", - "linux-raw-sys 0.4.5", + "linux-raw-sys", "windows-sys 0.48.0", ] @@ -1706,9 +1675,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.106" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cc66a619ed80bf7a0f6b17dd063a84b88f6dea1813737cf469aef1d081142c2" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -1805,10 +1774,10 @@ dependencies = [ [[package]] name = "ssg" -version = "0.0.17" +version = "0.0.18" dependencies = [ "assert_cmd", - "clap 4.4.2", + "clap 4.4.5", "comrak", "criterion", "dtt", @@ -1886,7 +1855,7 @@ dependencies = [ "cfg-if", "fastrand", "redox_syscall", - "rustix 0.38.11", + "rustix", "windows-sys 0.48.0", ] @@ -1901,11 +1870,11 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237" +checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" dependencies = [ - "rustix 0.37.23", + "rustix", "windows-sys 0.48.0", ] @@ -2036,9 +2005,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.7.8" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +checksum = "1bc1433177506450fe920e46a4f9812d0c211f5dd556da10e731a0a3dfa151f0" dependencies = [ "serde", "serde_spanned", @@ -2057,9 +2026,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.19.15" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +checksum = "ca676d9ba1a322c1b64eb8045a5ec5c0cfb0c9d08e15e9ff622589ad5221c8fe" dependencies = [ "indexmap 2.0.0", "serde", diff --git a/Cargo.toml b/Cargo.toml index 847dcf46..a68da76f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ name = "ssg" readme = "README.md" repository = "https://github.com/sebastienrousseau/shokunin" rust-version = "1.71.1" -version = "0.0.17" +version = "0.0.18" include = [ "/CONTRIBUTING.md", "/LICENSE-APACHE", @@ -46,7 +46,7 @@ harness = false path = "benches/bench.rs" [dependencies] -clap = "4.4.2" +clap = "4.4.5" comrak = "0.18.0" dtt = "0.0.4" log = {version="0.4.20", features = ["std"] } @@ -56,10 +56,10 @@ quick-xml = "0.30.0" regex = "1.9.5" reqwest = { version = "0.11.20", features = ["blocking", "json"] } serde = { version = "1.0.188", features = ["derive"] } -serde_json = "1.0.106" +serde_json = "1.0.107" serde_yaml = "0.9.25" tempfile = "3.8.0" -toml = "0.7.8" +toml = "0.8.1" yaml-rust = "0.4.5" vrd = "0.0.4" diff --git a/README.md b/README.md index aac88079..34d4aaf7 100644 --- a/README.md +++ b/README.md @@ -181,7 +181,7 @@ To use the Shokunin Static Site Generator (SSG) library in your project, add the ```toml [dependencies] -shokunin = "0.0.17" +shokunin = "0.0.18" ``` Add the following to your `main.rs` file: @@ -282,6 +282,6 @@ A special thank you goes to the [Rust Reddit][13] community for providing a lot [crates-badge]: https://img.shields.io/crates/v/ssg.svg?style=for-the-badge 'Crates.io badge' [divider]: https://kura.pro/common/images/elements/divider.svg "divider" [docs-badge]: https://img.shields.io/docsrs/ssg.svg?style=for-the-badge 'Docs.rs badge' -[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.17-orange.svg?style=for-the-badge 'Lib.rs badge' +[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.18-orange.svg?style=for-the-badge 'Lib.rs badge' [license-badge]: https://img.shields.io/crates/l/ssg.svg?style=for-the-badge 'License badge' [made-with-rust-badge]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust badge' diff --git a/TEMPLATE.md b/TEMPLATE.md index 831a2350..4ab1c1a2 100644 --- a/TEMPLATE.md +++ b/TEMPLATE.md @@ -10,7 +10,7 @@ -# Shokunin Static Site Generator v0.0.17 🦀 +# Shokunin Static Site Generator v0.0.18 🦀 A Content-First Open Source Static Site Generator (SSG) written in Rust @@ -70,7 +70,7 @@ Shokunin Static Site Generator (SSG) feature highlights include: [crates-badge]: https://img.shields.io/crates/v/ssg.svg?style=for-the-badge 'Crates.io badge' [divider]: https://kura.pro/common/images/elements/divider.svg "divider" [docs-badge]: https://img.shields.io/docsrs/ssg.svg?style=for-the-badge 'Docs.rs badge' -[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.17-orange.svg?style=for-the-badge 'Lib.rs badge' +[libs-badge]: https://img.shields.io/badge/lib.rs-v0.0.18-orange.svg?style=for-the-badge 'Lib.rs badge' [license-badge]: https://img.shields.io/crates/l/ssg.svg?style=for-the-badge 'License badge' [made-with-rust-badge]: https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust 'Made With Rust badge' diff --git a/content/404.md b/content/404.md index 972e41ff..5f42156b 100644 --- a/content/404.md +++ b/content/404.md @@ -8,6 +8,7 @@ banner_height: "398" banner_width: "1440" banner: "https://kura.pro/unsplash/images/banners/ash-from-modern-afflatus-NQ6Lh81BTRs-unsplash.jpg" cdn: "https://kura.pro" +changefreq: "weekly" charset: "utf-8" cname: "kaishi.one" copyright: "© 2023 Kaishi. All rights reserved." @@ -38,7 +39,7 @@ revisit-after: "7 days" robots: "index, follow" short_name: "404" subtitle: "Sorry we can't find that page." -theme_color: "rgb(143, 250, 111)" +theme-color: "rgb(143, 250, 111)" tags: "404, page not found, not available" title: "404" url: "https://kaishi.one/404/" diff --git a/content/contact.md b/content/contact.md index f4b064c1..47bde5b2 100644 --- a/content/contact.md +++ b/content/contact.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/vishal-bansal-SC5sXeyjloE-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -40,7 +41,7 @@ robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "How can we help you today?" ## The subtitle of the page. (max 64 characters) tags: "contact us, contact form, get in touch, contact page, contact information, customer service, support, feedback, questions, inquiries, help" ## The tags of the site. (max 160 characters) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. title: "Contact Us" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. diff --git a/content/features.md b/content/features.md index f98299fc..cedc6d05 100644 --- a/content/features.md +++ b/content/features.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/ryunosuke-kikuno-G5hYMUoJQf8-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -24,7 +25,7 @@ image_width: "1200" ## The image width of the site. image: "https://kura.pro/kaishi/images/banners/banner-kaishi.webp" ## The main image of the site in SVG format. keywords: "kaishi starter templates, shokunin static site generator, static site generator, starter templates, bootstrap, bootstrap css, bootstrap javascript, content security policy, open graph meta tags, responsive navigation bar, schema.org meta tags" ## The keywords of the site. (max 160 characters) language: "en-GB" ## The language of the site. (default: en-GB) -layout: "page" ## The layout of the site. +layout: "post" ## The layout of the site. locale: "en_GB" ## The locale of the site. logo_alt: "Logo of Kaishi, a starter template for static sites" ## The logo alt of the site. logo_height: "33" ## The logo height of the site. @@ -39,7 +40,7 @@ robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) tags: "kaishi starter templates, shokunin static site generator, static site generator, starter templates, bootstrap, bootstrap css, bootstrap javascript, content security policy, open graph meta tags, responsive navigation bar, schema.org meta tags" ## The tags of the site. (max 160 characters) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. title: "Features" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. @@ -105,6 +106,7 @@ site_software: "Shokunin, Rust" ## The software of the site. --- + ## Starter Templates All the starter templates, whether pages or websites are built from scratch @@ -116,13 +118,37 @@ your website or web application. **Kaishi Starter Templates** has the following features enabled: + +
+
+
+
+ + - **Accessibility Meta-Tags:** These meta tags are designed to make the website more accessible to users with disabilities. By setting Accessible Rich Internet Applications (ARIA) roles and attributes, full keyboard control, and no flashing hazard, you can make sure your website is accessible to everyone. - **Apple Meta-Tags:** These meta tags improve websites for Apple devices, like iPhones, iPads, and Apple devices. You can change web app capabilities, status bar style, title, application name, and author to improve Apple devices' appearance. - **Bootstrap CSS:** Bootstrap is a popular CSS framework that provides you with a set of pre-designed styles and components. By using Bootstrap, you can quickly and easily create a professional-looking website without having to write CSS from scratch. - **Bootstrap JavaScript:** Bootstrap JavaScript is a set of pre-built scripts that provide you with responsive navigation menus and modal dialogues. + +
+
+
+ +
+
+
+ + - **Content Security Policy:** This meta tag is used to specify the sources of content allowed to load on the page. It is designed to prevent cross-site scripting (XSS) attacks and other security vulnerabilities. - **Microsoft Meta Tags:** These meta tags are designed to optimise the website for Microsoft devices. You can set site verification, application configuration, tap highlight colour, tile colour, and tile image to look good on Windows devices. - **Open Graph/Facebook Meta-Tags:** These meta tags allow you to control how your website appears when shared on Facebook and other social media platforms. By setting the title, description, and image, you can make sure that your website looks its best when shared online. - **Responsive Navigation Bar:** The responsive navigation bar provides users with an intuitive and easy-to-use interface for navigating the website. It aims to adapt to the size of the screen, making it accessible to users on both desktop and mobile devices. - **Schema.org Meta Tags:** These meta tags are used to provide structured data about the website's content. Setting the name, description, and image on a website helps search engines and others understand the content better. - **Twitter Meta Tags:** These meta tags are designed to optimise the website for Twitter sharing. You can set the card type, creator, description, image, site, title, and URL to make their website look good on Twitter. + + +
+
+
+
+ \ No newline at end of file diff --git a/content/index.md b/content/index.md index 0be96b29..539c1c0d 100644 --- a/content/index.md +++ b/content/index.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/bernardo-lorena-ponte-cEp2Tow6XKk-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -38,7 +39,7 @@ revisit-after: "7 days" ## The revisit after of the site. robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. tags: "kaishi, shokunin static site generator, static site generator, minimalist website template, modern website template, responsive website template, website starter template, freelance creative, startup founder, small business owner, online presence" ## The tags of the site. (comma separated, max 10 tags) title: "Kaishi, a Shokunin Static Site Generator Starter Template" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. diff --git a/content/offline.md b/content/offline.md index c5325953..4a2dae4e 100644 --- a/content/offline.md +++ b/content/offline.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/tianyi-ma-WiONHd_zYI4-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -39,7 +40,7 @@ robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) tags: "offline, starter, templates, static, site, generator, rust, shokunin, kaishi" ## The tags of the site. (comma separated, max 10 tags) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. title: "Kaishi, a Shokunin Static Site Generator Starter Template" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. diff --git a/content/post.md b/content/post.md new file mode 100644 index 00000000..a27c6ab6 --- /dev/null +++ b/content/post.md @@ -0,0 +1,126 @@ +--- + +# Front Matter (YAML) + +author: "Jane Doe" ## The author of the page. (max 64 characters) +banner_alt: "Green And Black Tiled Wall" ## The banner alt of the site. +banner_height: "398" ## The banner height of the site. +banner_width: "1440" ## The banner width of the site. +banner: "https://kura.pro/unsplash/images/banners/ryunosuke-kikuno-G5hYMUoJQf8-unsplash.jpg" ## The banner of the site. +cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. +charset: "utf-8" ## The charset of the site. (default: utf-8) +cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) +copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. +date: "July 12, 2023" +description: "Everything You Need to Build a Stunning Website." ## The description of the site. (max 160 characters) +download: "" ## The download url for the product. +format-detection: "telephone=no" ## The format detection of the site. +hreflang: "en" ## The hreflang of the site. (default: en-gb) +icon: "https://kura.pro/kaishi/images/logos/kaishi.svg" ## The icon of the site in SVG format. +id: "https://kaishi.one" ## The id of the site. +image_alt: "Logo of Kaishi, a starter template for static sites" ## The image alt of the site. +image_height: "630" ## The image height of the site. +image_width: "1200" ## The image width of the site. +image: "https://kura.pro/kaishi/images/banners/banner-kaishi.webp" ## The main image of the site in SVG format. +keywords: "kaishi starter templates, shokunin static site generator, static site generator, starter templates, bootstrap, bootstrap css, bootstrap javascript, content security policy, open graph meta tags, responsive navigation bar, schema.org meta tags" ## The keywords of the site. (max 160 characters) +language: "en-GB" ## The language of the site. (default: en-GB) +layout: "post" ## The layout of the site. +locale: "en_GB" ## The locale of the site. +logo_alt: "Logo of Kaishi, a starter template for static sites" ## The logo alt of the site. +logo_height: "33" ## The logo height of the site. +logo_width: "100" ## The logo width of the site. +logo: "https://kura.pro/kaishi/images/banners/banner-kaishi.webp" ## The logo of the site in SVG format. +name: "Kaishi" ## The name of the website. (max 64 characters) +permalink: "https://kaishi.one/features" ## The url of the site. +rating: "general" ## The rating of the site. +referrer: "no-referrer" ## The referrer of the site. +revisit-after: "7 days" ## The revisit after of the site. +robots: "index, follow" ## The robots of the site. +short_name: "kaishi" ## The short name of the site. (max 12 characters) +subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) +tags: "kaishi starter templates, shokunin static site generator, static site generator, starter templates, bootstrap, bootstrap css, bootstrap javascript, content security policy, open graph meta tags, responsive navigation bar, schema.org meta tags" ## The tags of the site. (max 160 characters) +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. +title: "Features" ## The title of the page. (max 64 characters) +url: "https://kaishi.one" ## The url of the site. +viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. + +# RSS - The RSS feed front matter (YAML). +atom_link: https://kaishi.one/rss.xml +category: "Technology" +docs: https://validator.w3.org/feed/docs/rss2.html +generator: "Shokunin 🦀 (version 0.0.17)" +item_description: RSS feed for the site +item_guid: https://kaishi.one/rss.xml +item_link: https://kaishi.one/rss.xml +item_pub_date: "Thu, 12 Jul 2023 15:15:15 GMT" +item_title: "RSS" +last_build_date: "Thu, 12 Jul 2023 15:15:15 GMT" +managing_editor: jane.doe@kaishi.one +pub_date: "Thu, 12 Jul 2023 15:15:15 GMT" +ttl: "60" +type: "website" +webmaster: jane.doe@kaishi.one + +# Apple - The Apple front matter (YAML). +apple_mobile_web_app_orientations: "portrait" ## The Apple mobile web app orientations of the page. +apple_touch_icon_sizes: "192x192" ## The Apple touch icon sizes of the page. +apple-mobile-web-app-capable: "yes" ## The Apple mobile web app capable of the page. +apple-mobile-web-app-status-bar-inset: "black" ## The Apple mobile web app status bar inset of the page. +apple-mobile-web-app-status-bar-style: "black-translucent" ## The Apple mobile web app status bar style of the page. +apple-mobile-web-app-title: "Kaishi" ## The Apple mobile web app title of the page. +apple-touch-fullscreen: "yes" ## The Apple touch fullscreen of the page. + +# MS Application - The MS Application front matter (YAML). + +msapplication-navbutton-color: "rgb(143, 250, 111)" + +# Twitter Card - The Twitter Card front matter (YAML). + +## twitter_card - The Twitter Card type of the page. +twitter_card: "summary" +## twitter_creator - The Twitter Card creator of the page. +twitter_creator: "janedoe" +## twitter_description - The Twitter Card description of the page. +twitter_description: "Everything You Need to Build a Stunning Website." +## twitter_image - The Twitter Card image of the page. +twitter_image: "https://kura.pro/kaishi/images/logos/kaishi.svg" +## twitter_image:alt - The Twitter Card image alt of the page. +twitter_image_alt: "Logo of Kaishi, a starter template for static sites" +## twitter_site - The Twitter Card site of the page. +twitter_site: "janedoe" +## twitter_title - The Twitter Card title of the page. +twitter_title: "Kaishi, a Shokunin Static Site Generator Starter Template" +## twitter_url - The Twitter Card url of the page. +twitter_url: "https://kaishi.one" + +# Humans.txt - The Humans.txt front matter (YAML). +author_website: "https://kura.pro" ## The author website of the page. +author_twitter: "@wwdseb" ## The author twitter of the page. +author_location: "London, UK" ## The author location of the page. +thanks: "Thanks for reading!" ## The thanks of the page. +site_last_updated: "2023-07-05" ## The last updated of the site. +site_standards: "HTML5, CSS3, RSS, Atom, JSON, XML, YAML, Markdown, TOML" ## The standards of the site. +site_components: "Kaishi, Kaishi Builder, Kaishi CLI, Kaishi Templates, Kaishi Themes" ## The components of the site. +site_software: "Shokunin, Rust" ## The software of the site. + +--- + +![A very tall building that has a lot of holes in it](https://kura.pro/stock/images/banners/johannes-plenio-6XUA5KQ9-1k.webp).class=\"img-fluid clearfix\" + +## Starter Templates + +

+ by + +

+

+ +All the starter templates, whether pages or websites are built from scratch +using the same principles and features. This means that you can easily mix and +match them together to create your own custom layouts and content. + +Get started with Shokunin using any of our Starter Templates for building +your website or web application. diff --git a/content/privacy.md b/content/privacy.md index cf7a769c..56ca4c04 100644 --- a/content/privacy.md +++ b/content/privacy.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/johannes-plenio-6XUA5KQ9-1k-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -39,7 +40,7 @@ robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) tags: "privacy policy, kaishi, shokunin static site generator, static site generator, user data, google analytics, microsoft clarity, tracking tools, personal information, rights, changes" ## The tags of the site. (max 160 characters) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. title: "Kaishi, a Shokunin Static Site Generator Starter Template" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. diff --git a/content/tags.md b/content/tags.md index 8d98eab8..04f40ea8 100644 --- a/content/tags.md +++ b/content/tags.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/sean-stratton-ObpCE_X3j6U-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -39,7 +40,7 @@ robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) tags: "terms of use, kaishi, shokunin static site generator, static site generator, intellectual property, linked sites, liability, privacy, governing law, changes, contact us" ## The tags of the site. (max 160 characters) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. title: "Explore by tag" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. diff --git a/content/terms.md b/content/terms.md index ea30ce25..33655338 100644 --- a/content/terms.md +++ b/content/terms.md @@ -8,6 +8,7 @@ banner_height: "398" ## The banner height of the site. banner_width: "1440" ## The banner width of the site. banner: "https://kura.pro/unsplash/images/banners/sean-stratton-ObpCE_X3j6U-unsplash.jpg" ## The banner of the site. cdn: "https://kura.pro" ## The CDN of the site. +changefreq: "weekly" ## The changefreq of the site. charset: "utf-8" ## The charset of the site. (default: utf-8) cname: "kaishi.one" ## The cname value of the site. (Only required for the index page.) copyright: "© 2023 Kaishi. All rights reserved." ## The copyright of the site. @@ -39,7 +40,7 @@ robots: "index, follow" ## The robots of the site. short_name: "kaishi" ## The short name of the site. (max 12 characters) subtitle: "Build Amazing Websites with Minimal Effort using Kaishi Starter Templates" ## The subtitle of the page. (max 64 characters) tags: "terms of use, kaishi, shokunin static site generator, static site generator, intellectual property, linked sites, liability, privacy, governing law, changes, contact us" ## The tags of the site. (max 160 characters) -theme_color: "rgb(143, 250, 111)" ## The theme color of the site. +theme-color: "rgb(143, 250, 111)" ## The theme color of the site. title: "Terms of Use" ## The title of the page. (max 64 characters) url: "https://kaishi.one" ## The url of the site. viewport: "width=device-width, initial-scale=1, shrink-to-fit=no" ## The viewport of the site. diff --git a/src/compiler.rs b/src/compiler.rs index a87d87d2..22517f3e 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -21,7 +21,7 @@ use crate::{ utilities::{ file::add, template::{render_page, PageOptions}, - write::write_files + write::write_files_to_build_directory }, }; use std::{error::Error, fs, path::Path, collections::HashMap}; @@ -286,7 +286,7 @@ pub fn compile( // Iterate over compiled files and write pages to output directory for file in &compiled_files { - write_files(build_dir_path, file, template_path)?; + write_files_to_build_directory(build_dir_path, file, template_path)?; } let tags_html_content = generate_tags_html(&global_tags_data); diff --git a/src/lib.rs b/src/lib.rs index 20c6a60e..cf159fd2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,7 +10,7 @@ //! *Part of the [Mini Functions][0] family of Rust libraries.* //! //! [![Crates.io](https://img.shields.io/crates/v/ssg.svg?style=for-the-badge&color=success&labelColor=27A006)](https://crates.io/crates/ssg "Crates.io") -//! [![Lib.rs](https://img.shields.io/badge/lib.rs-v0.0.17-success.svg?style=for-the-badge&color=8A48FF&labelColor=6F36E4)](https://lib.rs/crates/ssg "Lib.rs") +//! [![Lib.rs](https://img.shields.io/badge/lib.rs-v0.0.18-success.svg?style=for-the-badge&color=8A48FF&labelColor=6F36E4)](https://lib.rs/crates/ssg "Lib.rs") //! [![License](https://img.shields.io/crates/l/ssg.svg?style=for-the-badge&color=007EC6&labelColor=03589B)](https://opensource.org/license/apache-2-0/ "MIT or Apache License, Version 2.0") //! [![Rust](https://img.shields.io/badge/rust-f04041?style=for-the-badge&labelColor=c0282d&logo=rust)](https://www.rust-lang.org "Rust") //! @@ -66,7 +66,7 @@ //! //! ```toml //! [dependencies] -//! shokunin = "0.0.17" +//! shokunin = "0.0.18" //! ``` //! //! And in your `main.rs`: diff --git a/src/macros.rs b/src/macros.rs index 88680944..5413a030 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -287,23 +287,51 @@ macro_rules! macro_metadata_option { /// # `macro_render_layout` Macro /// -/// Selects the appropriate template for rendering based on the specified layout, -/// and uses this template to render a context into a string. +/// This macro selects and renders a specified layout with a given context. +/// +/// * `$layout`: The desired layout name (e.g., "contact", "index", "page"). +/// If a template file corresponding to `$layout.html` exists in the template directory, +/// it will be used. Otherwise, the macro falls back to predefined mappings. +/// +/// * `$template_path`: The path to the directory containing the template files. +/// +/// * `$context`: The context to be rendered into the template. +/// +/// ## Behaviour: +/// +/// 1. If a file named `$layout.html` exists in `$template_path`, it will be used as the template. +/// 2. If no such file exists, the macro checks for predefined layout names: +/// * "contact" maps to "contact.html" +/// * "index" maps to "index.html" +/// * "page" maps to "page.html" +/// 3. If `$layout` is unrecognized and doesn't correspond to a file in the template directory, +/// the macro defaults to using "index.html". +/// +/// ## Returns: +/// +/// The macro returns a rendered string using the selected template and provided context. /// #[macro_export] macro_rules! macro_render_layout { ($layout:expr, $template_path:expr, $context:expr) => {{ let layout_str: &str = &$layout; - let template_file = match layout_str { - "contact" => "contact.html", - "index" => "index.html", - "page" => "page.html", - _ => "index.html", + // Check if a file with the name of the layout exists in the template directory + let file_path = Path::new($template_path).join(format!("{}.html", layout_str)); + let template_file = if file_path.exists() { + format!("{}.html", layout_str) + } else { + match layout_str { + "contact" => "contact.html", + "index" => "index.html", + "page" => "page.html", + "post" => "post.html", + _ => "index.html", + }.to_string() }; let template_content = fs::read_to_string( - Path::new($template_path).join(template_file), + Path::new($template_path).join(&template_file), ) .unwrap(); render_template(&template_content, &$context) diff --git a/src/modules/cname.rs b/src/modules/cname.rs index 533c5668..48454d61 100644 --- a/src/modules/cname.rs +++ b/src/modules/cname.rs @@ -1,13 +1,38 @@ // Copyright © 2023 Shokunin Static Site Generator. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT +// Import the CnameData model from the `crate::models::data` module. use crate::models::data::CnameData; + +// Import the HashMap collection from the `std::collections` module. use std::collections::HashMap; -/// Function to create CnameData +/// Function to create a CnameData object from a HashMap of metadata. +/// +/// The `metadata` HashMap must contain a key named `cname` with the value +/// of the CNAME record. +/// +/// Returns a CnameData object with the CNAME record value. +/// +/// The `cname` value is the canonical name of the domain or subdomain. It is +/// the "true" name of the domain or subdomain, and it is what other DNS +/// records point to. For example, the `cname` value for the `www.example.com` +/// subdomain is typically `example.com`. +/// +/// The `cname` value is used to create aliases for domains and subdomains. +/// This can be useful for a variety of reasons, such as: +/// +/// * To make it easier for users to remember the domain name or subdomain. +/// * To distribute traffic across multiple servers. +/// * To use a domain name or subdomain with a service provider that does not +/// allow you to create your own DNS records. pub fn create_cname_data(metadata: &HashMap) -> CnameData { + // Get the value of the `cname` key from the `metadata` HashMap. + let cname = metadata.get("cname").cloned().unwrap_or_default(); + + // Create a new CnameData object with the CNAME record value. CnameData { - cname: metadata.get("cname").cloned().unwrap_or_default(), + cname, } } diff --git a/src/modules/html.rs b/src/modules/html.rs index 31a85193..c9e92dd5 100644 --- a/src/modules/html.rs +++ b/src/modules/html.rs @@ -41,7 +41,7 @@ use crate::utilities::directory::{ /// let html = generate_html(content, title, description, None); /// let html_str = html.unwrap_or_else(|e| panic!("Error: {:?}", e)); /// -/// assert_eq!(html_str, "

My Page

This is a test page

Hello, world!

\n

This is a test.

\n"); +/// assert_eq!(html_str, "

My Page

This is a test page

Hello, world!

\n

This is a test.

\n"); /// /// ``` // @@ -126,7 +126,7 @@ fn generate_header(title: &str, id_regex: &Regex) -> String { if title.is_empty() { return String::new(); } - let header_str = format!("

{}

", title); + let header_str = format!("

{}

", title); format_header_with_id_class(&header_str, id_regex) } diff --git a/src/modules/human.rs b/src/modules/human.rs index 2a74f809..9a40bcc3 100644 --- a/src/modules/human.rs +++ b/src/modules/human.rs @@ -1,21 +1,38 @@ // Copyright © 2023 Shokunin Static Site Generator. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT +// Import the HumansData struct from the data module. use crate::models::data::HumansData; + +// Import the HashMap struct from the collections module. use std::collections::HashMap; -/// Function to create HumansData +/// Function to create a HumansData object from a HashMap of metadata. +/// +/// The `metadata` HashMap must contain the following keys: +/// +/// * `author_location`: The location of the author. +/// * `author_twitter`: The Twitter handle of the author. +/// * `author_website`: The website of the author. +/// * `author`: The name of the author of the website or blog. +/// * `site_components`: The components that the website or blog uses. +/// * `site_last_updated`: The date on which the website or blog was last updated. +/// * `site_software`: The software that the website or blog uses. +/// * `site_standards`: The standards that the website or blog follows. +/// * `thanks`: A list of people or organizations to thank for their contributions to the website or blog. +/// +/// Returns a HumansData object with the metadata. pub fn create_human_data(metadata: &HashMap) -> HumansData { HumansData { - author: metadata.get("author").cloned().unwrap_or_default(), - author_website: metadata.get("author_website").cloned().unwrap_or_default(), - author_twitter: metadata.get("author_twitter").cloned().unwrap_or_default(), author_location: metadata.get("author_location").cloned().unwrap_or_default(), - thanks: metadata.get("thanks").cloned().unwrap_or_default(), - site_last_updated: metadata.get("site_last_updated").cloned().unwrap_or_default(), - site_standards: metadata.get("site_standards").cloned().unwrap_or_default(), + author_twitter: metadata.get("author_twitter").cloned().unwrap_or_default(), + author_website: metadata.get("author_website").cloned().unwrap_or_default(), + author: metadata.get("author").cloned().unwrap_or_default(), site_components: metadata.get("site_components").cloned().unwrap_or_default(), + site_last_updated: metadata.get("site_last_updated").cloned().unwrap_or_default(), site_software: metadata.get("site_software").cloned().unwrap_or_default(), + site_standards: metadata.get("site_standards").cloned().unwrap_or_default(), + thanks: metadata.get("thanks").cloned().unwrap_or_default(), } } diff --git a/src/modules/json.rs b/src/modules/json.rs index e4dfd03c..b3ebb714 100644 --- a/src/modules/json.rs +++ b/src/modules/json.rs @@ -13,19 +13,26 @@ use crate::models::data::{ }; /// ## Function: `manifest` - Generate a JSON manifest for a web app +/// +/// The `ManifestData` object contains the following fields: +/// +/// * `background_color`: The background color of the web app. +/// * `description`: The description of the web app. +/// * `display`: The display mode of the web app. +/// * `icons`: A list of icons for the web app. +/// * `name`: The name of the web app. +/// * `orientation`: The orientation of the web app. +/// * `scope`: The scope of the web app. +/// * `short_name`: The short name of the web app. +/// * `start_url`: The start URL of the web app. +/// * `theme_color`: The theme color of the web app. +/// +/// Returns a JSON string containing the manifest. pub fn manifest(options: &ManifestData) -> String { let mut json_map = Map::new(); - json_map.insert("name".to_string(), json!(options.name)); - json_map - .insert("short_name".to_string(), json!(options.short_name)); - json_map.insert("start_url".to_string(), json!(options.start_url)); + json_map.insert("background_color".to_string(),json!(options.background_color),); + json_map.insert("description".to_string(), json!(options.description)); json_map.insert("display".to_string(), json!(options.display)); - json_map.insert( - "background_color".to_string(), - json!(options.background_color), - ); - json_map - .insert("description".to_string(), json!(options.description)); let mut icons_vec = vec![]; for icon in &options.icons { @@ -41,17 +48,23 @@ pub fn manifest(options: &ManifestData) -> String { icons_vec.push(json!(icon_map)); } json_map.insert("icons".to_string(), json!(icons_vec)); - - json_map - .insert("orientation".to_string(), json!(options.orientation)); + json_map.insert("name".to_string(), json!(options.name)); + json_map.insert("orientation".to_string(), json!(options.orientation)); json_map.insert("scope".to_string(), json!(options.scope)); - json_map - .insert("theme_color".to_string(), json!(options.theme_color)); + json_map.insert("short_name".to_string(), json!(options.short_name)); + json_map.insert("start_url".to_string(), json!(options.start_url)); + json_map.insert("theme_color".to_string(), json!(options.theme_color)); serde_json::to_string_pretty(&json_map).unwrap() } /// ## Function: `txt` - Generate a robots.txt for a web app +/// +/// The `TxtData` object contains the following fields: +/// +/// * `permalink`: The permalink of the web app. +/// +/// Returns a string containing the robots.txt file. pub fn txt(options: &TxtData) -> String { let permalink = options.permalink.clone(); let url = format!("{}/sitemap.xml", permalink); @@ -59,6 +72,12 @@ pub fn txt(options: &TxtData) -> String { } /// ## Function: `cname` - Generate a CNAME for a web app +/// +/// The `CnameData` object contains the following fields: +/// +/// * `cname`: The CNAME value of the web app. +/// +/// Returns a string containing the CNAME file. pub fn cname(options: &CnameData) -> String { let cname_value = options.cname.clone(); let full_domain = format!("www.{}", cname_value); @@ -67,6 +86,20 @@ pub fn cname(options: &CnameData) -> String { } /// ## Function: `human` - Generate a humans.txt for a web app +/// +/// The `HumansData` object contains the following fields: +/// +/// * `author_location`: The location of the author. +/// * `author_twitter`: The Twitter handle of the author. +/// * `author_website`: The website of the author. +/// * `author`: The author of the web app. +/// * `site_components`: The components that the web app uses. +/// * `site_last_updated`: The date on which the web app was last updated. +/// * `site_software`: The software that the web app uses. +/// * `site_standards`: The standards that the web app follows. +/// * `thanks`: A list of people or organizations to thank for their contributions to the web app. +/// +/// Returns a string containing the humans.txt file. pub fn human(options: &HumansData) -> String { let mut s = String::from("/* TEAM */\n"); @@ -109,13 +142,24 @@ pub fn human(options: &HumansData) -> String { } /// ## Function: `sitemap` - Generate a sitemap for a web app +/// +/// The `SiteMapData` object contains the following fields: +/// +/// * `changefreq`: The change frequency of the web app. +/// * `lastmod`: The last modified date of the web app. +/// * `loc`: The base URL of the web app. +/// +/// The `dir` parameter is the directory containing the web app. +/// +/// Returns a string containing the sitemap.xml file. pub fn sitemap(options: SiteMapData, dir: &Path) -> String { + let lastmod = options.lastmod.clone(); let changefreq = options.changefreq.clone(); let base_url = options.loc.clone(); let base_dir = PathBuf::from(dir); let mut urls = vec![]; - visit_dirs(&base_dir, &base_dir, &base_url, &changefreq, &mut urls) + visit_dirs(&base_dir, &base_dir, &base_url, &changefreq, &lastmod, &mut urls) .unwrap(); let urls_str = urls.join("\n"); @@ -126,11 +170,27 @@ pub fn sitemap(options: SiteMapData, dir: &Path) -> String { ) } -fn visit_dirs( +/// ## Function: `visit_dirs` - Recursively visit all directories in a tree and add the URLs of all index.html files to the `urls` vector. +/// +/// The `base_dir` parameter is the root directory of the tree. +/// +/// The `dir` parameter is the current directory being visited. +/// +/// The `base_url` parameter is the base URL of the website. +/// +/// The `changefreq` parameter is the change frequency of the website. +/// +/// The `lastmod` parameter is the last modified date of the website. +/// +/// The `urls` parameter is a vector of URLs that will be populated by the function. +/// +/// Returns a `std::io::Result` value. +pub fn visit_dirs( base_dir: &Path, dir: &Path, base_url: &str, changefreq: &str, + lastmod: &str, urls: &mut Vec, ) -> std::io::Result<()> { if dir.is_dir() { @@ -139,7 +199,7 @@ fn visit_dirs( let path = entry.path(); if path.is_dir() { visit_dirs( - base_dir, &path, base_url, changefreq, urls, + base_dir, &path, base_url, changefreq, lastmod, urls, )?; } else if path.file_name().unwrap() == "index.html" { let url = path @@ -149,12 +209,8 @@ fn visit_dirs( .unwrap() .replace("'\\'", "/"); urls.push(format!( - r#" - - {}/{} - {} - "#, - base_url, url, changefreq + r#"{}{}{}/{}"#, + changefreq, lastmod, base_url, url )); } } diff --git a/src/modules/manifest.rs b/src/modules/manifest.rs index d469ef69..7c147b32 100644 --- a/src/modules/manifest.rs +++ b/src/modules/manifest.rs @@ -5,6 +5,10 @@ use crate::{models::data::{IconData, ManifestData}, macro_metadata_option}; use std::collections::HashMap; /// Function to create ManifestData +/// +/// The `metadata` parameter is a map of metadata strings. +/// +/// Returns a `ManifestData` object. pub fn create_manifest_data(metadata: &HashMap) -> ManifestData { ManifestData { name: metadata.get("name").cloned().unwrap_or_default(), @@ -25,7 +29,7 @@ pub fn create_manifest_data(metadata: &HashMap) -> ManifestData .unwrap_or_else(Vec::new), orientation: "portrait-primary".to_string(), scope: "/".to_string(), - theme_color: macro_metadata_option!(metadata, "theme_color"), + theme_color: macro_metadata_option!(metadata, "theme-color"), } } diff --git a/src/modules/metatags.rs b/src/modules/metatags.rs index 2ba3d5ab..7a45f8af 100644 --- a/src/modules/metatags.rs +++ b/src/modules/metatags.rs @@ -96,7 +96,7 @@ pub fn generate_primary_meta_tags(metadata: &MetaDataMap) -> String { let tag_names = [ "author", "description", "format-detection", "generator", "keywords", "language", "permalink", "rating", "referrer", "revisit-after", - "robots", "theme_color", "title", "viewport", + "robots", "theme-color", "title", "viewport", ]; macro_generate_tags_from_list!(&tag_names, metadata) } diff --git a/src/modules/sitemap.rs b/src/modules/sitemap.rs index 75af1d1d..bb238f34 100644 --- a/src/modules/sitemap.rs +++ b/src/modules/sitemap.rs @@ -1,15 +1,26 @@ // Copyright © 2023 Shokunin Static Site Generator. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT +// Import models::data::SiteMapData use crate::models::data::SiteMapData; + +// Import std::collections::HashMap use std::collections::HashMap; /// Function to create SiteMapData +/// +/// The `metadata` parameter is a map of metadata strings. +/// +/// Returns a `SiteMapData` object. pub fn create_site_map_data(metadata: &HashMap) -> SiteMapData { SiteMapData { - loc: metadata.get("permalink").cloned().unwrap_or_default(), + /// The change frequency of the website. + changefreq: metadata.get("changefreq").cloned().unwrap_or_default(), + + /// The last modified date of the website. lastmod: metadata.get("last_build_date").cloned().unwrap_or_default(), - changefreq: metadata.get("weekly").cloned().unwrap_or_default(), + + /// The base URL of the website. + loc: metadata.get("permalink").cloned().unwrap_or_default(), } } - diff --git a/src/modules/txt.rs b/src/modules/txt.rs index 5397170f..7830ecec 100644 --- a/src/modules/txt.rs +++ b/src/modules/txt.rs @@ -1,10 +1,17 @@ // Copyright © 2023 Shokunin Static Site Generator. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT +// Import models::data::TxtData use crate::models::data::TxtData; + +// Import std::collections::HashMap use std::collections::HashMap; /// Function to create TxtData +/// +/// The `metadata` parameter is a map of metadata strings. +/// +/// Returns a `TxtData` object. pub fn create_txt_data(metadata: &HashMap) -> TxtData { TxtData { permalink: metadata.get("permalink").cloned().unwrap_or_default(), diff --git a/src/term/cli.rs b/src/term/cli.rs index 9593fae0..3bab47ba 100644 --- a/src/term/cli.rs +++ b/src/term/cli.rs @@ -44,7 +44,7 @@ pub fn build() -> Result { .author("Sebastien Rousseau") .about("") .bin_name("ssg") - .version("0.0.17") + .version("0.0.18") .arg( Arg::new("new") .help("Create a new project.") @@ -109,7 +109,7 @@ pub fn build() -> Result { /// ``` pub fn print_banner() { // Set the title and description for the CLI - let title = "Shokunin 🦀 (v0.0.17)"; + let title = "Shokunin 🦀 (v0.0.18)"; let description = "A Fast and Flexible Static Site Generator written in Rust"; diff --git a/src/utilities/backup.rs b/src/utilities/backup.rs index 75d30508..8bbd75de 100644 --- a/src/utilities/backup.rs +++ b/src/utilities/backup.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 OR MIT extern crate regex; -// use minify_html::{minify, Cfg}; use std::{ fs::{self}, io::{self}, diff --git a/src/utilities/directory.rs b/src/utilities/directory.rs index 41fe372d..e61142e7 100644 --- a/src/utilities/directory.rs +++ b/src/utilities/directory.rs @@ -278,11 +278,17 @@ pub fn format_header_with_id_class( if !id_attribute_added && (c == ' ' || c == '>') { formatted_header_str.push_str(&format!( - " id=\"{}-{}\" tabindex=\"0\"", + " id=\"{}-{}\" tabindex=\"0\" {}", header_type, - id_regex - .replace_all(&first_word, "-"), + id_regex.replace_all(&first_word, "-"), + if header_type == "h1" { + "itemprop=\"headline\"" + } else { + "itemprop=\"subheadline\"" + } )); + + print!("header_type={:?}", header_type); id_attribute_added = true; } diff --git a/src/utilities/template.rs b/src/utilities/template.rs index 83c74e94..942f2356 100644 --- a/src/utilities/template.rs +++ b/src/utilities/template.rs @@ -6,7 +6,7 @@ use reqwest; use std::{ collections::HashMap, fs::{self, File}, - path::Path, + path::{Path, PathBuf}, }; #[derive(Debug, Default, PartialEq, Eq, Clone)] @@ -161,82 +161,60 @@ pub fn create_template_folder( // Get the current working directory let current_dir = std::env::current_dir()?; - // Determine the template directory path based on the provided argument or use the default path let template_dir_path = match template_path { + Some(path) if path.starts_with("http://") || path.starts_with("https://") => { + download_files_from_url(path)? + }, Some(path) => { - if path.starts_with("http://") - || path.starts_with("https://") - { - // If a URL is provided, download the template files to a temporary directory - let tempdir = tempfile::tempdir()?; - let template_dir_path = tempdir.into_path(); - println!( - "Creating temporary directory for template: {:?}", - template_dir_path - ); - - let url = path; - let files = [ - "contact.html", - "index.html", - "main.js", - "page.html", - "sw.js", - ]; - - for file in files.iter() { - let file_url = format!("{}/{}", url, file); - let file_path = template_dir_path.join(file); - let mut download = - reqwest::blocking::get(&file_url)?; - let mut file = File::create(&file_path)?; - download.copy_to(&mut file)?; - println!( - "Downloaded template file to: {:?}", - file_path - ); - } - - template_dir_path + let local_path = current_dir.join(path); + if local_path.exists() && local_path.is_dir() { + println!("Using local template directory: {}", path); + local_path } else { - // If a local path is provided, use it as the template - // directory path - // println!("Using local template directory: {}", path); - current_dir.join(path) + return Err(TemplateError::Io(std::io::Error::new( + std::io::ErrorKind::NotFound, + format!("Template directory not found: {}", path), + ))); } - } + }, None => { - // If no path is provided, download the default template files to a temporary directory - let tempdir = tempfile::tempdir()?; - let template_dir_path = tempdir.into_path(); - println!( - "Creating temporary directory for default template: {:?}", - template_dir_path - ); - - let url = "https://raw.githubusercontent.com/sebastienrousseau/shokunin/main/template/"; - let files = [ - "contact.html", - "index.html", - "main.js", - "page.html", - "sw.js", - ]; - - for file in files.iter() { - let file_url = format!("{}/{}", url, file); - let file_path = template_dir_path.join(file); - let mut download = reqwest::blocking::get(&file_url)?; - let mut file = File::create(&file_path)?; - download.copy_to(&mut file)?; - println!( - "Downloaded default template file to: {:?}", - file_path - ); - } - - template_dir_path + let default_url = "https://raw.githubusercontent.com/sebastienrousseau/shokunin/main/template/"; + download_files_from_url(default_url)? } }; + Ok(String::from(template_dir_path.to_str().unwrap())) } + +fn download_files_from_url(url: &str) -> Result { + let tempdir = tempfile::tempdir()?; + let template_dir_path = tempdir.into_path(); + println!( + "Creating temporary directory for template: {:?}", + template_dir_path + ); + + let files = [ + "contact.html", + "index.html", + "main.js", + "page.html", + "post.html", + "sw.js", + ]; + + for file in files.iter() { + let file_url = format!("{}/{}", url, file); + let file_path = template_dir_path.join(file); + let mut download = reqwest::blocking::get(&file_url)?; + let mut file = File::create(&file_path)?; + download.copy_to(&mut file)?; + println!( + "Downloaded template file to: {:?}", + file_path + ); + } + + Ok(template_dir_path) +} + diff --git a/src/utilities/write.rs b/src/utilities/write.rs index 7775a199..fbbebd1e 100644 --- a/src/utilities/write.rs +++ b/src/utilities/write.rs @@ -1,26 +1,55 @@ // Copyright © 2023 Shokunin Static Site Generator. All rights reserved. // SPDX-License-Identifier: Apache-2.0 OR MIT - +// Import the FileData object definition. use crate::models::data::FileData; + +// Import the minify_html function. use crate::utilities::minification::minify_html; + +// Import the Error trait. use std::error::Error; + +// Import the fs module. use std::fs; + +// Import the Path type. use std::path::Path; -/// Write the files to the build directory -pub fn write_files(build_dir_path: &Path, file: &FileData, template_path: &Path) -> Result<(), Box> { - let file_name = match Path::new(&file.name).extension() { - Some(ext) if ext == "js" => file.name.replace(".js", ""), - Some(ext) if ext == "json" => file.name.replace(".json", ""), - Some(ext) if ext == "md" => file.name.replace(".md", ""), - Some(ext) if ext == "toml" => file.name.replace(".toml", ""), - Some(ext) if ext == "txt" => file.name.replace(".txt", ""), - Some(ext) if ext == "xml" => file.name.replace(".xml", ""), +/// Write the files to the build directory. +/// +/// The `build_dir_path` parameter is the path to the build directory. +/// +/// The `file` parameter is the file data object to write. +/// +/// The `template_path` parameter is the path to the template directory. +/// +/// Returns a `Result` value, which is either `Ok(())` on success or +/// `Err(Box)` on failure. +pub fn write_files_to_build_directory( + build_dir_path: &Path, + file: &FileData, + template_path: &Path +) -> Result<(), Box> { + + // Determine the file name without extension and check if it's "index". + let file_name = match (Path::new(&file.name).extension().and_then( + |s| s.to_str() + ), &file.name) { + (Some(ext), name) if + ["js", "json", "md", "toml", "txt", "xml"].contains(&ext) => { + name.replace(&format!(".{}", ext), "") + }, _ => file.name.to_string(), }; + // Check if the file name is "index" to decide the directory structure. + let index_html_minified = file_name == "index"; + let dir_name = build_dir_path.join(&file_name); + if file_name == "index" { + // List of files that need special handling when the file name is + // "index". let file_paths = [ ("CNAME", &file.cname), ("humans.txt", &file.human), @@ -30,26 +59,34 @@ pub fn write_files(build_dir_path: &Path, file: &FileData, template_path: &Path) ("rss.xml", &file.rss), ("sitemap.xml", &file.sitemap), ]; - println!("\n {}", file_name.to_uppercase()); + + // Print the section header. + println!("\n{}", file_name.to_uppercase()); + + // Process each file in the list. for (file_name, content) in &file_paths { - let file_path = build_dir_path.join(file_name); - fs::write(&file_path, content)?; - if file_name == &"index.html" { - let minified_content = minify_html(&file_path)?; - fs::write(&file_path, &minified_content)?; - } - println!(" - {}", file_path.display()); + write_and_minify_file( + build_dir_path, + file_name, + content, + index_html_minified + )?; } + // Copy other template files to the build directory. let other_files = ["main.js", "sw.js"]; for file_name in &other_files { - let dest_path = build_dir_path.join(file_name); - fs::copy(&template_path.join(file_name), &dest_path)?; + copy_template_file( + template_path, + build_dir_path, + file_name + )?; } } else { - let dir_name = build_dir_path.join(file_name.clone()); + // Create a subdirectory based on the file name. fs::create_dir_all(&dir_name)?; + // List of files that don't require special handling. let file_paths = [ ("index.html", &file.content), ("manifest.json", &file.json), @@ -58,17 +95,52 @@ pub fn write_files(build_dir_path: &Path, file: &FileData, template_path: &Path) ("sitemap.xml", &file.sitemap), ]; - println!("\n {}", file_name.to_uppercase()); + // Print the section header. + println!("\n{}", file_name.to_uppercase()); + + // Process each file in the list. for (file_name, content) in &file_paths { - let file_path = dir_name.join(file_name); - fs::write(&file_path, content)?; - if file_name == &"index.html" { - let minified_content = minify_html(&file_path)?; - fs::write(&file_path, &minified_content)?; - } - println!(" - {}", file_path.display()); + write_and_minify_file( + &dir_name, + file_name, + content, + index_html_minified + )?; } } + Ok(()) +} + +// Function to write a file and optionally minify its content. +fn write_and_minify_file( + dir_path: &Path, + file_name: &str, + content: &str, + minify: bool, +) -> Result<(), Box> { + let file_path = dir_path.join(file_name); + fs::write(&file_path, content)?; + + // Minify "index.html" content if required. + if minify && file_name == "index.html" { + let minified_content = minify_html(&file_path)?; + fs::write(&file_path, minified_content)?; + } + + // Print the file path. + println!(" - {}", file_path.display()); + Ok(()) +} + +// Function to copy a template file to the build directory. +fn copy_template_file( + template_path: &Path, + dest_dir: &Path, + file_name: &str +) -> Result<(), Box> { + let dest_path = dest_dir.join(file_name); + fs::copy(template_path.join(file_name), dest_path)?; + Ok(()) } \ No newline at end of file diff --git a/template/contact.html b/template/contact.html index 5b6577df..134a85fe 100644 --- a/template/contact.html +++ b/template/contact.html @@ -23,16 +23,7 @@ - + @@ -82,7 +73,7 @@ - + + + + + diff --git a/template/index.html b/template/index.html index c5af4443..e87bb296 100644 --- a/template/index.html +++ b/template/index.html @@ -23,16 +23,7 @@ - + @@ -82,7 +73,7 @@ - + @@ -208,38 +199,7 @@ src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"> > + + + + \ No newline at end of file diff --git a/template/template.html b/template/template.html index edf514a8..f7e6448b 100644 --- a/template/template.html +++ b/template/template.html @@ -23,16 +23,7 @@ - + @@ -82,7 +73,7 @@ - + >