Skip to content

Instantly share code, notes, and snippets.

@KES777
Created March 3, 2018 16:48
Show Gist options
  • Save KES777/1598d226fbe460663f464a23b88e3dff to your computer and use it in GitHub Desktop.
Save KES777/1598d226fbe460663f464a23b88e3dff to your computer and use it in GitHub Desktop.
Mojolicious Theming
...
sub startup {
...
$app->hook( before_render => sub{
my( $c, $args ) = @_;
my $theme = $c->stash->{ theme } // '';
$args->{template} = "$theme/$args->{template}";
# But here we get two problems:
# 1. $args->{ template } does not exists for routes without actions
# Template is defined too late: https://github.com/kraih/mojo/blob/master/lib/Mojolicious/Renderer.pm#L109
# 2. We can not fallback to default template if it is not found
});
}
package Mojolicious::Plugin::Control::Input;
use Mojo::Base 'Mojolicious::Plugin';
sub register {
my( $plugin, $app, $conf ) = @_;
$app->helper( input_field => sub{ input( $plugin, @_ ) } );
$app->helper( form_field => sub{ input( $plugin, @_ ) } );
# Mark this package as class with static files in DATA section
push @{ $app->static->classes }, __PACKAGE__;
# Mark this package as class with template files in DATA section
push @{ $app->renderer->classes }, __PACKAGE__;
}
sub id {
my( $p, $c ) = @_;
my $id = $c->stash->{ control }{ input }++;
unless( $id ) {
$c->content_for( stylesheets =>
$c->stylesheet( '/control/input.css' )
);
}
return $id;
}
use Mojo::ByteStream 'b';
sub input {
my( $p, $c, $name ) = (shift, shift, shift);
my %attrs = @_ % 2 ? (value => shift, @_) : @_;
my $id = $p->id( $c ); # Always call id. This loads CSS
$attrs{ id } //= "input$id";
return $c->render_to_string( "control/input",
args => { name => $name, %attrs },
);
}
1;
__DATA__
@@ control/input.html.ep
%= label_for $args->{ name }, $args->{ title }
%= text_field $args->{ name }, %$args}
@@ v2/control/input.html.ep
<div class="form__field">
%= label_for $args->{ id }, $args->{ title }, class => 'form__label'
%= input_tag $args->{ name }, class => 'form__input', type => 'text', %$args
</div>
@@ control/input.css
form .form__label {
min-width: 200px;
max_width: 200px;
}
.form__header {
color: #2F80ED;
font-weight: 500;
margin-bottom: 20px;
}
.form__field {
display: flex;
align-items: flex-start;
margin-bottom: 10px;
}
.form__label {
padding-top: 10px;
color: #5B5F7E;
font-weight: 500;
}
.form__inputs {
display: flex;
flex-direction: column;
}
.form__input {
padding: 10px;
font-size: 1rem;
color: #fff;
background-color: transparent;
border: 1px solid #5B5F7E;
border-radius: 5px;
box-shadow: none;
outline: none;
transition: all .25s ease-in-out;
}
.form__input:hover, .form__input:focus {
border-color: #fff;
}
.form__input:disabled {
border-color: transparent;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment