parent
aa95d978ec
commit
cd8f761fcf
|
@ -98,6 +98,11 @@ impl Post {
|
|||
store::get_obj(&Self::uuid_to_post_key(uuid)).await
|
||||
}
|
||||
|
||||
pub async fn find_by_url(url: &str) -> MyResult<Post> {
|
||||
let uuid = store::get_str(&Self::url_to_mapping_key(url)).await?;
|
||||
Self::find_by_uuid(&uuid).await
|
||||
}
|
||||
|
||||
// Write the Post to KV storage; this can be a new post or
|
||||
// update to an existing post; either way, the CALLER is
|
||||
// responsible for making sure PostsList is updated with the
|
||||
|
|
47
src/lib.rs
47
src/lib.rs
|
@ -42,7 +42,52 @@ fn build_routes() -> router::Router {
|
|||
return router;
|
||||
}
|
||||
|
||||
async fn default_route(_req: Request, _url: Url) -> MyResult<Response> {
|
||||
async fn default_route(_req: Request, url: Url) -> MyResult<Response> {
|
||||
// We assume that anything that falls into this catch-all handler
|
||||
// would be either posts or 404
|
||||
// If the path doesn't end with `/`, normalize it first
|
||||
let path = url.pathname();
|
||||
if !path.ends_with("/") {
|
||||
return Response::new_with_opt_str_and_init(
|
||||
None,
|
||||
ResponseInit::new()
|
||||
.status(302)
|
||||
.headers(headers!{
|
||||
"Location" => &format!("{}{}/", url.origin(), path)
|
||||
}.as_ref())
|
||||
).internal_err();
|
||||
}
|
||||
|
||||
// TODO: handle home page and pagination on home page
|
||||
// Now we can be sure the path ends with `/`
|
||||
// (and of course it starts with `/` as per standard)
|
||||
if path.len() > 1 {
|
||||
let path = &path[1..path.len() - 1];
|
||||
if let Ok(post) = blog::Post::find_by_url(path).await {
|
||||
if post.url != path {
|
||||
// Redirect to the latest path of the post
|
||||
return Response::new_with_opt_str_and_init(
|
||||
None,
|
||||
ResponseInit::new()
|
||||
.status(301)
|
||||
.headers(headers!{
|
||||
"Location" => &format!("{}/{}/", url.origin(), post.url)
|
||||
}.as_ref())
|
||||
).internal_err();
|
||||
} else {
|
||||
// TODO: Actually render the page...
|
||||
return Response::new_with_opt_str_and_init(
|
||||
Some(&post.content),
|
||||
ResponseInit::new()
|
||||
.status(200)
|
||||
.headers(headers!{
|
||||
"Content-Type" => "text/html"
|
||||
}.as_ref())
|
||||
).internal_err();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Err(Error::NotFound("This page is not available".into()))
|
||||
}
|
||||
|
||||
|
|
11
src/sn.rs
11
src/sn.rs
|
@ -53,6 +53,17 @@ async fn get_actions(_req: Request, url: Url) -> MyResult<Response> {
|
|||
access_type: Some(AccessType::Decrypted)
|
||||
});
|
||||
|
||||
if post_exists {
|
||||
actions.push(Action {
|
||||
label: "Open Post".into(),
|
||||
url: format!("{}/{}/", origin, post.unwrap().url),
|
||||
verb: Verb::Show,
|
||||
context: Context::Item,
|
||||
content_types: vec![ContentType::Note],
|
||||
access_type: None
|
||||
})
|
||||
}
|
||||
|
||||
let info = ActionsExtension {
|
||||
identifier: CONFIG.plugin_identifier.clone(),
|
||||
name: CONFIG.title.clone(),
|
||||
|
|
Loading…
Reference in New Issue