- package App::WRT::Renderer;
-
- use strict;
- use warnings;
- use 5.10.0;
-
- use Carp;
- use File::Basename;
-
- =pod
-
- =head1 NAME
-
- App::WRT::Renderer - render a wrt repo to publishable HTML
-
- =head1 SYNOPSIS
-
- use App::WRT;
- use App::WRT::Renderer;
-
- my $wrt = App::WRT::new_from_file($config_file);
- my $renderer = App::WRT::Renderer->new(
- $wrt,
- sub { say $_[0]; }
- );
-
- $renderer->render();
-
- =head1 METHODS
-
- =over
-
- =item new($class, $entry_dir, $logger, $io)
-
- Get a new Renderer. Takes an instance of App::WRT, a logging callback, and a
- App::WRT::FileIO or similar object to be used for the actual intake and
- mangling of things on the filesystem.
-
- =cut
-
- sub new {
- my $class = shift;
- my ($wrt, $logger, $io) = @_;
-
- ref($logger) eq 'CODE' or
- croak("Error: Renderer expects an anonymous function for logging");
-
- my %params = (
- wrt => $wrt,
- logger => $logger,
- io => $io,
- );
-
- my $self = \%params;
- bless $self, $class;
- }
-
-
- =item write($path, $contents)
-
- Write $contents to $path, using the FileIO object passed into the constructor
- above.
-
- =cut
-
- sub write {
- my ($self, $file, $contents) = @_;
- $self->{io}->file_put_contents($file, $contents)
- }
-
-
- =item render($class, $entry_dir)
-
- Render entries to F<publish_dir>.
-
- =cut
-
- sub render {
- my $self = shift;
-
- my $entry_dir = $self->{wrt}->{entry_dir};
- my $publish_dir = $self->{wrt}->{publish_dir};
-
- # Ensure that publication path exists and is a directory:
- if (-e $publish_dir) {
- unless (-d $publish_dir) {
- croak("$publish_dir exists but is not a directory");
- }
- } else {
- $self->log("Attempting to create $publish_dir");
- unless ($self->dir_make_logged($publish_dir)) {
- croak("Could not create $publish_dir");
- }
- }
-
- # Handle the front page. With no entries given, display() will use the
- # configured default, which is probably "new" unless the user has changed it.
- $self->write(
- "${publish_dir}/index.html",
- $self->{wrt}->display()
- );
-
- # Handle feed formats:
- my $feed_alias = $self->{wrt}->{feed_alias};
- my $xml_feed_content = $self->{wrt}->feed_print_recent();
- my $json_feed_content = $self->{wrt}->feed_print_json_recent();
- $self->write("${publish_dir}/${feed_alias}", $xml_feed_content);
- $self->write("${publish_dir}/${feed_alias}.xml", $xml_feed_content);
- $self->write("${publish_dir}/${feed_alias}.json", $json_feed_content);
-
- # Handle any other paths that aren't derived directly from files:
- my @meta_paths = qw(all);
-
- my $rendered_count = 0;
- my $copied_count = 0;
- for my $target ($self->{wrt}->{entries}->all(), @meta_paths)
- {
- # Skip index files - these are the text content of an entry, not
- # a sub-entry:
- next if $target =~ m{/index$};
-
- # Lowercase and alphanumeric + underscores + dashes, no dots - an entry:
- if ($self->{wrt}->{entries}->is_renderable($target)) {
- $self->dir_make_logged("$publish_dir/$target");
-
- my $rendered = $self->{wrt}->display($target);
-
- my $target_file = "$publish_dir/$target/index.html";
- $self->log("[write] $target_file " . length($rendered));
- $self->write($target_file, $rendered);
- $rendered_count++;
- next;
- }
-
- # A directory - no-op:
- if (-d "$entry_dir/$target") {
- $self->log("[directory] $entry_dir/$target");
- next;
- }
-
- # Some other file - a static asset of some kind:
- my $dirname = dirname($target);
- $self->log("[copy] archives/$target -> $publish_dir/$target");
- $self->dir_make_logged("$publish_dir/$dirname");
- $self->{io}->file_copy("$entry_dir/$target", "$publish_dir/$target");
- $copied_count++;
- }
-
- $self->log("rendered $rendered_count entries");
- $self->log("copied $copied_count static files");
-
- # Presumed success:
- return 1;
- }
-
-
- =item dir_make_logged($path)
-
- Make a directory path or log an error.
-
- =cut
-
- sub dir_make_logged {
- my ($self, $path) = @_;
- my $path_err;
- $self->log("[create] $path");
- $self->{io}->dir_make($path);
- # XXX: surface these somehow
- # $self->log(Dumper($path_err)) if @{ $path_err };
- }
-
-
- =item log(@log_items)
-
- Call logging callback with passed parameters.
-
- =cut
-
- sub log {
- my ($self) = shift;
- $self->{logger}->(@_);
- }
-
- =back
-
- =cut
-
- 1;
|