Generate post links, so far only top-level.

This commit is contained in:
Tom Alexander 2023-12-23 21:06:53 -05:00
parent 6a086d57de
commit 24218f2979
Signed by: talexander
GPG Key ID: D3A179C9A53C0EDE
3 changed files with 33 additions and 10 deletions

View File

@ -1 +1 @@
<a href="{.raw_link}">{#.children}{>object/}{/.children}</a>
<a href="{.target}">{#.children}{>object/}{/.children}</a>

View File

@ -28,7 +28,7 @@ render!(RenderRegularLink, IRegularLink, original, render_context, {
let target = original
.target
.generate_final_target()?
.generate_final_target(render_context.clone())?
.unwrap_or_else(|| "".to_owned());
Ok(RenderRegularLink {

View File

@ -1,9 +1,11 @@
use organic::types::StandardProperties;
use url::Url;
use super::get_web_path;
use super::macros::intermediate;
use super::IObject;
use crate::context::RenderContext;
use crate::error::CustomError;
#[derive(Debug, Clone)]
@ -47,14 +49,16 @@ pub(crate) enum LinkTarget {
impl LinkTarget {
pub(crate) fn from_string<S: AsRef<str>>(input: S) -> Result<LinkTarget, CustomError> {
fn impl_from_string(input: &str) -> Result<LinkTarget, CustomError> {
let parsed = Url::parse(input)?;
let parsed = Url::parse(input);
if let Err(url::ParseError::RelativeUrlWithoutBase) = parsed {
// For URLs to targets.
// TODO: This shouldn't be raw but instead a variant for targets.
return Ok(LinkTarget::Raw(input.to_owned()));
}
let parsed = parsed?;
match parsed.scheme() {
"post" => {
let post_id = parsed
.path_segments()
.ok_or_else(|| "cannot be base")?
.next()
.map(str::to_owned);
let post_id = parsed.host_str().map(str::to_owned);
Ok(LinkTarget::Post { post_id })
}
_ => Ok(LinkTarget::Raw(input.to_owned())),
@ -63,7 +67,26 @@ impl LinkTarget {
impl_from_string(input.as_ref())
}
pub(crate) fn generate_final_target(&self) -> Result<Option<String>, CustomError> {
todo!()
pub(crate) fn generate_final_target(
&self,
render_context: RenderContext<'_>,
) -> Result<Option<String>, CustomError> {
match self {
LinkTarget::Raw(raw_link) => Ok(Some(raw_link.clone())),
LinkTarget::Post { post_id } => {
let path = post_id
.as_ref()
.map(|post_id| {
get_web_path(
render_context.config,
render_context.output_root_directory,
render_context.output_file,
render_context.config.get_relative_path_to_post(post_id),
)
})
.map_or(Ok(None), |r| r.map(Some))?;
Ok(path)
}
}
}
}