Modifica la estructura general del código fuente

Importante actualización que reorganiza el código fuente de PageTop. Usa
Cargo para crear un espacio de trabajo con los diferentes proyectos que
estructuran las funcionalidades de PageTop en módulos interdependientes
que se integran en Drust para construir una solución web para la gestión
de contenidos.
This commit is contained in:
Manuel Cillero 2022-03-13 11:14:33 +01:00
parent 4b5d8ce38a
commit ab0ac11f65
83 changed files with 115 additions and 81 deletions

View file

@ -1,105 +0,0 @@
use crate::prelude::*;
pub struct Block {
renderable: fn() -> bool,
weight : i8,
id : Option<String>,
title : Option<String>,
markup : Vec<Markup>,
template : String,
}
impl PageComponent for Block {
fn prepare() -> Self {
Block {
renderable: always,
weight : 0,
id : None,
title : None,
markup : Vec::new(),
template : "default".to_owned(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, assets: &mut PageAssets) -> Markup {
let id = assets.serial_id(self.name(), self.id());
html! {
div id=(id) class="block" {
@if self.title != None {
h2 class="block-title" { (self.title()) }
}
div class="block-body" {
@for markup in self.markup.iter() {
(*markup)
}
}
}
}
}
}
impl Block {
pub fn markup(markup: Markup) -> Self {
Block::prepare().add_markup(markup)
}
// Block BUILDER.
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 = util::valid_id(id);
self
}
pub fn with_title(mut self, title: &str) -> Self {
self.title = util::optional_str(title);
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_owned();
self
}
// Block GETTERS.
pub fn id(&self) -> &str {
util::assigned_str(&self.id)
}
pub fn title(&self) -> &str {
util::assigned_str(&self.title)
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,75 +0,0 @@
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_owned(),
}
}
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 {
pub fn markup(markup: Markup) -> Self {
Chunck::prepare().add_markup(markup)
}
// Chunck BUILDER.
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_owned();
self
}
// Chunck GETTERS.
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,103 +0,0 @@
use crate::prelude::*;
enum ContainerType { Column, Row, Wrapper }
pub struct Container {
renderable: fn() -> bool,
weight : i8,
id : Option<String>,
container : ContainerType,
components: PageContainer,
template : String,
}
impl PageComponent for Container {
fn prepare() -> Self {
Container {
renderable: always,
weight : 0,
id : None,
container : ContainerType::Wrapper,
components: PageContainer::new(),
template : "default".to_owned(),
}
}
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 => "container",
ContainerType::Row => "row",
ContainerType::Column => "col",
};
html! {
div id=[&self.id] class=(classes) {
(self.components.render(assets))
}
}
}
}
impl Container {
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
}
// Container BUILDER.
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 = util::valid_id(id);
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_owned();
self
}
// Container GETTERS.
pub fn id(&self) -> &str {
util::assigned_str(&self.id)
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,160 +0,0 @@
use crate::prelude::*;
enum ButtonType {Button, Reset, Submit}
pub struct Button {
renderable : fn() -> bool,
weight : i8,
button_type: ButtonType,
name : Option<String>,
value : Option<String>,
autofocus : Option<String>,
disabled : Option<String>,
template : String,
}
impl PageComponent for Button {
fn prepare() -> Self {
Button {
renderable : always,
weight : 0,
button_type: ButtonType::Button,
name : None,
value : None,
autofocus : None,
disabled : None,
template : "default".to_owned(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, _: &mut PageAssets) -> Markup {
let (button_type, button_class) = match &self.button_type {
ButtonType::Button => ("button", "btn btn-primary form-button"),
ButtonType::Reset => ("reset", "btn btn-primary form-reset" ),
ButtonType::Submit => ("submit", "btn btn-primary form-submit")
};
let id_item = match &self.name {
Some(name) => Some(format!("edit-{}", name)),
_ => None
};
html! {
button
type=(button_type)
id=[&id_item]
class=(button_class)
name=[&self.name]
value=[&self.value]
autofocus=[&self.autofocus]
disabled=[&self.disabled]
{
@match &self.value {
Some(value) => (value),
_ => ""
};
}
}
}
}
impl Button {
pub fn button(value: &str) -> Self {
Button::prepare().with_value(value)
}
pub fn reset(value: &str) -> Self {
let mut button = Button::prepare().with_value(value);
button.button_type = ButtonType::Reset;
button
}
pub fn submit(value: &str) -> Self {
let mut button = Button::prepare().with_value(value);
button.button_type = ButtonType::Submit;
button
}
// Button BUILDER.
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_name(mut self, name: &str) -> Self {
self.name = util::valid_id(name);
self
}
pub fn with_value(mut self, value: &str) -> Self {
self.value = util::optional_str(value);
self
}
pub fn autofocus(mut self, toggle: bool) -> Self {
self.autofocus = match toggle {
true => Some("autofocus".to_owned()),
false => None
};
self
}
pub fn disabled(mut self, toggle: bool) -> Self {
self.disabled = match toggle {
true => Some("disabled".to_owned()),
false => None
};
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_owned();
self
}
// Button GETTERS.
pub fn name(&self) -> &str {
util::assigned_str(&self.name)
}
pub fn value(&self) -> &str {
util::assigned_str(&self.value)
}
pub fn has_autofocus(&self) -> bool {
match &self.autofocus {
Some(_) => true,
_ => false
}
}
pub fn is_disabled(&self) -> bool {
match &self.disabled {
Some(_) => true,
_ => false
}
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,243 +0,0 @@
use crate::prelude::*;
pub struct Date {
renderable : fn() -> bool,
weight : i8,
name : Option<String>,
value : Option<String>,
label : Option<String>,
placeholder : Option<String>,
autofocus : Option<String>,
autocomplete: Option<String>,
disabled : Option<String>,
readonly : Option<String>,
required : Option<String>,
help_text : Option<String>,
template : String,
}
impl PageComponent for Date {
fn prepare() -> Self {
Date {
renderable : always,
weight : 0,
name : None,
value : None,
label : None,
placeholder : None,
autofocus : None,
autocomplete: None,
disabled : None,
readonly : None,
required : None,
help_text : None,
template : "default".to_owned(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, _: &mut PageAssets) -> Markup {
let (class_item, id_item) = match &self.name {
Some(name) => (
format!("form-item form-item-{} form-type-date", name),
Some(format!("edit-{}", name))
),
None => (
"form-item form-type-date".to_owned(),
None
)
};
html! {
div class=(class_item) {
@if self.label != None {
label class="form-label" for=[&id_item] {
(self.label()) " "
@if self.required != None {
span
class="form-required"
title="Este campo es obligatorio."
{
"*"
} " "
}
}
}
input
type="date"
id=[&id_item]
class="form-control"
name=[&self.name]
value=[&self.value]
placeholder=[&self.placeholder]
autofocus=[&self.autofocus]
autocomplete=[&self.autocomplete]
readonly=[&self.readonly]
required=[&self.required]
disabled=[&self.disabled];
@if self.help_text != None {
div class="form-text" {
(self.help_text())
}
}
}
}
}
}
impl Date {
// Date BUILDER.
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_name(mut self, name: &str) -> Self {
self.name = util::valid_id(name);
self
}
pub fn with_value(mut self, value: &str) -> Self {
self.value = util::optional_str(value);
self
}
pub fn with_label(mut self, label: &str) -> Self {
self.label = util::optional_str(label);
self
}
pub fn with_placeholder(mut self, placeholder: &str) -> Self {
self.placeholder = util::optional_str(placeholder);
self
}
pub fn autofocus(mut self, toggle: bool) -> Self {
self.autofocus = match toggle {
true => Some("autofocus".to_owned()),
false => None
};
self
}
pub fn autocomplete(mut self, toggle: bool) -> Self {
self.autocomplete = match toggle {
true => None,
false => Some("off".to_owned())
};
self
}
pub fn disabled(mut self, toggle: bool) -> Self {
self.disabled = match toggle {
true => Some("disabled".to_owned()),
false => None
};
self
}
pub fn readonly(mut self, toggle: bool) -> Self {
self.readonly = match toggle {
true => Some("readonly".to_owned()),
false => None
};
self
}
pub fn required(mut self, toggle: bool) -> Self {
self.required = match toggle {
true => Some("required".to_owned()),
false => None
};
self
}
pub fn with_help_text(mut self, help_text: &str) -> Self {
self.help_text = util::optional_str(help_text);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_owned();
self
}
// Date GETTERS.
pub fn name(&self) -> &str {
util::assigned_str(&self.name)
}
pub fn value(&self) -> &str {
util::assigned_str(&self.value)
}
pub fn label(&self) -> &str {
util::assigned_str(&self.label)
}
pub fn placeholder(&self) -> &str {
util::assigned_str(&self.placeholder)
}
pub fn has_autofocus(&self) -> bool {
match &self.autofocus {
Some(_) => true,
_ => false
}
}
pub fn has_autocomplete(&self) -> bool {
match &self.autocomplete {
Some(_) => false,
_ => true
}
}
pub fn is_disabled(&self) -> bool {
match &self.disabled {
Some(_) => true,
_ => false
}
}
pub fn is_readonly(&self) -> bool {
match &self.readonly {
Some(_) => true,
_ => false
}
}
pub fn is_required(&self) -> bool {
match &self.required {
Some(_) => true,
_ => false
}
}
pub fn help_text(&self) -> &str {
util::assigned_str(&self.help_text)
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,131 +0,0 @@
use crate::prelude::*;
pub enum FormMethod {Get, Post}
pub struct Form {
renderable: fn() -> bool,
weight : i8,
id : Option<String>,
action : Option<String>,
method : FormMethod,
charset : Option<String>,
elements : PageContainer,
template : String,
}
impl PageComponent for Form {
fn prepare() -> Self {
Form {
renderable: always,
weight : 0,
id : None,
action : None,
method : FormMethod::Post,
charset : Some("UTF-8".to_owned()),
elements : PageContainer::new(),
template : "default".to_owned(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, assets: &mut PageAssets) -> Markup {
let method = match self.method {
FormMethod::Get => None,
FormMethod::Post => Some("post".to_owned())
};
html! {
form
id=[&self.id]
action=[&self.action]
method=[method]
accept-charset=[&self.charset]
{
div {
(self.elements.render(assets))
}
}
}
}
}
impl Form {
// Form BUILDER.
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 = util::valid_id(id);
self
}
pub fn with_action(mut self, action: &str) -> Self {
self.action = util::optional_str(action);
self
}
pub fn with_method(mut self, method: FormMethod) -> Self {
self.method = method;
self
}
pub fn with_charset(mut self, charset: &str) -> Self {
self.charset = util::optional_str(charset);
self
}
pub fn add(mut self, element: impl PageComponent) -> Self {
self.elements.add(element);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_owned();
self
}
// Form GETTERS.
pub fn id(&self) -> &str {
util::assigned_str(&self.id)
}
pub fn action(&self) -> &str {
util::assigned_str(&self.action)
}
pub fn method(&self) -> &str {
match &self.method {
FormMethod::Get => "get",
FormMethod::Post => "post"
}
}
pub fn charset(&self) -> &str {
util::assigned_str(&self.charset)
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,70 +0,0 @@
use crate::prelude::*;
pub struct Hidden {
weight : i8,
name : Option<String>,
value : Option<String>,
}
impl PageComponent for Hidden {
fn prepare() -> Self {
Hidden {
weight : 0,
name : None,
value : None,
}
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, _: &mut PageAssets) -> Markup {
let id_item = match &self.name {
Some(name) => Some(format!("value-{}", name)),
_ => None
};
html! {
input
type="hidden"
id=[&id_item]
name=[&self.name]
value=[&self.value];
}
}
}
impl Hidden {
pub fn set(name: &str, value: &str) -> Self {
Hidden::prepare().with_name(name).with_value(value)
}
// Hidden BUILDER.
pub fn with_weight(mut self, weight: i8) -> Self {
self.weight = weight;
self
}
pub fn with_name(mut self, name: &str) -> Self {
self.name = util::valid_id(name);
self
}
pub fn with_value(mut self, value: &str) -> Self {
self.value = util::optional_str(value);
self
}
// Hidden GETTERS.
pub fn name(&self) -> &str {
util::assigned_str(&self.name)
}
pub fn value(&self) -> &str {
util::assigned_str(&self.value)
}
}

View file

@ -1,325 +0,0 @@
use crate::prelude::*;
enum InputType {Email, Password, Search, Telephone, Textfield, Url}
pub struct Input {
renderable : fn() -> bool,
weight : i8,
input_type : InputType,
name : Option<String>,
value : Option<String>,
label : Option<String>,
size : Option<u16>,
minlength : Option<u16>,
maxlength : Option<u16>,
placeholder : Option<String>,
autofocus : Option<String>,
autocomplete: Option<String>,
disabled : Option<String>,
readonly : Option<String>,
required : Option<String>,
help_text : Option<String>,
template : String,
}
impl PageComponent for Input {
fn prepare() -> Self {
Input {
renderable : always,
weight : 0,
input_type : InputType::Textfield,
name : None,
value : None,
label : None,
size : Some(60),
minlength : None,
maxlength : Some(128),
placeholder : None,
autofocus : None,
autocomplete: None,
disabled : None,
readonly : None,
required : None,
help_text : None,
template : "default".to_owned(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, _: &mut PageAssets) -> Markup {
let (input_type, class_type) = match &self.input_type {
InputType::Email => ("email", "form-type-email"),
InputType::Password => ("password", "form-type-password"),
InputType::Search => ("search", "form-type-search"),
InputType::Telephone => ("tel", "form-type-telephone"),
InputType::Textfield => ("text", "form-type-textfield"),
InputType::Url => ("url", "form-type-url")
};
let (class_item, id_item) = match &self.name {
Some(name) => (
format!("form-item form-item-{} {}", name, class_type),
Some(format!("edit-{}", name))
),
None => (
format!("form-item {}", class_type),
None
)
};
html! {
div class=(class_item) {
@if self.label != None {
label class="form-label" for=[&id_item] {
(self.label()) " "
@if self.required != None {
span
class="form-required"
title="Este campo es obligatorio."
{
"*"
} " "
}
}
}
input
type=(input_type)
id=[&id_item]
class="form-control"
name=[&self.name]
value=[&self.value]
size=[self.size]
minlength=[self.minlength]
maxlength=[self.maxlength]
placeholder=[&self.placeholder]
autofocus=[&self.autofocus]
autocomplete=[&self.autocomplete]
readonly=[&self.readonly]
required=[&self.required]
disabled=[&self.disabled];
@if self.help_text != None {
div class="form-text" {
(self.help_text())
}
}
}
}
}
}
impl Input {
pub fn textfield() -> Self {
Input::prepare()
}
pub fn password() -> Self {
let mut input = Input::prepare();
input.input_type = InputType::Password;
input
}
pub fn search() -> Self {
let mut input = Input::prepare();
input.input_type = InputType::Search;
input
}
pub fn email() -> Self {
let mut input = Input::prepare();
input.input_type = InputType::Email;
input
}
pub fn telephone() -> Self {
let mut input = Input::prepare();
input.input_type = InputType::Telephone;
input
}
pub fn url() -> Self {
let mut input = Input::prepare();
input.input_type = InputType::Url;
input
}
// Input BUILDER.
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_name(mut self, name: &str) -> Self {
self.name = util::valid_id(name);
self
}
pub fn with_value(mut self, value: &str) -> Self {
self.value = util::optional_str(value);
self
}
pub fn with_label(mut self, label: &str) -> Self {
self.label = util::optional_str(label);
self
}
pub fn with_size(mut self, size: Option<u16>) -> Self {
self.size = size;
self
}
pub fn with_minlength(mut self, minlength: Option<u16>) -> Self {
self.minlength = minlength;
self
}
pub fn with_maxlength(mut self, maxlength: Option<u16>) -> Self {
self.maxlength = maxlength;
self
}
pub fn with_placeholder(mut self, placeholder: &str) -> Self {
self.placeholder = util::optional_str(placeholder);
self
}
pub fn autofocus(mut self, toggle: bool) -> Self {
self.autofocus = match toggle {
true => Some("autofocus".to_owned()),
false => None
};
self
}
pub fn autocomplete(mut self, toggle: bool) -> Self {
self.autocomplete = match toggle {
true => None,
false => Some("off".to_owned())
};
self
}
pub fn disabled(mut self, toggle: bool) -> Self {
self.disabled = match toggle {
true => Some("disabled".to_owned()),
false => None
};
self
}
pub fn readonly(mut self, toggle: bool) -> Self {
self.readonly = match toggle {
true => Some("readonly".to_owned()),
false => None
};
self
}
pub fn required(mut self, toggle: bool) -> Self {
self.required = match toggle {
true => Some("required".to_owned()),
false => None
};
self
}
pub fn with_help_text(mut self, help_text: &str) -> Self {
self.help_text = util::optional_str(help_text);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_owned();
self
}
// Input GETTERS.
pub fn name(&self) -> &str {
util::assigned_str(&self.name)
}
pub fn value(&self) -> &str {
util::assigned_str(&self.value)
}
pub fn label(&self) -> &str {
util::assigned_str(&self.label)
}
pub fn size(&self) -> Option<u16> {
self.size
}
pub fn minlength(&self) -> Option<u16> {
self.minlength
}
pub fn maxlength(&self) -> Option<u16> {
self.maxlength
}
pub fn placeholder(&self) -> &str {
util::assigned_str(&self.placeholder)
}
pub fn has_autofocus(&self) -> bool {
match &self.autofocus {
Some(_) => true,
_ => false
}
}
pub fn has_autocomplete(&self) -> bool {
match &self.autocomplete {
Some(_) => false,
_ => true
}
}
pub fn is_disabled(&self) -> bool {
match &self.disabled {
Some(_) => true,
_ => false
}
}
pub fn is_readonly(&self) -> bool {
match &self.readonly {
Some(_) => true,
_ => false
}
}
pub fn is_required(&self) -> bool {
match &self.required {
Some(_) => true,
_ => false
}
}
pub fn help_text(&self) -> &str {
util::assigned_str(&self.help_text)
}
pub fn template(&self) -> &str {
self.template.as_str()
}
}
fn always() -> bool {
true
}

View file

@ -1,11 +0,0 @@
mod form;
pub use form::{Form, FormMethod};
mod input;
pub use input::Input;
mod hidden;
pub use hidden::Hidden;
mod date;
pub use date::Date;
mod button;
pub use button::Button;

View file

@ -1,252 +0,0 @@
use crate::prelude::*;
enum MenuItemType {
Label(String),
Link(String, String),
LinkBlank(String, String),
Markup(Markup),
Separator,
Submenu(String, Menu),
}
// -----------------------------------------------------------------------------
// MenuItem.
// -----------------------------------------------------------------------------
pub struct MenuItem {
renderable: fn() -> bool,
weight : i8,
item_type : Option<MenuItemType>,
}
impl PageComponent for MenuItem {
fn prepare() -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : None,
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, assets: &mut PageAssets) -> Markup {
match &self.item_type {
Some(MenuItemType::Label(label)) => html! {
li class="label" { a href="#" { (label) } }
},
Some(MenuItemType::Link(label, path)) => html! {
li class="link" { a href=(path) { (label) } }
},
Some(MenuItemType::LinkBlank(label, path)) => html! {
li class="link_blank" {
a href=(path) target="_blank" { (label) }
}
},
Some(MenuItemType::Markup(markup)) => html! {
li class="markup" { (*markup) }
},
Some(MenuItemType::Submenu(label, menu)) => html! {
li class="submenu" {
a href="#" { (label) }
ul {
(menu.render_items(assets))
}
}
},
Some(MenuItemType::Separator) => html! {
li class="separator" { }
},
None => html! {}
}
}
}
impl MenuItem {
pub fn label(label: &str) -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : Some(MenuItemType::Label(label.to_owned())),
}
}
pub fn link(label: &str, path: &str) -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : Some(MenuItemType::Link(
label.to_owned(),
path.to_owned(),
)),
}
}
pub fn link_blank(label: &str, path: &str) -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : Some(MenuItemType::LinkBlank(
label.to_owned(),
path.to_owned(),
)),
}
}
pub fn markup(markup: Markup) -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : Some(MenuItemType::Markup(markup)),
}
}
pub fn separator() -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : Some(MenuItemType::Separator),
}
}
pub fn submenu(label: &str, menu: Menu) -> Self {
MenuItem {
renderable: always,
weight : 0,
item_type : Some(MenuItemType::Submenu(
label.to_owned(),
menu
)),
}
}
// MenuItem BUILDER.
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
}
}
// -----------------------------------------------------------------------------
// Menu.
// -----------------------------------------------------------------------------
pub struct Menu {
renderable: fn() -> bool,
weight : i8,
id : Option<String>,
items : PageContainer,
template : String,
}
impl PageComponent for Menu {
fn prepare() -> Self {
Menu {
renderable: always,
weight : 0,
id : None,
items : PageContainer::new(),
template : "default".to_owned(),
}
}
fn is_renderable(&self) -> bool {
(self.renderable)()
}
fn weight(&self) -> i8 {
self.weight
}
fn default_render(&self, assets: &mut PageAssets) -> Markup {
assets
.add_stylesheet(StyleSheet::source(
"/theme/menu/css/menu.css?ver=1.1.1"
))
.add_stylesheet(StyleSheet::source(
"/theme/menu/css/menu-clean.css?ver=1.1.1"
))
.add_javascript(JavaScript::source(
"/theme/menu/js/menu.min.js?ver=1.1.1"
))
.add_jquery();
let id = assets.serial_id(self.name(), self.id());
html! {
ul id=(id) class="sm sm-clean" {
(self.render_items(assets))
}
script type="text/javascript" defer {
"jQuery(function(){jQuery('#" (id) "').smartmenus({"
"hideTimeout: 0,"
"showTimeout: 80,"
"});});"
}
}
}
}
impl Menu {
// Menu BUILDER.
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 = util::valid_id(id);
self
}
pub fn add(mut self, item: MenuItem) -> Self {
self.items.add(item);
self
}
pub fn using_template(mut self, template: &str) -> Self {
self.template = template.to_owned();
self
}
// Menu GETTERS.
pub fn id(&self) -> &str {
util::assigned_str(&self.id)
}
pub fn template(&self) -> &str {
self.template.as_str()
}
// Menu EXTRAS.
pub fn render_items(&self, assets: &mut PageAssets) -> Markup {
html! { (self.items.render(assets)) }
}
}
fn always() -> bool {
true
}

View file

@ -1,11 +0,0 @@
mod container;
pub use container::Container;
mod chunck;
pub use chunck::Chunck;
mod block;
pub use block::Block;
mod menu;
pub use menu::{Menu, MenuItem};
pub mod form;
pub use form::{Form, FormMethod};