Reactive-Mojo/lib/Reactive/Mojo/Plugin.pm
package Reactive::Mojo::Plugin;
use 5.006;
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Plugin';
use Mojo::ByteStream;
use Reactive::Core;
use Reactive::Mojo::TemplateRenderer;
=head1 NAME
Reactive::Mojo::Plugin - Mojolicious plugin for Reactive
=head1 VERSION
Version 0.01
=cut
our $VERSION = '0.01';
=head1 SYNOPSIS
Register the plugin in startup method of your Mojolicious App
It takes `namespaces` configuration param which should be an arrayref of the namespaces within your app to scan for Reactive components
sub startup ($self) {
...
$self->secrets($config->{secrets});
$self->plugin(
'Reactive::Mojo::Plugin',
{
namespaces => [
'My::App::Components',
],
},
);
...
Then within you templates you can use a component like
<%= reactive('Counter') %>
or if there is initial state you want to set
<%= reactive('Counter', value => 10) %>
add the required JS with
<%= reactive_js %>
see Reactive::Core and Reactive::Examples for more information about creating components
=cut
=head2 register($self, Mojolicious $app, HashRef $conf)
This register method is not expected to be called directly via userland code
but instead will be called by Mojoicious when adding the plugin
$self->plugin(
'Reactive::Mojo::Plugin',
{
namespaces => [
'My::App::Components',
],
},
);
=cut
sub register {
my $self = shift;
my $app = shift;
my $conf = shift;
my $renderer = Reactive::Mojo::TemplateRenderer->new(
app => $app,
);
my $reactive = Reactive::Core->new(
template_renderer => $renderer,
secret => $app->secrets->[0],
component_namespaces => $conf->{namespaces} // [],
);
$app->helper(reactive => sub {
my ($c, $component, %args) = @_;
return $reactive->initial_render($component, %args);
});
$app->helper(reactive_js => sub {
my $c = shift;
my $block = <<'HTML';
<script defer src="https://cdn.jsdelivr.net/npm/@alpinejs/morph@3.x.x/dist/cdn.min.js"></script>
<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>
<script src="/assets/reactive.js"></script>
HTML
return Mojo::ByteStream->new($block);
});
$app->routes->get('/assets/reactive.js' => sub {
my $c = shift;
my $path = $INC{'Reactive/Core.pm'};
$path =~ s/Core.pm$/reactive.js/;
$c->res->headers->content_type('application/javascript');
$c->reply->file($path);
});
$app->routes->post('/reactive' => sub {
my $c = shift;
my $data = $c->req->json;
$c->render(
json => $reactive->process_request($data)
);
});
}
=head1 AUTHOR
Robert Moore, C<< <robert at r-moore.tech> >>
=head1 BUGS
Please report any bugs or feature requests to C<bug-reactive-mojo at rt.cpan.org>, or through
the web interface at L<https://rt.cpan.org/NoAuth/ReportBug.html?Queue=Reactive-Mojo>. I will be notified, and then you'll
automatically be notified of progress on your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Reactive::Mojo::Plugin
You can also look for information at:
=over 4
=item * RT: CPAN's request tracker (report bugs here)
L<https://rt.cpan.org/NoAuth/Bugs.html?Dist=Reactive-Mojo>
=item * CPAN Ratings
L<https://cpanratings.perl.org/d/Reactive-Mojo>
=item * Search CPAN
L<https://metacpan.org/release/Reactive-Mojo>
=back
=head1 ACKNOWLEDGEMENTS
=head1 LICENSE AND COPYRIGHT
This software is Copyright (c) 2025 by Robert Moore.
This is free software, licensed under:
The Artistic License 2.0 (GPL Compatible)
=cut
1; # End of Reactive::Mojo