mirror of
https://github.com/zyllian/zyllian.github.io.git
synced 2025-05-09 10:06:42 -07:00
many many changes
This commit is contained in:
parent
80bc863cdf
commit
efa0d03315
22 changed files with 360 additions and 45 deletions
29
site/blog/estradiol-delivery-methods.md
Normal file
29
site/blog/estradiol-delivery-methods.md
Normal file
|
@ -0,0 +1,29 @@
|
|||
---
|
||||
title: Estradiol Delivery Methods
|
||||
timestamp: 2023-05-28T16:00:00.00Z
|
||||
tags: [trans, hrt]
|
||||
desc: A comparison of the various ways I've taken estradiol since starting HRT.
|
||||
header_image_file: cat.jpeg # TODO: placeholder image
|
||||
header_image_alt: placeholder
|
||||
draft: true
|
||||
---
|
||||
|
||||
I thought it might be useful to write out my experiences with the four methods of taking estradiol I've tried.
|
||||
|
||||
- patches
|
||||
- wouldn't consistently stay on me
|
||||
- could feel the effects wearing off 3-4 days after application
|
||||
- insurance sucks
|
||||
- sublingual pills
|
||||
- worked alright, except:
|
||||
- could feel them wearing off ~5-6 hours after taking a dose
|
||||
- apparently hard to measure levels? had one test at ~200 mg/ml and another at 400+ mg/ml at same dosage
|
||||
- swallowed pills
|
||||
- could not get ideal levels with a reasonable number of pills, but:
|
||||
- couldn't actually feel them wearing off even at 12 hours between doses
|
||||
- injections
|
||||
- holy shit these are great
|
||||
- was kinda nervous the first few times I injected myself, but I got used to it
|
||||
- cannot feel it wearing off between doses
|
||||
- levels are actually good??
|
||||
- insurance sucks pt. 2
|
23
site/blog/so-now-i-have-a-blog.md
Normal file
23
site/blog/so-now-i-have-a-blog.md
Normal file
|
@ -0,0 +1,23 @@
|
|||
---
|
||||
title: so now i have a blog
|
||||
timestamp: 2023-06-09T16:00:00.00Z
|
||||
tags: [meta, technical]
|
||||
desc: I added a blog to my site.
|
||||
header_image_file: cat.jpeg # TODO: placeholder image
|
||||
header_image_alt: placeholder
|
||||
draft: true
|
||||
---
|
||||
|
||||
So now I have a blog on my site. I don't really have any plans to post here regularly, but idk maybe that'll change in the future.
|
||||
|
||||
That's pretty much it as far as the non-technical side of things goes.
|
||||
|
||||
## The Technical Side of Things
|
||||
|
||||
I haven't really written anything about how my site works before, so this is also going to contain some general information about the site as a whole.
|
||||
|
||||
`zyl.gay` is a static website built with a custom static site builder I built for it. It started by taking Markdown pages and rendering them on top of the appropriate template.
|
||||
|
||||
When I added the [images section](/images/) to the site I added the first abstraction on top of this: YAML files with the relevant metadata for the image (including a short but unstyled description) which then get rendered not only into pages for the individual pages, but also a paginated display for all the images _and_ a method to view images by tag.
|
||||
|
||||
To get blogs working I modified the image page code to be generic over provided resource types, so really the images and the blog posts are rendered the same way, just with different configurations.
|
|
@ -3,5 +3,6 @@ title: Zyllian
|
|||
description: "Zoey's website."
|
||||
sass_styles: [index.scss]
|
||||
images_per_page: 10
|
||||
blog_posts_per_page: 20
|
||||
cdn_url: "https://i.zyl.gay"
|
||||
s3_prefix: # no longer prefixed
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
---
|
||||
title: among us 😱
|
||||
timestamp: 2022-12-14T00:00:00.00Z
|
||||
alt: Screenshot of Pokémon White on an evolution screen. Text reads "Congratulations! Your amogus evolved into Amoonguss!"
|
||||
desc: aaahhhh
|
||||
file: amogus.png
|
||||
tags: [pokémon, sussy]
|
||||
---
|
||||
|
||||
aaahhhh
|
|
@ -1,5 +1,7 @@
|
|||
---
|
||||
title: cat 3
|
||||
timestamp: 2022-12-14T00:00:00.00Z
|
||||
alt: Picture of my cat sleeping in a box barely large enough for them. Their head is resting on one edge of the box.
|
||||
file: boxtop.jpeg
|
||||
tags: [cat]
|
||||
---
|
|
@ -1,5 +1,7 @@
|
|||
---
|
||||
title: cat
|
||||
timestamp: 2022-12-14T00:00:00.00Z
|
||||
alt: Picture of my cat sleeping curled up on top of some pillows.
|
||||
file: cat.jpeg
|
||||
tags: [cat]
|
||||
---
|
|
@ -1,5 +1,7 @@
|
|||
---
|
||||
title: cat 2
|
||||
timestamp: 2022-12-14T00:00:00.00Z
|
||||
alt: Close up picture of my cat laying on a shelf while staring not quite at the camera.
|
||||
file: cat2.jpeg
|
||||
tags: [cat]
|
||||
---
|
13
site/images/makeup-first-lol.md
Normal file
13
site/images/makeup-first-lol.md
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
title: first time applying makeup
|
||||
timestamp: 2023-02-10T21:40:00.00Z
|
||||
alt: Bathroom mirror selfie of me in a cap, dark-rimmed glasses, and a flannel button-up over a mesh shirt wearing some light red lipstick, light and slightly orange blush around the nose, and poorly applied eyeliner.
|
||||
file: makeup-first-lol.jpeg
|
||||
tags: [me, selfie]
|
||||
---
|
||||
|
||||
had the house to myself to try out some outfits and makeup without any external pressure
|
||||
|
||||
this picture's of my first time applying any makeup where despite thinking it all looked like shit individually, I think all the parts came together well
|
||||
|
||||
I'm wearing only lipstick, a little blush, and eyeliner. the foundation in the kit I was given wouldn't stay on 🤷
|
|
@ -1,9 +0,0 @@
|
|||
title: first time applying makeup
|
||||
timestamp: 2023-02-10T21:40:00.00Z
|
||||
alt: Bathroom mirror selfie of me in a cap, dark-rimmed glasses, and a flannel button-up over a mesh shirt wearing some light red lipstick, light and slightly orange blush around the nose, and poorly applied eyeliner.
|
||||
desc: >
|
||||
<p>had the house to myself to try out some outfits and makeup without any external pressure</p>
|
||||
<p>this picture's of my first time applying any makeup where despite thinking it all looked like shit individually, I think all the parts came together well</p>
|
||||
<p>I'm wearing only lipstick, a little blush, and eyeliner. the foundation in the kit I was given wouldn't stay on 🤷</p>
|
||||
file: makeup-first-lol.jpeg
|
||||
tags: [me, selfie]
|
|
@ -1,6 +1,9 @@
|
|||
---
|
||||
title: shorts to dresses
|
||||
timestamp: 2022-12-14T00:00:00.00Z
|
||||
alt: Screenshot from Pokémon Black 2 of an NPC saying "This dress is comfy and easy to wear..."
|
||||
desc: yooo they're turning the comfy shorts kid trans
|
||||
file: trans-comfy.png
|
||||
tags: [pokémon, trans]
|
||||
---
|
||||
|
||||
yooo they're turning the comfy shorts kid trans
|
|
@ -9,11 +9,15 @@ body {
|
|||
--text-color: black;
|
||||
--accent-color: #b520e7;
|
||||
--accent-text-color: var(--bg-color);
|
||||
--accent-color-neutral: #aaa;
|
||||
--accent-text-color-neutral: #eee;
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--bg-color: #333;
|
||||
--text-color: #ccc;
|
||||
--accent-text-color: black;
|
||||
--accent-color-neutral: #555;
|
||||
--accent-text-color-neutral: #bbb;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -55,7 +59,7 @@ abbr {
|
|||
.images-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
|
||||
.image {
|
||||
position: relative;
|
||||
padding: 4px;
|
||||
|
@ -81,7 +85,8 @@ abbr {
|
|||
}
|
||||
|
||||
.image-full {
|
||||
.title, .tags-title {
|
||||
.title,
|
||||
.tags-title {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
@ -92,3 +97,68 @@ abbr {
|
|||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.blog-post-list {
|
||||
.post {
|
||||
p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.short-desc {
|
||||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
|
||||
&:before {
|
||||
content: "└ ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.blog-post {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
max-width: max(1000px, 40%);
|
||||
|
||||
.title,
|
||||
.tags-title {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.header-image-wrapper {
|
||||
color: var(--accent-text-color-neutral);
|
||||
background-color: var(--accent-color-neutral);
|
||||
font-style: italic;
|
||||
font-size: 1.2rem;
|
||||
margin-bottom: 8px;
|
||||
|
||||
.short-desc {
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header-image {
|
||||
width: 100%;
|
||||
max-height: 60vh;
|
||||
object-fit: cover;
|
||||
object-position: 50% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
text-indent: 1rem;
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6 {
|
||||
text-indent: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
<span class="pronouns">she/they</span>
|
||||
</span>
|
||||
<span class="spacer"></span>
|
||||
{{!-- <a href="/blog/">Blog</a> | --}}
|
||||
<a href="/images/">Images</a> |
|
||||
<a href="https://github.com/Zyllian/zyllian.github.io" rel="noopener noreferrer">Source</a>
|
||||
</header>
|
||||
|
|
23
site/templates/blog-list.hbs
Normal file
23
site/templates/blog-list.hbs
Normal file
|
@ -0,0 +1,23 @@
|
|||
{{#if tag}}
|
||||
<h1>Blog posts tagged {{tag}}</h1>
|
||||
<p><a href="/blog/">View all blog posts</a></p>
|
||||
{{else}}
|
||||
<h1>Blog Posts</h1>
|
||||
<p><a href="tags">View blog tags</a></p>
|
||||
<p><a href="rss.xml">RSS Feed</a></p>
|
||||
{{/if}}
|
||||
<h1>Page {{page}}/{{page_max}}</h1>
|
||||
{{#if previous}}
|
||||
<a href="./{{previous}}">Previous page</a>
|
||||
{{/if}}
|
||||
{{#if next}}
|
||||
<a href="./{{next}}">Next page</a>
|
||||
{{/if}}
|
||||
<div class="blog-post-list">
|
||||
{{#each resources}}
|
||||
<div class="post">
|
||||
<p class="title"><a href="/blog/{{id}}">{{title}}</a></p>
|
||||
<p class="short-desc">{{desc}}</p>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
22
site/templates/blog-post.hbs
Normal file
22
site/templates/blog-post.hbs
Normal file
|
@ -0,0 +1,22 @@
|
|||
<div class="blog-post">
|
||||
<h1 class="title">{{title}}</h1>
|
||||
<span class="timestamp">Published {{timestamp}}</span>
|
||||
{{#if draft}}
|
||||
<h2>DRAFT</h2>
|
||||
{{/if}}
|
||||
<div class="header-image-wrapper">
|
||||
<p class="short-desc">{{desc}}</p>
|
||||
<img class="header-image" src="{{header_image}}" alt="{{header_image_alt}}"
|
||||
style="object-fit: {{object_fit}}; object-position: {{object_position}};">
|
||||
</div>
|
||||
<div class="content">
|
||||
{{{content}}}
|
||||
</div>
|
||||
<hr />
|
||||
<h3 class="tags-title">Tags</h3>
|
||||
<div class="post-tags">
|
||||
{{#each tags}}
|
||||
<a class="tag" href="/blog/tag/{{this}}">{{this}}</a>{{#unless @last}},{{/unless}}
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
|
@ -2,9 +2,7 @@
|
|||
<h1 class="title">{{title}}</h1>
|
||||
<span class="timestamp">Published {{timestamp}}</span>
|
||||
<img class="image-actual" src="{{src}}" alt="{{alt}}">
|
||||
{{#if desc}}
|
||||
<p>{{{desc}}}</p>
|
||||
{{/if}}
|
||||
{{{content}}}
|
||||
<p><a href="{{src}}">View full size image</a></p>
|
||||
<h3 class="tags-title">Tags</h3>
|
||||
<div class="image-tags">
|
||||
|
|
1
site/templates/rss/blog-post.hbs
Normal file
1
site/templates/rss/blog-post.hbs
Normal file
|
@ -0,0 +1 @@
|
|||
<div>{{{source}}}</div>
|
86
src/blog.rs
Normal file
86
src/blog.rs
Normal file
|
@ -0,0 +1,86 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
builder::SiteBuilder,
|
||||
resource::{ResourceBuilder, ResourceBuilderConfig, ResourceMetadata, ResourceMethods},
|
||||
};
|
||||
|
||||
pub const BLOG_PATH: &str = "blog";
|
||||
|
||||
/// Builds the blog.
|
||||
pub fn build_blog(site_builder: &SiteBuilder) -> anyhow::Result<()> {
|
||||
let config = ResourceBuilderConfig {
|
||||
source_path: BLOG_PATH.to_string(),
|
||||
output_path_short: BLOG_PATH.to_string(),
|
||||
output_path_long: BLOG_PATH.to_string(),
|
||||
resource_template: "blog-post".to_string(),
|
||||
resource_list_template: "blog-list".to_string(),
|
||||
rss_template: "rss/blog-post".to_string(),
|
||||
rss_title: "Zyllian's blog".to_string(),
|
||||
rss_description: "Feed of recent blog posts on Zyllian's website.".to_string(),
|
||||
list_title: "Blog".to_string(),
|
||||
tag_list_title: "Blog Tags".to_string(),
|
||||
resource_name_plural: "Blog posts".to_string(),
|
||||
resources_per_page: site_builder.site.config.blog_posts_per_page,
|
||||
};
|
||||
|
||||
let mut builder = ResourceBuilder::<BlogPostMetadata, BlogPostTemplateData>::new(config);
|
||||
builder.load_all(site_builder)?;
|
||||
builder.build_all(site_builder)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Metadata for a blog post.
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct BlogPostMetadata {
|
||||
/// A short description about the post.
|
||||
pub desc: String,
|
||||
/// Path to the post's header image.
|
||||
pub header_image_file: String,
|
||||
/// Alt text for the post's header image.
|
||||
pub header_image_alt: String,
|
||||
/// Optional custom object fit value.
|
||||
pub image_fit: Option<String>,
|
||||
/// Optional custom object position value.
|
||||
pub image_center: Option<String>,
|
||||
}
|
||||
|
||||
/// Template data for a blog post.
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct BlogPostTemplateData {
|
||||
/// CDN path to the post's header image.
|
||||
pub header_image: String,
|
||||
/// Custom object fit value.
|
||||
pub object_fit: String,
|
||||
/// Custom object position value.
|
||||
pub object_position: String,
|
||||
}
|
||||
|
||||
impl ResourceMethods<BlogPostTemplateData> for ResourceMetadata<BlogPostMetadata> {
|
||||
fn get_short_desc(&self) -> String {
|
||||
self.inner.desc.clone()
|
||||
}
|
||||
|
||||
fn get_extra_resource_template_data(
|
||||
&self,
|
||||
site_config: &crate::SiteConfig,
|
||||
) -> anyhow::Result<BlogPostTemplateData> {
|
||||
// TODO: render markdown
|
||||
Ok(BlogPostTemplateData {
|
||||
header_image: site_config
|
||||
.cdn_url(&self.inner.header_image_file)?
|
||||
.to_string(),
|
||||
object_fit: self
|
||||
.inner
|
||||
.image_fit
|
||||
.clone()
|
||||
.unwrap_or_else(|| "cover".to_string()),
|
||||
object_position: self
|
||||
.inner
|
||||
.image_center
|
||||
.clone()
|
||||
.unwrap_or_else(|| "50% 50%".to_string()),
|
||||
})
|
||||
}
|
||||
}
|
|
@ -25,7 +25,7 @@ struct TemplateData<'a> {
|
|||
/// Struct used to build the site.
|
||||
pub struct SiteBuilder<'a> {
|
||||
/// The matter instance used to extract front matter.
|
||||
matter: Matter<YAML>,
|
||||
pub(crate) matter: Matter<YAML>,
|
||||
/// The Handlebars registry used to render templates.
|
||||
pub(crate) reg: Handlebars<'a>,
|
||||
/// The site info used to build the site.
|
||||
|
@ -242,4 +242,9 @@ impl<'a> SiteBuilder<'a> {
|
|||
pub fn build_images(&self) -> anyhow::Result<()> {
|
||||
crate::images::build_images(self)
|
||||
}
|
||||
|
||||
/// Builds the site's blog.
|
||||
pub fn build_blog(&self) -> anyhow::Result<()> {
|
||||
crate::blog::build_blog(self)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
use crate::{
|
||||
builder::SiteBuilder,
|
||||
|
@ -28,7 +27,7 @@ pub fn build_images(site_builder: &SiteBuilder) -> anyhow::Result<()> {
|
|||
};
|
||||
|
||||
let mut builder = ResourceBuilder::<ImageMetadata, ImageTemplateData>::new(config);
|
||||
builder.load_all(&site_builder.site.site_path)?;
|
||||
builder.load_all(site_builder)?;
|
||||
builder.build_all(site_builder)?;
|
||||
|
||||
Ok(())
|
||||
|
@ -45,13 +44,6 @@ pub struct ImageMetadata {
|
|||
pub file: String,
|
||||
}
|
||||
|
||||
impl ImageMetadata {
|
||||
/// Gets an image's CDN url.
|
||||
pub fn cdn_url(&self, config: &SiteConfig) -> anyhow::Result<Url> {
|
||||
Ok(config.cdn_url.join(&config.s3_prefix)?.join(&self.file)?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Template data for a specific image.
|
||||
#[derive(Debug, Serialize)]
|
||||
struct ImageTemplateData {
|
||||
|
@ -70,7 +62,7 @@ impl ResourceMethods<ImageTemplateData> for ResourceMetadata<ImageMetadata> {
|
|||
site_config: &SiteConfig,
|
||||
) -> anyhow::Result<ImageTemplateData> {
|
||||
Ok(ImageTemplateData {
|
||||
src: self.inner.cdn_url(site_config)?.to_string(),
|
||||
src: site_config.cdn_url(&self.inner.file)?.to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
11
src/lib.rs
11
src/lib.rs
|
@ -1,3 +1,4 @@
|
|||
mod blog;
|
||||
mod builder;
|
||||
mod images;
|
||||
mod link_list;
|
||||
|
@ -38,12 +39,21 @@ pub struct SiteConfig {
|
|||
pub sass_styles: Vec<PathBuf>,
|
||||
/// The number of images to display on a single page of an image list.
|
||||
pub images_per_page: usize,
|
||||
/// The number of blog posts to display on a single page of a post list.
|
||||
pub blog_posts_per_page: usize,
|
||||
/// URL to the CDN used for the site's images.
|
||||
pub cdn_url: Url,
|
||||
/// Prefix applied to all files uploaded to the site's S3 space.
|
||||
pub s3_prefix: String,
|
||||
}
|
||||
|
||||
impl SiteConfig {
|
||||
/// Gets a CDN url from the given file name.
|
||||
pub fn cdn_url(&self, file: &str) -> anyhow::Result<Url> {
|
||||
Ok(self.cdn_url.join(&self.s3_prefix)?.join(file)?)
|
||||
}
|
||||
}
|
||||
|
||||
/// Struct for the front matter in templates. (nothing here yet)
|
||||
#[derive(Debug, Default, Deserialize)]
|
||||
pub struct TemplateMetadata {}
|
||||
|
@ -134,6 +144,7 @@ impl Site {
|
|||
builder.site.build_all_pages(&builder)?;
|
||||
builder.build_sass()?;
|
||||
builder.build_images()?;
|
||||
builder.build_blog()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ use std::{
|
|||
|
||||
use anyhow::Context;
|
||||
use itertools::Itertools;
|
||||
use pulldown_cmark::{Options, Parser};
|
||||
use rss::{validation::Validate, ChannelBuilder, ItemBuilder};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize, Serializer};
|
||||
use time::{format_description::well_known::Rfc2822, OffsetDateTime};
|
||||
|
@ -25,6 +26,12 @@ pub struct ResourceMetadata<T> {
|
|||
/// Extra resource data not included.
|
||||
#[serde(flatten)]
|
||||
pub inner: T,
|
||||
/// Whether the resource is a draft. Drafts can be committed without being published to the live site.
|
||||
#[serde(default)]
|
||||
pub draft: bool,
|
||||
/// The resource's content. Defaults to nothing until loaded in another step.
|
||||
#[serde(default)]
|
||||
pub content: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
|
@ -141,19 +148,39 @@ where
|
|||
}
|
||||
|
||||
/// Loads resource metadata from the given path.
|
||||
fn load(path: &Path) -> anyhow::Result<(String, ResourceMetadata<M>)> {
|
||||
fn load(builder: &SiteBuilder, path: &Path) -> anyhow::Result<(String, ResourceMetadata<M>)> {
|
||||
let id = Self::get_id(path);
|
||||
let metadata = serde_yaml::from_str(&std::fs::read_to_string(path)?)?;
|
||||
Ok((id, metadata))
|
||||
|
||||
let input = std::fs::read_to_string(path)?;
|
||||
let mut page = builder
|
||||
.matter
|
||||
.parse_with_struct::<ResourceMetadata<M>>(&input)
|
||||
.ok_or_else(|| anyhow::anyhow!("Failed to parse resource front matter"))?;
|
||||
|
||||
let parser = Parser::new_ext(&page.content, Options::all());
|
||||
let mut html = String::new();
|
||||
pulldown_cmark::html::push_html(&mut html, parser);
|
||||
|
||||
page.data.content = html;
|
||||
|
||||
Ok((id, page.data))
|
||||
}
|
||||
|
||||
/// Loads all resource metadata from the given config.
|
||||
pub fn load_all(&mut self, site_path: &Path) -> anyhow::Result<()> {
|
||||
pub fn load_all(&mut self, builder: &SiteBuilder) -> anyhow::Result<()> {
|
||||
self.loaded_metadata.clear();
|
||||
for e in site_path.join(&self.config.source_path).read_dir()? {
|
||||
for e in builder
|
||||
.site
|
||||
.site_path
|
||||
.join(&self.config.source_path)
|
||||
.read_dir()?
|
||||
{
|
||||
let p = e?.path();
|
||||
if let Some("yml") = p.extension().and_then(|e| e.to_str()) {
|
||||
let (id, metadata) = Self::load(&p)?;
|
||||
if let Some("md") = p.extension().and_then(|e| e.to_str()) {
|
||||
let (id, metadata) = Self::load(builder, &p)?;
|
||||
if cfg!(not(debug_assertions)) && metadata.draft {
|
||||
continue;
|
||||
}
|
||||
self.loaded_metadata.push((id, metadata));
|
||||
}
|
||||
}
|
||||
|
@ -201,6 +228,16 @@ where
|
|||
}
|
||||
|
||||
pub fn build_all(&self, builder: &SiteBuilder) -> anyhow::Result<()> {
|
||||
let out_short = builder.build_path.join(&self.config.output_path_short);
|
||||
let out_long = builder.build_path.join(&self.config.output_path_long);
|
||||
|
||||
if !out_short.exists() {
|
||||
std::fs::create_dir_all(&out_short)?;
|
||||
}
|
||||
if !out_long.exists() {
|
||||
std::fs::create_dir_all(&out_long)?;
|
||||
}
|
||||
|
||||
for (id, resource) in &self.loaded_metadata {
|
||||
self.build(builder, id.clone(), resource)?;
|
||||
}
|
||||
|
@ -267,8 +304,6 @@ where
|
|||
Ok(())
|
||||
}
|
||||
|
||||
let out_path = builder.build_path.join(&self.config.output_path_short);
|
||||
|
||||
// Build main list of resources
|
||||
build_list(
|
||||
builder,
|
||||
|
@ -276,7 +311,7 @@ where
|
|||
data.iter().collect(),
|
||||
&self.config.list_title,
|
||||
None,
|
||||
&builder.build_path.join(&self.config.output_path_long),
|
||||
&out_long,
|
||||
self.config.resources_per_page,
|
||||
)?;
|
||||
|
||||
|
@ -310,7 +345,7 @@ where
|
|||
links,
|
||||
&self.config.tag_list_title,
|
||||
)?;
|
||||
std::fs::write(out_path.join("tags.html"), out)?;
|
||||
std::fs::write(out_short.join("tags.html"), out)?;
|
||||
}
|
||||
|
||||
for (tag, data) in tags {
|
||||
|
@ -320,7 +355,7 @@ where
|
|||
data,
|
||||
&format!("{} tagged {tag}", self.config.resource_name_plural),
|
||||
Some(tag.as_str()),
|
||||
&out_path.join("tag").join(&tag),
|
||||
&out_short.join("tag").join(&tag),
|
||||
self.config.resources_per_page,
|
||||
)?;
|
||||
}
|
||||
|
@ -367,13 +402,7 @@ where
|
|||
.build();
|
||||
channel.validate().context("Failed to validate RSS feed")?;
|
||||
let out = channel.to_string();
|
||||
std::fs::write(
|
||||
builder
|
||||
.build_path
|
||||
.join(&self.config.output_path_long)
|
||||
.join("rss.xml"),
|
||||
out,
|
||||
)?;
|
||||
std::fs::write(out_long.join("rss.xml"), out)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ fn create(
|
|||
if build {
|
||||
builder.site.build_all_pages(builder)?;
|
||||
builder.build_images()?;
|
||||
builder.build_blog()?;
|
||||
}
|
||||
} else if relative_path.display().to_string() == "config.yaml" {
|
||||
let new_config = serde_yaml::from_str(&std::fs::read_to_string(path)?)?;
|
||||
|
@ -78,6 +79,9 @@ fn create(
|
|||
} else if let Ok(_image_path) = relative_path.strip_prefix(crate::images::IMAGES_PATH) {
|
||||
// HACK: this could get very inefficient with a larger number of images. should definitely optimize
|
||||
builder.build_images()?;
|
||||
} else if let Ok(_blog_path) = relative_path.strip_prefix(crate::blog::BLOG_PATH) {
|
||||
// HACK: same as above
|
||||
builder.build_blog()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -109,6 +113,8 @@ fn remove(builder: &mut SiteBuilder, path: &Path, relative_path: &Path) -> anyho
|
|||
} else if let Ok(_image_path) = relative_path.strip_prefix(crate::images::IMAGES_PATH) {
|
||||
// HACK: same as in `create`
|
||||
builder.build_images()?;
|
||||
} else if let Ok(_blog_path) = relative_path.strip_prefix(crate::blog::BLOG_PATH) {
|
||||
// HACK: same as above
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -138,6 +144,7 @@ impl Site {
|
|||
builder
|
||||
.build_images()
|
||||
.context("Failed to build image pages")?;
|
||||
builder.build_blog().context("Failed to build blog")?;
|
||||
|
||||
// Map of websocket connections
|
||||
let peers: Arc<Mutex<HashMap<SocketAddr, WebSocket>>> =
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue