--- /dev/null
+package App::Commentry;
+
+use aliased 'App::Commentry::CommentStore';
+use FindBin;
+use HTML::Zoom;
+use Web::Simple;
+
+sub default_config {
+ (
+ store_dir => $FindBin::Bin.'/../store/comments',
+ template_dir => $FindBin::Bin.'/../share/html',
+ )
+}
+
+has comment_store => (
+ is => 'lazy', handles => { 'comments_for' => 'get' }
+);
+
+sub _build_comment_store {
+ my $self = shift;
+ my $store_dir = $self->config->{store_dir};
+ die "Comment Store directory ${store_dir} does not exist"
+ unless -d $store_dir;
+ CommentStore->new(base_dir => $self->config->{store_dir});
+}
+
+has template_dir => (
+ is => 'lazy'
+);
+
+sub _build_template_dir {
+ my $self = shift;
+ my $template_dir = $self->config->{template_dir};
+ die "template_dir ${template_dir} does not exist"
+ unless -d $template_dir;
+ $template_dir;
+}
+
+sub dispatch_request {
+ my ($self) = @_;
+ sub (/fragments/*/**) {
+ my ($self, $action, $path) = @_;
+ return unless $action eq 'show' or $action eq 'add';
+ return unless my $set = $self->comments_for({ path => $path });
+ $self->${\"_fragment_${action}"}($set);
+ }
+}
+
+sub _fragment_show {
+ my ($self, $set) = @_;
+ sub (GET) {
+ $self->_zoom_response(fragment_show => sub {
+ $_->select('.comment')
+ ->repeat($set->map(sub {
+ my ($comment) = @_;
+ sub {
+ $_->select('.comment-title')->replace_content($comment->title)
+ ->select('.comment-body')->replace_content($comment->body)
+ }
+ }));
+ });
+ }
+}
+
+sub _zoom_response {
+ my ($self, $template, $apply) = @_;
+ my $zfh = ($self->{zoom_cache}{$template} ||= do {
+ HTML::Zoom->from_file($self->template_dir.'/'.$template.'.html')
+ })->apply($apply)->to_fh;
+ [ 200, [ 'Content-type' => 'text/html' ], $zfh ];
+}
+
+1;
--- /dev/null
+package App::Commentry::MappedSet;
+
+use Moo;
+
+has source => (is => 'ro', required => 1);
+has mapping => (is => 'ro', required => 1);
+
+sub flatten {
+ my ($self) = @_;
+ map $self->mapping->($_), $self->source->flatten;
+}
+
+sub to_stream {
+ require HTML::Zoom::ArrayStream;
+ HTML::Zoom::ArrayStream->new({ array => [ $_[0]->flatten ] });
+}
+
+1;