Añade composición de páginas basada en componentes

This commit is contained in:
Manuel Cillero 2022-02-13 20:11:33 +01:00
parent 0e3300dc90
commit 24e773c17b
30 changed files with 895 additions and 31 deletions

View file

@ -0,0 +1,77 @@
use crate::prelude::*;
pub struct Chunck {
renderable: fn() -> bool,
weight : i8,
markup : Vec<Markup>,
template : String,
}
impl PageComponent for Chunck {
fn prepare() -> Self {
Chunck {
renderable: always,
weight : 0,
markup : Vec::new(),
template : "default".to_string(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, _: &mut PageAssets) -> Markup {
html! {
@for markup in self.markup.iter() {
(*markup)
}
}
}
}
impl Chunck {
// Chunck BUILDER.
pub fn markup(markup: Markup) -> Self {
let mut chunck = Chunck::prepare();
chunck.markup.push(markup);
chunck
}
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
self.renderable = renderable;
self
}
pub fn with_weight(mut self, weight: i8) -> Self {
self.weight = weight;
self
}
pub fn add_markup(mut self, markup: Markup) -> Self {
self.markup.push(markup);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_string();
self
}
// Chunck GETTERS.
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -0,0 +1,103 @@
use crate::prelude::*;
enum ContainerType { Column, Row, Wrapper }
pub struct Container {
renderable: fn() -> bool,
weight : i8,
id : String,
container : ContainerType,
components: PageContainer,
template : String,
}
impl PageComponent for Container {
fn prepare() -> Self {
Container {
renderable: always,
weight : 0,
id : "".to_string(),
container : ContainerType::Wrapper,
components: PageContainer::new(),
template : "default".to_string(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, assets: &mut PageAssets) -> Markup {
let classes = match self.container {
ContainerType::Wrapper => "wrapper",
ContainerType::Row => "row",
ContainerType::Column => "col",
};
html! {
div class=(classes) {
(self.components.render(assets))
}
}
}
}
impl Container {
// Container BUILDER.
pub fn row() -> Self {
let mut grid = Container::prepare();
grid.container = ContainerType::Row;
grid
}
pub fn column() -> Self {
let mut grid = Container::prepare();
grid.container = ContainerType::Column;
grid
}
pub fn with_renderable(mut self, renderable: fn() -> bool) -> Self {
self.renderable = renderable;
self
}
pub fn with_weight(mut self, weight: i8) -> Self {
self.weight = weight;
self
}
pub fn with_id(mut self, id: &str) -> Self {
self.id = id.to_string();
self
}
pub fn add(mut self, component: impl PageComponent) -> Self {
self.components.add(component);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_string();
self
}
// Grid GETTERS.
pub fn id(&self) -> &str {
self.id.as_str()
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -0,0 +1,2 @@
pub mod container;
pub mod chunck;

View file

@ -1,3 +1,5 @@
//! Temas, Módulos y Componentes base.
pub mod theme;
pub mod module;
pub mod component;

View file

@ -1,4 +1,4 @@
module_name = Default homepage
module_desc = Displays a default homepage when none is configured.
greeting = Hello { $name }!
greetings = Hello { $name }!

View file

@ -1,4 +1,4 @@
module_name = Página de inicio predeterminada
module_desc = Muestra una página de inicio predeterminada cuando no hay ninguna configurada.
greeting = Hola { $name }!
greetings = ¡Hola { $name }!

View file

@ -14,26 +14,16 @@ impl Module for HomepageModule {
}
fn configure_module(&self, cfg: &mut server::web::ServiceConfig) {
cfg.service(
server::web::resource("/")
.route(server::web::get().to(greet))
);
cfg.service(
server::web::resource("/{name}")
.route(server::web::get().to(greet_with_param))
);
cfg.service(server::web::resource("/").to(home));
cfg.service(server::web::resource("/{name}").to(home));
}
}
async fn greet() -> impl server::Responder {
t("greeting", &args!["name" => config_get!("app.name")])
}
async fn greet_with_param(req: server::HttpRequest) -> server::HttpResponse {
async fn home(req: server::HttpRequest) -> server::Result<Markup> {
let name: String = req.match_info().get("name").unwrap_or("World").into();
let args = args!["name" => name];
server::HttpResponse::Ok()
.body(sycamore::render_to_string(|ctx| sycamore::view! { ctx,
p { (t("greeting", &args)) }
Page::prepare()
.add_to("content", Chunck::markup(html! {
h1 { (t("greetings", &args![ "name" => name])) }
}))
.render()
}

View file

@ -0,0 +1,9 @@
use crate::prelude::*;
pub struct MinimalTheme;
impl Theme for MinimalTheme {
fn name(&self) -> &str {
"Minimal"
}
}

1
src/base/theme/mod.rs Normal file
View file

@ -0,0 +1 @@
pub mod minimal;