Begin add PostPage
This commit is contained in:
parent
6ef76ea48d
commit
dcb5026a66
4 changed files with 45 additions and 5 deletions
|
@ -16,11 +16,12 @@ pub fn App() -> impl IntoView {
|
||||||
<Router>
|
<Router>
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="" view=pages::Home />
|
<Route path="" view=pages::Home />
|
||||||
<Route path="posts" view=|| view! {
|
<Route path="posts" view=|| view! { <pages::PostList folder="posts".to_string() /> } />
|
||||||
|
<Route path="posts/:slug" view=|| view! {
|
||||||
<Link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css"/>
|
<Link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css"/>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
|
||||||
<script>hljs.highlightAll();</script>
|
<script>hljs.highlightAll();</script>
|
||||||
<pages::PostList folder="posts".to_string() />
|
<pages::PostElement folder="posts".to_string() />
|
||||||
} />
|
} />
|
||||||
<Route path="/*any" view=|| view! { <h1>"Not Found"</h1> }/>
|
<Route path="/*any" view=|| view! { <h1>"Not Found"</h1> }/>
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
|
@ -11,6 +11,7 @@ pub struct PostMetadata {
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug)]
|
#[derive(Clone, Serialize, Deserialize, Debug)]
|
||||||
pub struct Post {
|
pub struct Post {
|
||||||
|
pub slug : String,
|
||||||
pub metadata: PostMetadata,
|
pub metadata: PostMetadata,
|
||||||
pub content: String,
|
pub content: String,
|
||||||
}
|
}
|
||||||
|
@ -26,6 +27,7 @@ cfg_if::cfg_if! {
|
||||||
.parse_with_struct::<PostMetadata>(&content)?;
|
.parse_with_struct::<PostMetadata>(&content)?;
|
||||||
|
|
||||||
let metadata = post_data.data;
|
let metadata = post_data.data;
|
||||||
|
let slug = format!("{}_{}", metadata.date, metadata.title.to_lowercase().replace(' ', "_"));
|
||||||
let content = post_data.content;
|
let content = post_data.content;
|
||||||
|
|
||||||
use pulldown_cmark::{Parser, Options, html};
|
use pulldown_cmark::{Parser, Options, html};
|
||||||
|
@ -34,6 +36,7 @@ cfg_if::cfg_if! {
|
||||||
html::push_html(&mut html_output, parser);
|
html::push_html(&mut html_output, parser);
|
||||||
|
|
||||||
Some(Self {
|
Some(Self {
|
||||||
|
slug,
|
||||||
metadata,
|
metadata,
|
||||||
content: html_output,
|
content: html_output,
|
||||||
})
|
})
|
||||||
|
|
|
@ -2,4 +2,4 @@ mod home;
|
||||||
pub use home::Home;
|
pub use home::Home;
|
||||||
|
|
||||||
mod posts;
|
mod posts;
|
||||||
pub use posts::PostList;
|
pub use posts::{PostList, PostElement};
|
|
@ -11,6 +11,20 @@ pub async fn get_posts(
|
||||||
Ok(posts)
|
Ok(posts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[server]
|
||||||
|
pub async fn get_post(
|
||||||
|
folder: String,
|
||||||
|
slug: String
|
||||||
|
) -> Result<Post, ServerFnError> {
|
||||||
|
let posts = Post::get_all(&folder)
|
||||||
|
.map_err(|e| ServerFnError::ServerError(e.to_string()))?;
|
||||||
|
|
||||||
|
let post = posts.into_iter().find(|post| post.slug == slug)
|
||||||
|
.ok_or(ServerFnError::ServerError("Post not found".to_string()))?;
|
||||||
|
|
||||||
|
Ok(post)
|
||||||
|
}
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn PostList(
|
pub fn PostList(
|
||||||
folder: String
|
folder: String
|
||||||
|
@ -22,8 +36,7 @@ pub fn PostList(
|
||||||
posts.iter()
|
posts.iter()
|
||||||
.map(|post| view! {
|
.map(|post| view! {
|
||||||
<li>
|
<li>
|
||||||
{post.metadata.title.clone()}
|
<a href={format!("/posts/{}", post.slug.clone())}>{post.metadata.title.clone()}</a>
|
||||||
<div inner_html=post.content.clone() />
|
|
||||||
</li>
|
</li>
|
||||||
})
|
})
|
||||||
.collect_view()
|
.collect_view()
|
||||||
|
@ -39,4 +52,27 @@ pub fn PostList(
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</main>
|
</main>
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
pub fn PostElement(
|
||||||
|
folder: String,
|
||||||
|
) -> impl IntoView {
|
||||||
|
let post = create_resource(|| (), |_| get_post("posts".to_string(), "2023-11-26_testing_layout".to_string()));
|
||||||
|
|
||||||
|
let post_view = move || {
|
||||||
|
post.and_then(|post| {
|
||||||
|
view! {
|
||||||
|
<div inner_html={post.content.clone()}></div>
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
view! {
|
||||||
|
<main class="m-0 p-0 bg-surface dark:bg-dark_surface text-on_surface dark:text-dark_on_surface">
|
||||||
|
<Suspense fallback=move || view! { <p>"Loading posts..."</p> }>
|
||||||
|
{post_view}
|
||||||
|
</Suspense>
|
||||||
|
</main>
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue