Created
May 17, 2017 13:50
-
-
Save Getty/8e60512a4e8b317f3e5f9028e724ad8a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
has xslate => ( | |
isa => 'Text::Xslate', | |
is => 'ro', | |
lazy_build => 1, | |
); | |
sub _build_xslate { | |
my ( $self ) = @_; | |
my $xslate; | |
my $obj2dir = sub { | |
my $obj = shift; | |
if (blessed $obj && $obj->can('i')) { | |
return $obj->i; | |
} | |
my $class = ref $obj; | |
# we might not want singletonrows in the end after all - i still leave it in for the case of the cases | |
if ($class =~ m/^(DBIx::Class::SingletonRows::Cached::XXX|XXX)::(DB::Result|DB::ResultSet|Admin::Model::DB)::(.*)$/) { | |
my $dir = $3; | |
$dir =~ s/::/_/g; | |
$dir = decamelize($dir); | |
$dir = lc($dir); | |
$dir .= '_rs' if $2 eq 'DB::ResultSet'; | |
return $dir; | |
} elsif ($class =~ m/^(DBIx::Class::SingletonRows::Cached::XXX|XXX)::(.*)$/) { | |
my $dir = $1; | |
$dir =~ s/::/_/g; | |
$dir = decamelize($dir); | |
$dir = lc($dir); | |
return $dir; | |
} | |
$class =~ s/::/_/g; | |
$class = decamelize($class); | |
$class = lc($class); | |
return $class; | |
}; | |
my $i_template_and_vars = sub { | |
my $object = shift; | |
my $subtemplate; | |
my $no_templatedir; | |
my $vars; | |
if (ref $object) { | |
$subtemplate = shift; | |
$vars = shift; | |
} elsif (!defined $object) { | |
return ''; | |
} else { | |
$no_templatedir = 1; | |
$subtemplate = $object; | |
my $next = shift; | |
if (ref $next eq 'HASH') { | |
$object = undef; | |
$vars = $next; | |
} else { | |
$object = $next; | |
$vars = shift; | |
} | |
} | |
my $main_object; | |
my @objects; | |
push @objects, $object if $object; | |
if (ref $object eq 'ARRAY') { | |
$main_object = $object->[0]; | |
@objects = @{$object}; | |
} else { | |
$main_object = $object; | |
} | |
my %current_vars = %{$xslate->current_vars}; | |
my $no_caller = delete $vars->{no_caller} ? 1 : 0; | |
if (defined $current_vars{_} && !$no_caller) { | |
$current_vars{caller} = $current_vars{_}; | |
} | |
$current_vars{_} = $main_object; | |
my $ref_main_object = ref $main_object; | |
if ($main_object && $ref_main_object) { | |
if (blessed $main_object && $main_object->can('meta')) { | |
for my $method ( $main_object->meta->get_all_methods ) { | |
if ($method->name =~ m/^i_(.*)$/) { | |
my $name = $1; | |
my $var_name = '_'.$name; | |
my $func = 'i_'.$name; | |
$current_vars{$var_name} = $main_object->$func; | |
} | |
} | |
} | |
} | |
my @template = ('i'); | |
unless ($no_templatedir) { | |
push @template, $obj2dir->($main_object); | |
} | |
push @template, $subtemplate ? $subtemplate : 'label'; | |
my %new_vars; | |
for (@objects) { | |
my $obj_dir = $obj2dir->($_); | |
if (defined $new_vars{$obj_dir}) { | |
if (ref $new_vars{$obj_dir} eq 'ARRAY') { | |
push @{$new_vars{$obj_dir}}, $_; | |
} else { | |
$new_vars{$obj_dir} = [ | |
$new_vars{$obj_dir}, $_, | |
]; | |
} | |
} else { | |
$new_vars{$obj_dir} = $_; | |
} | |
} | |
for (keys %new_vars) { | |
$current_vars{$_} = $new_vars{$_}; | |
} | |
if ($vars) { | |
for (keys %{$vars}) { | |
$current_vars{$_} = $vars->{$_}; | |
} | |
} | |
return join('/',@template).".tx",\%current_vars; | |
}; | |
$xslate = Text::Xslate->new({ | |
path => [ path(__FILE__)->parent->parent->child('root/templates')->realpath->absolute ], | |
suffix => '.tx', | |
function => { | |
# Mark text as raw HTML | |
r => sub { mark_raw(@_) }, | |
v => sub { $xslate->current_vars->{join('',@_)} if @_ }, | |
dump => sub { return p($_[0]) }, | |
pf => sub { sprintf(shift,@_) }, | |
sprintf => sub { sprintf(shift,@_) }, | |
js => sub { js(shift) }, | |
url_encode => sub { url_encode(@_) }, | |
# trick function for DBIx::Class::ResultSet | |
results => sub { | |
my ( $rs, $sorting ) = @_; | |
my @results = $rs->all; | |
$sorting | |
? [ sort { $a->$sorting <=> $b->$sorting } @results ] | |
: [ @results ]; | |
}, | |
columns => sub { | |
my ( $result ) = @_; | |
my %columns = $result->get_columns(); | |
return [ sort { $a cmp $b } keys %columns ]; | |
}, | |
# general functions avoiding xslates problems | |
call => sub { | |
my $thing = shift; | |
my $func = shift; | |
$thing->$func; | |
}, | |
call_if => sub { | |
my $thing = shift; | |
my $func = shift; | |
$thing->$func if $thing; | |
}, | |
replace => sub { | |
my $source = shift; | |
my $from = shift; | |
my $to = shift; | |
$source =~ s/$from/$to/g; | |
return $source; | |
}, | |
rounded => sub { | |
my $minutes = shift; | |
my $return = sprintf("%.1f",$minutes); | |
$return =~ s/\.0$//; | |
return $return; | |
}, | |
lines => sub { | |
my $text = shift; | |
my @lines = split /^/, $text; | |
return [ grep { length($_) > 0 } map { s/^\s+//; s/\s$//; s/\s+/ /g; $_; } @lines ]; | |
}, | |
urify => sub { | |
my $value = shift; | |
$value = lc $value; | |
$value =~ s/[^a-zA-Z]+/-/g; | |
return $value; | |
}, | |
ref => sub { ref($_[0]) }, | |
defined => sub { defined($_[0]) }, | |
floor => sub { floor($_[0]) }, | |
ceil => sub { ceil($_[0]) }, | |
length => sub { length($_[0]) }, | |
lc => sub { lc($_[0]) }, | |
uc => sub { uc($_[0]) }, | |
join => sub { join(shift,@_) }, | |
jointrue => sub { join(shift,map { $_ ? ($_) : () } @_) }, | |
i_template_and_vars => $i_template_and_vars, | |
i => sub { mark_raw($xslate->render($i_template_and_vars->(@_))) }, | |
i_template => sub { | |
my ( $template, $vars ) = $i_template_and_vars->(@_); | |
return $template | |
}, | |
datetime => sub { | |
my ( $date ) = @_; | |
$date = DateTime->from_epoch( epoch => $date ) unless ref $date; | |
return $date; | |
}, | |
time => sub { time() }, | |
ordinate => sub { | |
return ordinate($_[0]); | |
}, | |
dur_precise => sub { | |
my ( $date ) = @_; | |
$date = DateTime->from_epoch( epoch => $date ) unless ref $date; | |
return DateTime::Format::Human::Duration->new->format_duration( | |
ref $date eq 'DateTime::Duration' ? $date : (DateTime->now( time_zone => $self->time_zone ) - $date), | |
'units' => [qw/years months days hours minutes/], | |
'past' => '%s ago', | |
'future' => 'in %s', | |
'no_time' => 'just now', | |
); | |
}, | |
nl2br => sub { | |
my $t = shift || return; | |
$t =~ s/([\r])/<br>/g; | |
return $t; | |
}, | |
n => sub { | |
my ( $singular, $plural, @args ) = @_; | |
if ($args[0] == 1) { | |
return $singular =~ m/%/ | |
? sprintf($singular,@args) | |
: sprintf($singular); | |
} else { | |
return $plural =~ m/%/ | |
? sprintf($plural,@args) | |
: sprintf($plural); | |
} | |
}, | |
before_now => sub { | |
return 0 unless $_[0]; | |
DateTime->compare( DateTime->now( time_zone => $self->time_zone ), $_[0] ) == 1 ? 0 : 1; | |
}, | |
make_data => sub { | |
my ( $data ) = @_; | |
my $text = ' '; | |
for my $key (keys %{$data}) { | |
$text .= 'data-'.$key.'="'.html_escape($data->{$key} || "").'" '; | |
} | |
return mark_raw($text); | |
}, | |
alphapos => sub { | |
my ( $pos ) = @_; | |
my @alphas = 'a'..'zz'; | |
return $alphas[$pos-1]; | |
}, | |
style => sub { | |
my %style; | |
my @styles = @_; | |
while (@styles) { | |
my $t_style = $self->template_styles->{shift @styles}; | |
if (ref $t_style eq 'HASH') { | |
$style{$_} = $t_style->{$_} for keys %{$t_style}; | |
} elsif (ref $t_style eq 'ARRAY') { | |
unshift @styles, @{$t_style}; | |
} | |
} | |
my $return = 'style="'; | |
$return .= $_.':'.$style{$_}.';' for (sort { length($a) <=> length($b) } keys %style); | |
$return .= '"'; | |
return mark_raw($return); | |
}, | |
}, | |
}); | |
return $xslate; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment