🚧 Working on regions layout
This commit is contained in:
parent
625d16c0f2
commit
ee5742e0b2
11 changed files with 264 additions and 220 deletions
|
|
@ -43,43 +43,23 @@ impl ThemeTrait for Bootsier {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_body(&self, page: &mut Page) -> Markup {
|
fn prepare_body(&self, page: &mut Page) -> Markup {
|
||||||
let skip_to_id = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned()));
|
Body::with(match page.context().layout() {
|
||||||
|
"admin" => flex::Container::new()
|
||||||
flex::Container::body()
|
.add_item(flex::Item::region().with_id("top-menu"))
|
||||||
.with_id(page.body_id().get().unwrap_or_default())
|
.add_item(flex::Item::region().with_id("side-menu"))
|
||||||
.with_classes(ClassesOp::Add, page.body_classes().get().unwrap_or_default())
|
.add_item(flex::Item::region().with_id("content")),
|
||||||
.add_item(flex::Item::bundle()
|
_ => flex::Container::new()
|
||||||
.add_component(Html::with(html! {
|
.add_item(flex::Item::region().with_id("header"))
|
||||||
@if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
|
.add_item(flex::Item::region().with_id("nav_branding"))
|
||||||
div class="skip__to_content" {
|
.add_item(flex::Item::region().with_id("nav_main"))
|
||||||
a href=(skip_to_id) { (skip) }
|
.add_item(flex::Item::region().with_id("nav_additional"))
|
||||||
}
|
.add_item(flex::Item::region().with_id("breadcrumb"))
|
||||||
}
|
.add_item(flex::Item::region().with_id("content"))
|
||||||
}))
|
.add_item(flex::Item::region().with_id("sidebar_first"))
|
||||||
.add_component(
|
.add_item(flex::Item::region().with_id("sidebar_second"))
|
||||||
match page.context().layout() {
|
.add_item(flex::Item::region().with_id("footer")),
|
||||||
"admin" => flex::Container::new().add_item(
|
})
|
||||||
flex::Item::new()
|
.render(page.context())
|
||||||
.add_component(flex::Region::named("top-menu"))
|
|
||||||
.add_component(flex::Region::named("side-menu"))
|
|
||||||
.add_component(flex::Region::named("content")),
|
|
||||||
),
|
|
||||||
_ => flex::Container::new().add_item(
|
|
||||||
flex::Item::new()
|
|
||||||
.add_component(flex::Region::named("header"))
|
|
||||||
.add_component(flex::Region::named("nav_branding"))
|
|
||||||
.add_component(flex::Region::named("nav_main"))
|
|
||||||
.add_component(flex::Region::named("nav_additional"))
|
|
||||||
.add_component(flex::Region::named("breadcrumb"))
|
|
||||||
.add_component(flex::Region::named("content"))
|
|
||||||
.add_component(flex::Region::named("sidebar_first"))
|
|
||||||
.add_component(flex::Region::named("sidebar_second"))
|
|
||||||
.add_component(flex::Region::named("footer")),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.render(page.context())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_prepare_body(&self, page: &mut Page) {
|
fn after_prepare_body(&self, page: &mut Page) {
|
||||||
|
|
|
||||||
|
|
@ -4,5 +4,11 @@ pub use html::Html;
|
||||||
mod fluent;
|
mod fluent;
|
||||||
pub use fluent::Fluent;
|
pub use fluent::Fluent;
|
||||||
|
|
||||||
|
mod body;
|
||||||
|
pub use body::Body;
|
||||||
|
|
||||||
mod components;
|
mod components;
|
||||||
pub use components::Components;
|
pub use components::Components;
|
||||||
|
|
||||||
|
mod region;
|
||||||
|
pub use region::Region;
|
||||||
|
|
|
||||||
51
src/base/component/basic/body.rs
Normal file
51
src/base/component/basic/body.rs
Normal file
|
|
@ -0,0 +1,51 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub struct Body(MixedComponents);
|
||||||
|
|
||||||
|
impl ComponentTrait for Body {
|
||||||
|
fn new() -> Self {
|
||||||
|
Body::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
||||||
|
let skip_to_id = cx.body_skip_to().get().unwrap_or("content".to_owned());
|
||||||
|
|
||||||
|
PrepareMarkup::With(html! {
|
||||||
|
body id=[cx.body_id().get()] class=[cx.body_classes().get()] {
|
||||||
|
@if let Some(skip) = L10n::l("skip_to_content").using(cx.langid()) {
|
||||||
|
div class="skip__to_content" {
|
||||||
|
a href=(concat_string!("#", skip_to_id)) { (skip) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(self.components().render(cx))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Body {
|
||||||
|
pub fn with(component: impl ComponentTrait) -> Self {
|
||||||
|
Body::default().add_component(component)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_components(&mut self, op: AnyOp) -> &mut Self {
|
||||||
|
self.0.alter_value(op);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
pub fn add_component(mut self, component: impl ComponentTrait) -> Self {
|
||||||
|
self.0.alter_value(AnyOp::Add(AnyComponent::with(component)));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
// Body GETTERS.
|
||||||
|
|
||||||
|
pub fn components(&self) -> &MixedComponents {
|
||||||
|
&self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/base/component/basic/region.rs
Normal file
31
src/base/component/basic/region.rs
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub struct Region(OptionId);
|
||||||
|
|
||||||
|
impl ComponentTrait for Region {
|
||||||
|
fn new() -> Self {
|
||||||
|
Region::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> Option<String> {
|
||||||
|
self.0.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
||||||
|
match self.id() {
|
||||||
|
Some(id) => PrepareMarkup::With(cx.prepare_region(id)),
|
||||||
|
_ => PrepareMarkup::None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Region {
|
||||||
|
// Region BUILDER.
|
||||||
|
|
||||||
|
#[fn_builder]
|
||||||
|
pub fn alter_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.0.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,9 +4,6 @@ pub use container::Container;
|
||||||
mod item;
|
mod item;
|
||||||
pub use item::Item;
|
pub use item::Item;
|
||||||
|
|
||||||
mod region;
|
|
||||||
pub use region::Region;
|
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
// *************************************************************************************************
|
// *************************************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ use crate::prelude::*;
|
||||||
pub enum ContainerType {
|
pub enum ContainerType {
|
||||||
#[default]
|
#[default]
|
||||||
Default,
|
Default,
|
||||||
Body,
|
|
||||||
Header,
|
Header,
|
||||||
Main,
|
Main,
|
||||||
Section,
|
Section,
|
||||||
|
|
@ -77,11 +76,6 @@ impl ComponentTrait for Container {
|
||||||
(output)
|
(output)
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
ContainerType::Body => PrepareMarkup::With(html! {
|
|
||||||
body id=[self.id()] class=[self.classes().get()] style=[gap] {
|
|
||||||
(output)
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
ContainerType::Header => PrepareMarkup::With(html! {
|
ContainerType::Header => PrepareMarkup::With(html! {
|
||||||
header id=[self.id()] class=[self.classes().get()] style=[gap] {
|
header id=[self.id()] class=[self.classes().get()] style=[gap] {
|
||||||
(output)
|
(output)
|
||||||
|
|
@ -112,13 +106,6 @@ impl ComponentTrait for Container {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Container {
|
impl Container {
|
||||||
pub fn body() -> Self {
|
|
||||||
Container {
|
|
||||||
container_type: ContainerType::Body,
|
|
||||||
..Default::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn header() -> Self {
|
pub fn header() -> Self {
|
||||||
Container {
|
Container {
|
||||||
container_type: ContainerType::Header,
|
container_type: ContainerType::Header,
|
||||||
|
|
@ -210,7 +197,6 @@ impl Container {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
pub fn add_item(mut self, item: flex::Item) -> Self {
|
pub fn add_item(mut self, item: flex::Item) -> Self {
|
||||||
self.items.alter_value(AnyOp::Add(AnyComponent::with(item)));
|
self.items.alter_value(AnyOp::Add(AnyComponent::with(item)));
|
||||||
self
|
self
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use crate::prelude::*;
|
||||||
pub enum ItemType {
|
pub enum ItemType {
|
||||||
#[default]
|
#[default]
|
||||||
Default,
|
Default,
|
||||||
|
Region,
|
||||||
Wrapper,
|
Wrapper,
|
||||||
Bundle,
|
Bundle,
|
||||||
}
|
}
|
||||||
|
|
@ -57,36 +58,60 @@ impl ComponentTrait for Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
||||||
let output = self.components().render(cx);
|
let (output, region) = match self.item_type() {
|
||||||
if !output.is_empty() {
|
ItemType::Region => (
|
||||||
let order = match self.weight() {
|
self.components().render(cx),
|
||||||
0 => None,
|
if let Some(id) = self.id() {
|
||||||
_ => Some(concat_string!("order: ", self.weight().to_string(), ";")),
|
cx.prepare_region(id)
|
||||||
};
|
} else {
|
||||||
match self.item_type() {
|
Markup::default()
|
||||||
ItemType::Default => PrepareMarkup::With(html! {
|
},
|
||||||
div id=[self.id()] class=[self.classes().get()] style=[order] {
|
),
|
||||||
div class="flex__content" {
|
_ => (self.components().render(cx), Markup::default()),
|
||||||
(output)
|
};
|
||||||
}
|
if output.is_empty() && region.is_empty() {
|
||||||
}
|
return PrepareMarkup::None;
|
||||||
}),
|
}
|
||||||
ItemType::Wrapper => PrepareMarkup::With(html! {
|
let order = match self.weight() {
|
||||||
div id=[self.id()] class=[self.classes().get()] style=[order] {
|
0 => None,
|
||||||
|
_ => Some(concat_string!("order: ", self.weight().to_string(), ";")),
|
||||||
|
};
|
||||||
|
match self.item_type() {
|
||||||
|
ItemType::Default => PrepareMarkup::With(html! {
|
||||||
|
div id=[self.id()] class=[self.classes().get()] style=[order] {
|
||||||
|
div class="flex__content" {
|
||||||
(output)
|
(output)
|
||||||
}
|
}
|
||||||
}),
|
}
|
||||||
ItemType::Bundle => PrepareMarkup::With(html! {
|
}),
|
||||||
|
ItemType::Region => PrepareMarkup::With(html! {
|
||||||
|
div id=[self.id()] class=[self.classes().get()] style=[order] {
|
||||||
|
div class="flex__content flex__region" {
|
||||||
|
(region)
|
||||||
|
(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
ItemType::Wrapper => PrepareMarkup::With(html! {
|
||||||
|
div id=[self.id()] class=[self.classes().get()] style=[order] {
|
||||||
(output)
|
(output)
|
||||||
}),
|
}
|
||||||
}
|
}),
|
||||||
} else {
|
ItemType::Bundle => PrepareMarkup::With(html! {
|
||||||
PrepareMarkup::None
|
(output)
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Item {
|
impl Item {
|
||||||
|
pub fn region() -> Self {
|
||||||
|
Item {
|
||||||
|
item_type: ItemType::Region,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn wrapper() -> Self {
|
pub fn wrapper() -> Self {
|
||||||
Item {
|
Item {
|
||||||
item_type: ItemType::Wrapper,
|
item_type: ItemType::Wrapper,
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
use crate::prelude::*;
|
|
||||||
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub struct Region(OptionId);
|
|
||||||
|
|
||||||
impl ComponentTrait for Region {
|
|
||||||
fn new() -> Self {
|
|
||||||
Region::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
|
||||||
if let Some(name) = self.name().get() {
|
|
||||||
return PrepareMarkup::With(cx.prepare_region(name.as_str()));
|
|
||||||
}
|
|
||||||
PrepareMarkup::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Region {
|
|
||||||
pub fn named(name: impl Into<String>) -> Self {
|
|
||||||
Region::new().with_name(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Region BUILDER.
|
|
||||||
|
|
||||||
#[fn_builder]
|
|
||||||
pub fn alter_name(&mut self, name: impl Into<String>) -> &mut Self {
|
|
||||||
self.0.alter_value(name);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
// Region GETTERS.
|
|
||||||
|
|
||||||
pub fn name(&self) -> &OptionId {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -2,7 +2,9 @@ use crate::base::component::add_base_assets;
|
||||||
use crate::core::component::AnyOp;
|
use crate::core::component::AnyOp;
|
||||||
use crate::core::theme::all::{theme_by_single_name, THEME_DEFAULT};
|
use crate::core::theme::all::{theme_by_single_name, THEME_DEFAULT};
|
||||||
use crate::core::theme::{ComponentsInRegions, ThemeRef};
|
use crate::core::theme::{ComponentsInRegions, ThemeRef};
|
||||||
use crate::html::{html, Assets, HeadScript, HeadStyles, JavaScript, Markup, StyleSheet};
|
use crate::html::{html, Markup};
|
||||||
|
use crate::html::{Assets, HeadScript, HeadStyles, JavaScript, StyleSheet};
|
||||||
|
use crate::html::{ClassesOp, OptionClasses, OptionId};
|
||||||
use crate::locale::{LanguageIdentifier, LANGID_DEFAULT};
|
use crate::locale::{LanguageIdentifier, LANGID_DEFAULT};
|
||||||
use crate::service::HttpRequest;
|
use crate::service::HttpRequest;
|
||||||
use crate::{concat_string, util};
|
use crate::{concat_string, util};
|
||||||
|
|
@ -32,17 +34,20 @@ pub enum AssetsOp {
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
request : HttpRequest,
|
request : HttpRequest,
|
||||||
langid : &'static LanguageIdentifier,
|
langid : &'static LanguageIdentifier,
|
||||||
theme : ThemeRef,
|
theme : ThemeRef,
|
||||||
layout : &'static str,
|
layout : &'static str,
|
||||||
stylesheet: Assets<StyleSheet>, // Stylesheets.
|
stylesheet : Assets<StyleSheet>, // Stylesheets.
|
||||||
headstyles: Assets<HeadStyles>, // Styles in head.
|
headstyles : Assets<HeadStyles>, // Styles in head.
|
||||||
javascript: Assets<JavaScript>, // JavaScripts.
|
javascript : Assets<JavaScript>, // JavaScripts.
|
||||||
headscript: Assets<HeadScript>, // Scripts in head.
|
headscript : Assets<HeadScript>, // Scripts in head.
|
||||||
regions : ComponentsInRegions,
|
body_id : OptionId,
|
||||||
params : HashMap<&'static str, String>,
|
body_classes: OptionClasses,
|
||||||
id_counter: usize,
|
body_skip_to: OptionId,
|
||||||
|
regions : ComponentsInRegions,
|
||||||
|
params : HashMap<&'static str, String>,
|
||||||
|
id_counter : usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
|
|
@ -50,16 +55,19 @@ impl Context {
|
||||||
pub(crate) fn new(request: HttpRequest) -> Self {
|
pub(crate) fn new(request: HttpRequest) -> Self {
|
||||||
Context {
|
Context {
|
||||||
request,
|
request,
|
||||||
langid : &LANGID_DEFAULT,
|
langid : &LANGID_DEFAULT,
|
||||||
theme : *THEME_DEFAULT,
|
theme : *THEME_DEFAULT,
|
||||||
layout : "default",
|
layout : "default",
|
||||||
stylesheet: Assets::<StyleSheet>::new(), // Stylesheets.
|
stylesheet : Assets::<StyleSheet>::new(), // Stylesheets.
|
||||||
headstyles: Assets::<HeadStyles>::new(), // Styles in head.
|
headstyles : Assets::<HeadStyles>::new(), // Styles in head.
|
||||||
javascript: Assets::<JavaScript>::new(), // JavaScripts.
|
javascript : Assets::<JavaScript>::new(), // JavaScripts.
|
||||||
headscript: Assets::<HeadScript>::new(), // Scripts in head.
|
headscript : Assets::<HeadScript>::new(), // Scripts in head.
|
||||||
regions : ComponentsInRegions::default(),
|
body_id : OptionId::default(),
|
||||||
params : HashMap::<&str, String>::new(),
|
body_classes: OptionClasses::default(),
|
||||||
id_counter: 0,
|
body_skip_to: OptionId::default(),
|
||||||
|
regions : ComponentsInRegions::default(),
|
||||||
|
params : HashMap::<&str, String>::new(),
|
||||||
|
id_counter : 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -95,6 +103,21 @@ impl Context {
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn alter_body_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.body_id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alter_body_classes(&mut self, op: ClassesOp, classes: impl Into<String>) -> &mut Self {
|
||||||
|
self.body_classes.alter_value(op, classes);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn alter_body_skip_to(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
|
self.body_skip_to.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
pub fn alter_regions(&mut self, region: &'static str, op: AnyOp) -> &mut Self {
|
pub fn alter_regions(&mut self, region: &'static str, op: AnyOp) -> &mut Self {
|
||||||
self.regions.alter_components(region, op);
|
self.regions.alter_components(region, op);
|
||||||
self
|
self
|
||||||
|
|
@ -128,6 +151,18 @@ impl Context {
|
||||||
self.layout
|
self.layout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn body_id(&self) -> &OptionId {
|
||||||
|
&self.body_id
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn body_classes(&self) -> &OptionClasses {
|
||||||
|
&self.body_classes
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn body_skip_to(&self) -> &OptionId {
|
||||||
|
&self.body_skip_to
|
||||||
|
}
|
||||||
|
|
||||||
pub fn regions(&self) -> &ComponentsInRegions {
|
pub fn regions(&self) -> &ComponentsInRegions {
|
||||||
&self.regions
|
&self.regions
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +178,7 @@ impl Context {
|
||||||
|
|
||||||
/// Context PREPARE.
|
/// Context PREPARE.
|
||||||
|
|
||||||
pub fn prepare_assets(&mut self) -> Markup {
|
pub(crate) fn prepare_assets(&mut self) -> Markup {
|
||||||
html! {
|
html! {
|
||||||
(self.stylesheet.prepare()) // Stylesheets.
|
(self.stylesheet.prepare()) // Stylesheets.
|
||||||
(self.headstyles.prepare()) // Styles in head.
|
(self.headstyles.prepare()) // Styles in head.
|
||||||
|
|
@ -152,8 +187,10 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn prepare_region(&mut self, region: &str) -> Markup {
|
pub(crate) fn prepare_region(&mut self, region: impl Into<String>) -> Markup {
|
||||||
self.regions.all_components(self.theme, region).render(self)
|
self.regions
|
||||||
|
.all_components(self.theme, region.into().as_str())
|
||||||
|
.render(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Context EXTRAS.
|
// Context EXTRAS.
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
use crate::base::component::*;
|
use crate::base::component::*;
|
||||||
use crate::core::component::{ComponentBase, ComponentClassesOp, ComponentTrait};
|
use crate::config;
|
||||||
|
use crate::core::component::{ComponentBase, ComponentTrait};
|
||||||
use crate::core::package::PackageTrait;
|
use crate::core::package::PackageTrait;
|
||||||
use crate::html::{html, ClassesOp, Favicon, Markup};
|
use crate::html::{html, Favicon, Markup};
|
||||||
use crate::locale::L10n;
|
use crate::locale::L10n;
|
||||||
use crate::response::page::Page;
|
use crate::response::page::Page;
|
||||||
use crate::{concat_string, config};
|
|
||||||
|
|
||||||
pub type ThemeRef = &'static dyn ThemeTrait;
|
pub type ThemeRef = &'static dyn ThemeTrait;
|
||||||
|
|
||||||
|
|
@ -26,51 +26,38 @@ pub trait ThemeTrait: PackageTrait + Send + Sync {
|
||||||
fn before_prepare_body(&self, page: &mut Page) {}
|
fn before_prepare_body(&self, page: &mut Page) {}
|
||||||
|
|
||||||
fn prepare_body(&self, page: &mut Page) -> Markup {
|
fn prepare_body(&self, page: &mut Page) -> Markup {
|
||||||
let skip_to_id = concat_string!("#", page.skip_to().get().unwrap_or("content".to_owned()));
|
Body::with(
|
||||||
|
flex::Container::new()
|
||||||
flex::Container::body()
|
.with_id("body__wrapper")
|
||||||
.with_id(page.body_id().get().unwrap_or_default())
|
.with_direction(flex::Direction::Column(BreakPoint::None))
|
||||||
.with_classes(ClassesOp::Add, page.body_classes().get().unwrap_or_default())
|
.with_align(flex::Align::Center)
|
||||||
.add_item(flex::Item::bundle()
|
.add_item(flex::Item::region().with_id("header"))
|
||||||
.add_component(Html::with(html! {
|
.add_item(flex::Item::region().with_id("pagetop"))
|
||||||
@if let Some(skip) = L10n::l("skip_to_content").using(page.context().langid()) {
|
.add_item(
|
||||||
div class="skip__to_content" {
|
flex::Item::with(
|
||||||
a href=(skip_to_id) { (skip) }
|
flex::Container::new()
|
||||||
}
|
.with_direction(flex::Direction::Row(BreakPoint::None))
|
||||||
}
|
.add_item(
|
||||||
}))
|
flex::Item::region()
|
||||||
.add_component(flex::Container::new()
|
.with_id("sidebar_left")
|
||||||
.with_id("body__wrapper")
|
.with_grow(flex::Grow::Is1),
|
||||||
.with_direction(flex::Direction::Column(BreakPoint::None))
|
)
|
||||||
.with_align(flex::Align::Center)
|
.add_item(
|
||||||
.add_item(flex::Item::with(flex::Region::named("header")).with_id("header"))
|
flex::Item::region()
|
||||||
.add_item(flex::Item::with(flex::Region::named("pagetop")).with_id("pagetop"))
|
.with_id("content")
|
||||||
.add_item(
|
.with_grow(flex::Grow::Is3),
|
||||||
flex::Item::with(
|
)
|
||||||
flex::Container::new()
|
.add_item(
|
||||||
.with_direction(flex::Direction::Row(BreakPoint::None))
|
flex::Item::region()
|
||||||
.add_item(
|
.with_id("sidebar_right")
|
||||||
flex::Item::with(flex::Region::named("sidebar_left"))
|
.with_grow(flex::Grow::Is1),
|
||||||
.with_id("sidebar_left")
|
),
|
||||||
.with_grow(flex::Grow::Is1),
|
|
||||||
)
|
|
||||||
.add_item(
|
|
||||||
flex::Item::with(flex::Region::named("content"))
|
|
||||||
.with_id("content")
|
|
||||||
.with_grow(flex::Grow::Is3),
|
|
||||||
)
|
|
||||||
.add_item(
|
|
||||||
flex::Item::with(flex::Region::named("sidebar_right"))
|
|
||||||
.with_id("sidebar_right")
|
|
||||||
.with_grow(flex::Grow::Is1),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.with_id("flex__wrapper"),
|
|
||||||
)
|
)
|
||||||
.add_item(flex::Item::with(flex::Region::named("footer")).with_id("footer")),
|
.with_id("flex__wrapper"),
|
||||||
)
|
)
|
||||||
)
|
.add_item(flex::Item::region().with_id("footer")),
|
||||||
.render(page.context())
|
)
|
||||||
|
.render(page.context())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn after_prepare_body(&self, page: &mut Page) {
|
fn after_prepare_body(&self, page: &mut Page) {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,7 @@ use crate::base::action;
|
||||||
use crate::core::component::{AnyComponent, AnyOp, ComponentTrait};
|
use crate::core::component::{AnyComponent, AnyOp, ComponentTrait};
|
||||||
use crate::core::component::{AssetsOp, Context};
|
use crate::core::component::{AssetsOp, Context};
|
||||||
use crate::fn_builder;
|
use crate::fn_builder;
|
||||||
use crate::html::{html, Markup, DOCTYPE};
|
use crate::html::{html, ClassesOp, Favicon, Markup, OptionTranslated, DOCTYPE};
|
||||||
use crate::html::{ClassesOp, Favicon, OptionClasses, OptionId, OptionTranslated};
|
|
||||||
use crate::locale::L10n;
|
use crate::locale::L10n;
|
||||||
use crate::service::HttpRequest;
|
use crate::service::HttpRequest;
|
||||||
|
|
||||||
|
|
@ -16,30 +15,24 @@ use unic_langid::CharacterDirection;
|
||||||
|
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub struct Page {
|
pub struct Page {
|
||||||
title : OptionTranslated,
|
title : OptionTranslated,
|
||||||
description : OptionTranslated,
|
description: OptionTranslated,
|
||||||
metadata : Vec<(&'static str, &'static str)>,
|
metadata : Vec<(&'static str, &'static str)>,
|
||||||
properties : Vec<(&'static str, &'static str)>,
|
properties : Vec<(&'static str, &'static str)>,
|
||||||
favicon : Option<Favicon>,
|
favicon : Option<Favicon>,
|
||||||
context : Context,
|
context : Context,
|
||||||
body_id : OptionId,
|
|
||||||
body_classes: OptionClasses,
|
|
||||||
skip_to : OptionId,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Page {
|
impl Page {
|
||||||
#[rustfmt::skip]
|
#[rustfmt::skip]
|
||||||
pub fn new(request: HttpRequest) -> Self {
|
pub fn new(request: HttpRequest) -> Self {
|
||||||
Page {
|
Page {
|
||||||
title : OptionTranslated::default(),
|
title : OptionTranslated::default(),
|
||||||
description : OptionTranslated::default(),
|
description: OptionTranslated::default(),
|
||||||
metadata : Vec::default(),
|
metadata : Vec::default(),
|
||||||
properties : Vec::default(),
|
properties : Vec::default(),
|
||||||
favicon : None,
|
favicon : None,
|
||||||
context : Context::new(request),
|
context : Context::new(request),
|
||||||
body_id : OptionId::default(),
|
|
||||||
body_classes: OptionClasses::default(),
|
|
||||||
skip_to : OptionId::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,19 +76,19 @@ impl Page {
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_body_id(&mut self, id: impl Into<String>) -> &mut Self {
|
pub fn alter_body_id(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
self.body_id.alter_value(id);
|
self.context.alter_body_id(id);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_body_classes(&mut self, op: ClassesOp, classes: impl Into<String>) -> &mut Self {
|
pub fn alter_body_classes(&mut self, op: ClassesOp, classes: impl Into<String>) -> &mut Self {
|
||||||
self.body_classes.alter_value(op, classes);
|
self.context.alter_body_classes(op, classes);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
#[fn_builder]
|
#[fn_builder]
|
||||||
pub fn alter_skip_to(&mut self, id: impl Into<String>) -> &mut Self {
|
pub fn alter_body_skip_to(&mut self, id: impl Into<String>) -> &mut Self {
|
||||||
self.skip_to.alter_value(id);
|
self.context.alter_body_skip_to(id);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -153,18 +146,6 @@ impl Page {
|
||||||
&mut self.context
|
&mut self.context
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn body_id(&self) -> &OptionId {
|
|
||||||
&self.body_id
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn body_classes(&self) -> &OptionClasses {
|
|
||||||
&self.body_classes
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn skip_to(&self) -> &OptionId {
|
|
||||||
&self.skip_to
|
|
||||||
}
|
|
||||||
|
|
||||||
// Page RENDER.
|
// Page RENDER.
|
||||||
|
|
||||||
pub fn render(&mut self) -> ResultPage<Markup, ErrorPage> {
|
pub fn render(&mut self) -> ResultPage<Markup, ErrorPage> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue