update
This commit is contained in:
parent
e02def6bc1
commit
f3880d77d2
8 changed files with 265 additions and 85 deletions
|
@ -1,5 +1,10 @@
|
|||
use maud::{PreEscaped, html};
|
||||
|
||||
use crate::{
|
||||
request::{RequestContext, StringResponse},
|
||||
ui::UIWidget,
|
||||
};
|
||||
|
||||
// TODO : refactor shell
|
||||
|
||||
/// Represents the HTML structure of a page shell, including the head, body class, and body content.
|
||||
|
@ -9,9 +14,10 @@ pub struct Shell {
|
|||
/// The HTML content for the `<head>` section of the page.
|
||||
head: PreEscaped<String>,
|
||||
/// An optional class attribute for the `<body>` element.
|
||||
body_class: Option<String>,
|
||||
body_class: String,
|
||||
/// The HTML content for the static body portion.
|
||||
body_content: PreEscaped<String>,
|
||||
ui: bool,
|
||||
}
|
||||
|
||||
impl Shell {
|
||||
|
@ -25,18 +31,24 @@ impl Shell {
|
|||
/// # Returns
|
||||
/// A `Shell` instance encapsulating the provided HTML content and attributes.
|
||||
#[must_use]
|
||||
pub const fn new(
|
||||
head: PreEscaped<String>,
|
||||
body_content: PreEscaped<String>,
|
||||
body_class: Option<String>,
|
||||
pub fn new<T: UIWidget + 'static, C: UIWidget + 'static, B: UIWidget + 'static>(
|
||||
head: T,
|
||||
body_content: B,
|
||||
body_class: C,
|
||||
) -> Self {
|
||||
Self {
|
||||
head,
|
||||
body_class,
|
||||
body_content,
|
||||
head: head.render(),
|
||||
body_class: body_class.extended_class().join(" "),
|
||||
body_content: body_content.render(),
|
||||
ui: false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn use_ui(mut self) -> Self {
|
||||
self.ui = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Renders the full HTML page using the shell structure, with additional content and a title.
|
||||
///
|
||||
/// # Arguments
|
||||
|
@ -51,10 +63,15 @@ impl Shell {
|
|||
html {
|
||||
head {
|
||||
title { (title) };
|
||||
@if self.ui {
|
||||
script src="https://cdn.tailwindcss.com" {};
|
||||
script src="/assets/htmx.min.js" {};
|
||||
meta name="viewport" content="width=device-width, initial-scale=1.0";
|
||||
};
|
||||
(self.head)
|
||||
};
|
||||
@if self.body_class.is_some() {
|
||||
body class=(self.body_class.as_ref().unwrap()) {
|
||||
@if !self.body_class.is_empty() {
|
||||
body class=(self.body_class) {
|
||||
(self.body_content);
|
||||
|
||||
div id="main_content" {
|
||||
|
@ -73,4 +90,38 @@ impl Shell {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders a full page or an HTMX-compatible fragment based on the request context.
|
||||
///
|
||||
/// If the request is not an HTMX request, this function uses the provided shell to generate
|
||||
/// a full HTML page. If it is an HTMX request, only the provided content is rendered.
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `content` - The HTML content to render.
|
||||
/// * `title` - The title of the page for full-page rendering.
|
||||
/// * `ctx` - The `RequestContext` containing request metadata.
|
||||
///
|
||||
/// # Returns
|
||||
/// A `StringResponse`
|
||||
pub async fn render_page(
|
||||
&self,
|
||||
content: PreEscaped<String>,
|
||||
title: &str,
|
||||
ctx: RequestContext,
|
||||
) -> StringResponse {
|
||||
if ctx.is_htmx {
|
||||
(
|
||||
rocket::http::Status::Ok,
|
||||
(rocket::http::ContentType::HTML, content.into_string()),
|
||||
)
|
||||
} else {
|
||||
(
|
||||
rocket::http::Status::Ok,
|
||||
(
|
||||
rocket::http::ContentType::HTML,
|
||||
self.render(content, title).into_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue