<commit_before>package Mojolicious::Plugin::EPRenderer;
use Mojo::Base 'Mojolicious::Plugin';

use Mojo::Template;
use Mojo::Util qw(encode md5_sum monkey_patch);

sub register {
  my ($self, $app, $conf) = @_;

  # Auto escape by default to prevent XSS attacks
  my $template = {auto_escape => 1, %{$conf->{template} || {}}};

  # Add "ep" handler and make it the default
  $app->renderer->default_handler('ep')->add_handler(
    $conf->{name} || 'ep' => sub {
      my ($renderer, $c, $output, $options) = @_;

      # Generate name
      my $path = $options->{inline} || $renderer->template_path($options);
      return undef unless defined $path;
      my $stash = $c->stash;
      my $id    = encode 'UTF-8', join(', ', $path, sort keys %$stash);
      my $key   = $options->{cache} = md5_sum $id;

      # Compile helpers and stash values
      my $cache = $renderer->cache;
      my $mt    = $cache->get($key);
      unless ($mt) {
        $mt = Mojo::Template->new($template);

        # Helpers
        ++$self->{helpers} and _helpers($mt->namespace, $renderer->helpers)
          unless $self->{helpers};

        # Stash values
        my $prepend = 'my $self = shift; my $_S = $self->stash;';
        $prepend .= " my \$$_ = \$_S->{'$_'};" for grep {/^\w+$/} keys %$stash;

        # Cache
        $cache->set($key => $mt->prepend($prepend . $mt->prepend));
      }

      # Make current controller available
      no strict 'refs';
      no warnings 'redefine';
      local *{"@{[$mt->namespace]}::_C"} = sub {$c};

      # Render with "epl" handler
      return $renderer->handlers->{epl}->($renderer, $c, $output, $options);
    }
  );
}

sub _helpers {
  my ($namespace, $helpers) = @_;
  for my $name (grep {/^\w+$/} keys %$helpers) {
    monkey_patch $namespace, $name,
      sub { $helpers->{$name}->($namespace->_C, @_) };
  }
}

1;

=encoding utf8<commit_msg>make list of keys only once<commit_after>package Mojolicious::Plugin::EPRenderer;
use Mojo::Base 'Mojolicious::Plugin';

use Mojo::Template;
use Mojo::Util qw(encode md5_sum monkey_patch);

sub register {
  my ($self, $app, $conf) = @_;

  # Auto escape by default to prevent XSS attacks
  my $template = {auto_escape => 1, %{$conf->{template} || {}}};

  # Add "ep" handler and make it the default
  $app->renderer->default_handler('ep')->add_handler(
    $conf->{name} || 'ep' => sub {
      my ($renderer, $c, $output, $options) = @_;

      # Generate name
      my $path = $options->{inline} || $renderer->template_path($options);
      return undef unless defined $path;
      my @keys = sort grep {/^\w+$/} keys %{$c->stash};
      my $id = encode 'UTF-8', join(',', $path, @keys);
      my $key = $options->{cache} = md5_sum $id;

      # Cache template for "epl" handler
      my $cache = $renderer->cache;
      my $mt    = $cache->get($key);
      unless ($mt) {
        $mt = Mojo::Template->new($template);

        # Helpers (only once)
        ++$self->{helpers} and _helpers($mt->namespace, $renderer->helpers)
          unless $self->{helpers};

        # Stash values (every time)
        my $prepend = 'my $self = shift; my $_S = $self->stash;';
        $prepend .= " my \$$_ = \$_S->{'$_'};" for @keys;

        $cache->set($key => $mt->prepend($prepend . $mt->prepend));
      }

      # Make current controller available
      no strict 'refs';
      no warnings 'redefine';
      local *{"@{[$mt->namespace]}::_C"} = sub {$c};

      # Render with "epl" handler
      return $renderer->handlers->{epl}->($renderer, $c, $output, $options);
    }
  );
}

sub _helpers {
  my ($namespace, $helpers) = @_;
  for my $name (grep {/^\w+$/} keys %$helpers) {
    monkey_patch $namespace, $name,
      sub { $helpers->{$name}->($namespace->_C, @_) };
  }
}

1;

=encoding utf8
{'fraction_non_alphanumeric': 0.1962864721485411, 'fraction_numerical': 0.003183023872679045, 'mean_word_length': 2.8284263959390863, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 65, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5508638', 'n_tokens_mistral': 1313, 'n_tokens_neox': 1316, 'n_words': 332}