Slovo
view release on metacpan or search on metacpan
lib/Slovo/Plugin/TagHelpers.pm view on Meta::CPAN
package Slovo::Plugin::TagHelpers;
use Mojo::Base 'Mojolicious::Plugin::TagHelpers', -signatures;
use Scalar::Util 'blessed';
use Mojo::DOM::HTML 'tag_to_html';
use Mojo::Collection 'c';
my sub _select_box ($c, $name, $options, %attrs) {
return $c->tag(
div => class => "mui-select $name" => sub {
my $label = $c->label_for($name => delete $attrs{label} // ucfirst $name);
$c->param($name => delete $attrs{value})
if exists $attrs{value} && !defined $c->param($name);
return $label . ' ' . $c->select_field($name, $options, %attrs);
});
}
my sub _checkboxes ($c, $name, $options, %attrs) {
my $label = $c->label_for($name => delete $attrs{label} // ucfirst $name);
return $c->tag(
div => (class => "mui-textfield $name", %attrs) => sub {
my $html = "";
for my $check (@$options) {
my $group_name = $check->[0];
$check->[0] = $name;
$html
.= tag_to_html('label' => sub { $c->check_box(@$check) . " $group_name" }) . $/;
}
return $label . $/ . tag_to_html(div => (class => 'mui-checkbox') => sub {$html});
});
}
my sub _html_substr ($c, $html, $selector, $chars) {
state $html_dom = Mojo::DOM->new;
# Split on two subsequent new lines and get the first five paragraphs but
# only if the content is not HTML, (e. g. it is markdown).
return c(split m|$/$/|, $html)->head(5)->map(sub ($txt) {
$chars <= 0 && return '';
# strip potential inline markup
$txt =~ s/<[^>]+>?//g;
my $html = '<p>' . substr($txt, 0, $chars) . 'â¦</p>';
$chars -= length($txt);
return $html;
})->join('') unless $html =~ /^<\w/;
# Get the first 5 elements, matching $selector and prepare them for
# displaying as text, until the targeted number of characters is reached.
my $out = $html_dom->parse($html)->find($selector)->head(5)->map(sub ($el) {
return '' unless $el;
return '' if $chars <= 0;
my $txt = $el->all_text;
my $html = tag_to_html($el->tag, %{$el->attr}, substr($txt, 0, $chars));
$chars -= length($txt);
return $html;
})->join('');
return $out;
}
my sub _format_body ($c, $celina) {
my $id = 'celina_body_' . $celina->{data_format} . $celina->{id};
if ($celina->{data_format} eq 'markdown') {
my $body = $celina->{body} =~ s/\`/\\`/gr;
return
tag_to_html(div => (id => $id), sub { $celina->{body} })
. $/
. $c->javascript('/js/editormd/lib/marked.min.js')
. $/
. tag_to_html(
script => sub {
<<"JS";
document.getElementById('$id').innerHTML = marked(`$body`);
JS
});
}
return tag_to_html(div => (id => $id), sub { $celina->{body} });
}
sub register ($self, $app, $config) {
#initialise the base unless alredy initialised
$self->SUPER::register($app) unless exists $app->renderer->helpers->{t};
$app->helper(checkboxes => \&_checkboxes);
$app->helper(select_box => \&_select_box);
$app->helper(html_substr => \&_html_substr);
$app->helper(format_body => \&_format_body);
for my $h (qw(stylesheets javascripts)) {
$app->helper(
$h => sub {
state $tag = $h =~ s/s$//r;
if ($_[1]) {
my $d = $app->defaults->{$h} //= [];
push @$d, $_[0]->$tag($_[1]);
return $_[0];
( run in 0.956 second using v1.01-cache-2.11-cpan-71847e10f99 )