This commit is contained in:
parent
2979e21285
commit
ceb3f4b89d
@ -1,3 +1,2 @@
|
|||||||
pub mod blog_post_model;
|
pub mod blog_post_model;
|
||||||
pub mod featured_blog_posts;
|
pub mod featured_blog_posts;
|
||||||
pub mod tag_list;
|
|
||||||
|
17
src/main.rs
17
src/main.rs
@ -41,8 +41,6 @@ async fn main() {
|
|||||||
.nest_service("/config.yml", ServeDir::new("static/resources/config.yml")) // Decap CMS config
|
.nest_service("/config.yml", ServeDir::new("static/resources/config.yml")) // Decap CMS config
|
||||||
.nest_service("/robots.txt", ServeDir::new("robots.txt"));
|
.nest_service("/robots.txt", ServeDir::new("robots.txt"));
|
||||||
|
|
||||||
let app = app.fallback(handler_404);
|
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let app = app.layer(LiveReloadLayer::new());
|
let app = app.layer(LiveReloadLayer::new());
|
||||||
|
|
||||||
@ -54,21 +52,8 @@ async fn main() {
|
|||||||
axum::serve(listener, app).await.unwrap();
|
axum::serve(listener, app).await.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handler_404(OriginalUri(original_uri): OriginalUri) -> impl IntoResponse {
|
|
||||||
info!("{original_uri} not found");
|
|
||||||
(StatusCode::NOT_FOUND, "nothing to see here")
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Socials
|
// TODO Socials
|
||||||
// - fotos
|
// - fotos
|
||||||
// background gradient color
|
|
||||||
// TODO Change DNS system
|
|
||||||
// THINK deploy to alula? rather then katelyn? can be change whenever
|
// THINK deploy to alula? rather then katelyn? can be change whenever
|
||||||
// TODO after release
|
|
||||||
// OG tags
|
|
||||||
// - projects page
|
|
||||||
// TODO broken links
|
|
||||||
// showcase/eggfetcher
|
|
||||||
// broadcasts/
|
|
||||||
// manifest.json
|
|
||||||
//
|
//
|
||||||
|
// TODO 404 page
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use askama::Template;
|
|
||||||
use axum::{
|
use axum::{
|
||||||
extract::{OriginalUri, Path},
|
extract::{OriginalUri, Path},
|
||||||
http::StatusCode,
|
http::StatusCode,
|
||||||
@ -7,28 +6,16 @@ use tokio::try_join;
|
|||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blog_posts::{
|
blog_posts::blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
|
||||||
blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
|
|
||||||
tag_list::{get_popular_tags, get_posts_by_tag},
|
|
||||||
},
|
|
||||||
components::site_header::{HeaderProps, Link},
|
components::site_header::{HeaderProps, Link},
|
||||||
filters,
|
post_utils::{
|
||||||
post_utils::{post_listing::get_post_list, post_parser::ParseResult},
|
post_listing::get_post_list,
|
||||||
projects::{featured_projects::get_featured_projects, project_model::ProjectMetadata},
|
tags::{get_popular_tags, get_posts_by_tag},
|
||||||
|
},
|
||||||
|
projects::featured_projects::get_featured_projects,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Template)]
|
use super::post_list::PostListTemplate;
|
||||||
#[template(path = "blog_post_list.html")]
|
|
||||||
pub struct PostListTemplate {
|
|
||||||
pub title: String,
|
|
||||||
pub og_title: String,
|
|
||||||
pub segment: String,
|
|
||||||
pub posts: Vec<ParseResult<BlogPostMetadata>>,
|
|
||||||
pub header_props: HeaderProps,
|
|
||||||
pub tags: Vec<String>,
|
|
||||||
pub featured_projects: Vec<ParseResult<ProjectMetadata>>,
|
|
||||||
pub current_url: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn render_blog_post_list(
|
pub async fn render_blog_post_list(
|
||||||
tag: Option<Path<String>>,
|
tag: Option<Path<String>>,
|
||||||
|
@ -6,16 +6,16 @@ use tokio::try_join;
|
|||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blog_posts::{
|
blog_posts::blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
|
||||||
blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
|
|
||||||
tag_list::{get_popular_tags, get_posts_by_tag},
|
|
||||||
},
|
|
||||||
components::site_header::{HeaderProps, Link},
|
components::site_header::{HeaderProps, Link},
|
||||||
post_utils::post_listing::get_post_list,
|
post_utils::{
|
||||||
|
post_listing::get_post_list,
|
||||||
|
tags::{get_popular_tags, get_posts_by_tag},
|
||||||
|
},
|
||||||
projects::featured_projects::get_featured_projects,
|
projects::featured_projects::get_featured_projects,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::blog_post_list::PostListTemplate;
|
use super::post_list::PostListTemplate;
|
||||||
|
|
||||||
pub async fn render_broadcast_post_list(
|
pub async fn render_broadcast_post_list(
|
||||||
tag: Option<Path<String>>,
|
tag: Option<Path<String>>,
|
||||||
|
@ -3,13 +3,10 @@ use axum::http::StatusCode;
|
|||||||
use tokio::try_join;
|
use tokio::try_join;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blog_posts::{
|
blog_posts::{blog_post_model::BlogPostMetadata, featured_blog_posts::get_featured_blog_posts},
|
||||||
blog_post_model::BlogPostMetadata, featured_blog_posts::get_featured_blog_posts,
|
|
||||||
tag_list::get_popular_tags,
|
|
||||||
},
|
|
||||||
components::site_header::HeaderProps,
|
components::site_header::HeaderProps,
|
||||||
filters,
|
filters,
|
||||||
post_utils::post_parser::ParseResult,
|
post_utils::{post_parser::ParseResult, tags::get_popular_tags},
|
||||||
projects::{featured_projects::get_featured_projects, project_model::ProjectMetadata},
|
projects::{featured_projects::get_featured_projects, project_model::ProjectMetadata},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -4,5 +4,7 @@ pub mod blog_post_page;
|
|||||||
pub mod broadcast_list;
|
pub mod broadcast_list;
|
||||||
pub mod contact;
|
pub mod contact;
|
||||||
pub mod index;
|
pub mod index;
|
||||||
|
pub mod not_found;
|
||||||
|
pub mod post_list;
|
||||||
pub mod project_list;
|
pub mod project_list;
|
||||||
pub mod showcase;
|
pub mod showcase;
|
||||||
|
25
src/pages/not_found.rs
Normal file
25
src/pages/not_found.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use askama::Template;
|
||||||
|
use axum::{extract::OriginalUri, http::StatusCode};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
use crate::components::site_header::HeaderProps;
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "not_found.html")]
|
||||||
|
pub struct NotFoundPage {
|
||||||
|
title: String,
|
||||||
|
header_props: HeaderProps,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn render_not_found(
|
||||||
|
OriginalUri(original_uri): OriginalUri,
|
||||||
|
) -> Result<(StatusCode, NotFoundPage), StatusCode> {
|
||||||
|
info!("{original_uri} not found");
|
||||||
|
Ok((
|
||||||
|
StatusCode::NOT_FOUND,
|
||||||
|
NotFoundPage {
|
||||||
|
title: "This page does not exists".to_owned(),
|
||||||
|
header_props: HeaderProps::default(),
|
||||||
|
},
|
||||||
|
))
|
||||||
|
}
|
19
src/pages/post_list.rs
Normal file
19
src/pages/post_list.rs
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
use askama::Template;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
blog_posts::blog_post_model::BlogPostMetadata, components::site_header::HeaderProps, filters,
|
||||||
|
post_utils::post_parser::ParseResult, projects::project_model::ProjectMetadata,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[derive(Template)]
|
||||||
|
#[template(path = "post_list.html")]
|
||||||
|
pub struct PostListTemplate {
|
||||||
|
pub title: String,
|
||||||
|
pub og_title: String,
|
||||||
|
pub segment: String,
|
||||||
|
pub posts: Vec<ParseResult<BlogPostMetadata>>,
|
||||||
|
pub header_props: HeaderProps,
|
||||||
|
pub tags: Vec<String>,
|
||||||
|
pub featured_projects: Vec<ParseResult<ProjectMetadata>>,
|
||||||
|
pub current_url: String,
|
||||||
|
}
|
@ -2,7 +2,6 @@ use std::{path::Path, sync::Arc};
|
|||||||
|
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use image::ImageReader;
|
use image::ImageReader;
|
||||||
use tracing::debug;
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
image_generator::generate_images,
|
image_generator::generate_images,
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
pub mod post_listing;
|
pub mod post_listing;
|
||||||
pub mod post_parser;
|
pub mod post_parser;
|
||||||
|
pub mod tags;
|
||||||
|
@ -10,7 +10,7 @@ use pulldown_cmark::{CodeBlockKind, Event, Options, Parser, Tag, TagEnd};
|
|||||||
use serde::{de::DeserializeOwned, Deserialize, Deserializer};
|
use serde::{de::DeserializeOwned, Deserialize, Deserializer};
|
||||||
use syntect::{highlighting::ThemeSet, html::highlighted_html_for_string, parsing::SyntaxSet};
|
use syntect::{highlighting::ThemeSet, html::highlighted_html_for_string, parsing::SyntaxSet};
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
use tracing::{debug, error, info};
|
use tracing::{debug, error};
|
||||||
|
|
||||||
use crate::picture_generator::{
|
use crate::picture_generator::{
|
||||||
picture_markup_generator::generate_picture_markup, resolutions::get_max_resolution,
|
picture_markup_generator::generate_picture_markup, resolutions::get_max_resolution,
|
||||||
|
@ -2,10 +2,9 @@ use axum::http::StatusCode;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::{
|
use crate::blog_posts::blog_post_model::{BlogPostMetadata, BLOG_POST_PATH};
|
||||||
blog_posts::blog_post_model::{BlogPostMetadata, BLOG_POST_PATH},
|
|
||||||
post_utils::{post_listing::get_post_list, post_parser::ParseResult},
|
use super::{post_listing::get_post_list, post_parser::ParseResult};
|
||||||
};
|
|
||||||
|
|
||||||
pub async fn get_popular_tags(segment: Option<String>) -> Result<Vec<String>, StatusCode> {
|
pub async fn get_popular_tags(segment: Option<String>) -> Result<Vec<String>, StatusCode> {
|
||||||
const TAGS_LENGTH: usize = 7;
|
const TAGS_LENGTH: usize = 7;
|
@ -3,8 +3,8 @@ use crate::{
|
|||||||
pages::{
|
pages::{
|
||||||
admin::render_admin, blog_post_list::render_blog_post_list,
|
admin::render_admin, blog_post_list::render_blog_post_list,
|
||||||
blog_post_page::render_blog_post, broadcast_list::render_broadcast_post_list,
|
blog_post_page::render_blog_post, broadcast_list::render_broadcast_post_list,
|
||||||
contact::render_contact, index::render_index, project_list::render_projects_list,
|
contact::render_contact, index::render_index, not_found::render_not_found,
|
||||||
showcase::egg_fetcher::render_egg_fetcher,
|
project_list::render_projects_list, showcase::egg_fetcher::render_egg_fetcher,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use axum::{extract::MatchedPath, http::Request, routing::get, Router};
|
use axum::{extract::MatchedPath, http::Request, routing::get, Router};
|
||||||
@ -42,4 +42,5 @@ pub fn get_router() -> Router {
|
|||||||
)
|
)
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
.fallback(render_not_found)
|
||||||
}
|
}
|
||||||
|
@ -702,6 +702,11 @@ video {
|
|||||||
margin-bottom: 1.25rem;
|
margin-bottom: 1.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mx-3 {
|
||||||
|
margin-left: 0.75rem;
|
||||||
|
margin-right: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
.mb-1 {
|
.mb-1 {
|
||||||
margin-bottom: 0.25rem;
|
margin-bottom: 0.25rem;
|
||||||
}
|
}
|
||||||
@ -818,6 +823,10 @@ video {
|
|||||||
max-width: 64rem;
|
max-width: 64rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1 1 0%;
|
||||||
|
}
|
||||||
|
|
||||||
.flex-grow {
|
.flex-grow {
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
}
|
}
|
||||||
@ -868,6 +877,10 @@ video {
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.justify-around {
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
.gap-2 {
|
.gap-2 {
|
||||||
gap: 0.5rem;
|
gap: 0.5rem;
|
||||||
}
|
}
|
||||||
@ -1034,6 +1047,16 @@ video {
|
|||||||
line-height: 1.75rem;
|
line-height: 1.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-6xl {
|
||||||
|
font-size: 3.75rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-9xl {
|
||||||
|
font-size: 8rem;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
.font-bold {
|
.font-bold {
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<a href="{{url}}" class="block no-underline border rounded-md bg-pink-200 m-4 p-4 max-w-[392px] {{class}}">
|
<a href="{{url}}" class="block no-underline border rounded-md bg-pink-200 m-4 p-4 max-w-[392px] {{class}}">
|
||||||
<header class="flex text-center justify-center items-center gap-2 mb-2">
|
<header class="flex text-center justify-center items-center gap-2 mb-2">
|
||||||
<svg aria-hidden="true" class="h-7 w-7 fill-blue-950">
|
<svg role="img" aria-label="{{svg}} icon" aria-hidden="true" class="h-7 w-7 fill-blue-950">
|
||||||
<use href="#{{svg}}" />
|
<use href="#{{svg}}" />
|
||||||
</svg>
|
</svg>
|
||||||
<h3 class="text-lg font-medium mb-1 text-blue-950 visited:text-blue-950">{{heading|safe}}</h3>
|
<h3 class="text-lg font-medium mb-1 text-blue-950 visited:text-blue-950">{{heading|safe}}</h3>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
<section class="flex border rounded bg-white m-4 p-3 max-w-[32rem]">
|
<section class="flex border rounded bg-white m-4 p-3 max-w-[32rem]">
|
||||||
<aside class="flex justify-center items-center pr-3">
|
<aside class="flex justify-center items-center pr-3">
|
||||||
<svg aria-hidden="true" class="fill-blue-950 h-12 w-12 md:h-16 md:w-16">
|
<svg role="img" aria-label="{{svg}} icon" aria-hidden="true" class="fill-blue-950 h-12 w-12 md:h-16 md:w-16">
|
||||||
<use href="#{{svg}}" />
|
<use href="#{{svg}}" />
|
||||||
</svg>
|
</svg>
|
||||||
</aside>
|
</aside>
|
||||||
|
15
templates/not_found.html
Normal file
15
templates/not_found.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block content %}
|
||||||
|
|
||||||
|
<section id="not-found-page">
|
||||||
|
<p class="mx-6 mt-3 text-4xl text-blue-950 text-center font-extrabold lg:mx-auto max-w-read">
|
||||||
|
This page doesn't exists
|
||||||
|
</p>
|
||||||
|
<p class="m-6 text-9xl text-blue-950 text-center font-extrabold lg:mx-auto max-w-read">😓
|
||||||
|
</p>
|
||||||
|
<p class="mx-6 mt-3 text-xl text-blue-950 text-center lg:mx-auto max-w-read">
|
||||||
|
check out <a href="/">introduction page</a> or <a href="/contact">contact page</a>
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
{% endblock %}
|
@ -10,8 +10,8 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
<section id="blog-container" class="lg:grid lg:grid-cols-[2fr_1fr] lg:grid-rows-[min-content_1fr] xl:gap-x-32 max-w-maxindex mx-auto">
|
<section id="post-container" class="lg:grid lg:grid-cols-[2fr_1fr] lg:grid-rows-[min-content_1fr] xl:gap-x-32 max-w-maxindex mx-auto">
|
||||||
<section id="blog-list" class="lg:row-span-2">
|
<section id="post-list" class="lg:row-span-2">
|
||||||
{% if posts.len() == 0 %}
|
{% if posts.len() == 0 %}
|
||||||
<p class="no-posts">You've found void in the space.</p>
|
<p class="no-posts">You've found void in the space.</p>
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -19,7 +19,7 @@
|
|||||||
{{title}}
|
{{title}}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<section id="blog-tags">
|
<section id="tags-list">
|
||||||
<ul class="mx-5">
|
<ul class="mx-5">
|
||||||
{% for tag in tags %}
|
{% for tag in tags %}
|
||||||
<li class="inline-block mx-0.5 p-0.5 md:text-xl">
|
<li class="inline-block mx-0.5 p-0.5 md:text-xl">
|
||||||
@ -40,7 +40,7 @@
|
|||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</section> <!-- /#blog-list -->
|
</section> <!-- /#post-list -->
|
||||||
<section id="socials" class="hidden lg:block">
|
<section id="socials" class="hidden lg:block">
|
||||||
{% include "sections/social.html" %}
|
{% include "sections/social.html" %}
|
||||||
</section> <!-- /#socials -->
|
</section> <!-- /#socials -->
|
||||||
@ -59,5 +59,5 @@
|
|||||||
<a href="/showcase">check out more projects</a>
|
<a href="/showcase">check out more projects</a>
|
||||||
</section>
|
</section>
|
||||||
</section> <!-- /#showcase -->
|
</section> <!-- /#showcase -->
|
||||||
</section> <!-- /#blog-container -->
|
</section> <!-- /#post-list-container -->
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -1,7 +1,8 @@
|
|||||||
<footer class="my-4">
|
<footer class="my-4">
|
||||||
<hr class="mb-4 border-slate-300 mx-5">
|
<hr class="mb-4 border-slate-300 mx-5">
|
||||||
|
<section class="flex justify-around">
|
||||||
<p
|
<p
|
||||||
class="text-center"
|
class="text-center flex-1"
|
||||||
xmlns:cc="http://creativecommons.org/ns#"
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
xmlns:dct="http://purl.org/dc/terms/"
|
xmlns:dct="http://purl.org/dc/terms/"
|
||||||
>
|
>
|
||||||
@ -46,7 +47,12 @@
|
|||||||
height="24"
|
height="24"
|
||||||
width="24"
|
width="24"
|
||||||
/></a>
|
/></a>
|
||||||
<!-- TODO Display link to feed with icon -->
|
|
||||||
<a href="/feed.xml" class="hidden">RSS feed</a>
|
|
||||||
</p>
|
</p>
|
||||||
|
<aside class="mx-3">
|
||||||
|
<a href="/feed.xml">
|
||||||
|
<svg role="img" aria-hidden="true" aria-label="RSS feed" class="fill-blue-950 h-6 w-6">
|
||||||
|
<use href="#rss" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
</aside>
|
||||||
</footer>
|
</footer>
|
||||||
|
Loading…
Reference in New Issue
Block a user