From 1112417c282c48bf158c207db3531252751ebe59 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Mon, 5 Nov 2018 21:14:08 +0100 Subject: [PATCH 01/12] Make plerd use InstaPlerd::Post for jpeg files. --- lib/Plerd.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index 54d3e2f..c3fef39 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -13,6 +13,7 @@ use Carp; use Try::Tiny; use Plerd::Post; +use InstaPlerd::Post; use Plerd::WebmentionQueue; has 'path' => ( From 6ba208fa5d4c6301a326a2e4a7fe8544c9e250c7 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Thu, 8 Nov 2018 22:51:37 +0100 Subject: [PATCH 02/12] Make plerdwatcher act on jpegs too --- bin/plerdwatcher | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/plerdwatcher b/bin/plerdwatcher index 1c5c653..29fbefa 100755 --- a/bin/plerdwatcher +++ b/bin/plerdwatcher @@ -78,7 +78,7 @@ try { $watcher = File::ChangeNotify->instantiate_watcher ( directories => [ $plerd->source_directory . '' ], - filter => qr/\.(md|markdown)$/, + filter => qr/\.(md|markdown|jpe?g)$/, ); } catch { From f421ebe93f227b192033f95b0d5e1de387d7fcbb Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Fri, 9 Nov 2018 23:24:10 +0100 Subject: [PATCH 03/12] Add Extension support --- bin/plerdall | 7 +++++ bin/plerdwatcher | 16 ++++++++++- cpanfile | 3 +- lib/Plerd.pm | 71 ++++++++++++++++++++++++++++++++++++++++++------ 4 files changed, 87 insertions(+), 10 deletions(-) diff --git a/bin/plerdall b/bin/plerdall index 9c3844d..aba971f 100755 --- a/bin/plerdall +++ b/bin/plerdall @@ -57,6 +57,13 @@ foreach (qw( base_uri image ) ) { } } + +my @extensions = $config_ref->{ extensions } + ? split(',', $config_ref->{ extensions }) + : (); + +$config_ref->{ extensions } = \@extensions; + my $plerd = Plerd->new( $config_ref ); if ( $rebuild_webmentions ) { diff --git a/bin/plerdwatcher b/bin/plerdwatcher index 29fbefa..97b287f 100755 --- a/bin/plerdwatcher +++ b/bin/plerdwatcher @@ -71,14 +71,28 @@ foreach (qw( base_uri image ) ) { } } +my @extensions = $config_ref->{ extensions } + ? split(',', $config_ref->{ extensions }) + : (); + +$config_ref->{ extensions } = \@extensions; + + my $plerd; my $watcher; try { $plerd = Plerd->new( $config_ref ); + my $filter; + + my $trigger = defined (keys %{$plerd->post_triggers}) + ? sprintf '\.(md|markdown|%s)$', join('|', keys %{$plerd->post_triggers}) + : '\.(md|markdown)$'; + + $filter = qr/$trigger/; $watcher = File::ChangeNotify->instantiate_watcher ( directories => [ $plerd->source_directory . '' ], - filter => qr/\.(md|markdown|jpe?g)$/, + filter => $filter, ); } catch { diff --git a/cpanfile b/cpanfile index 2eac0c2..985b888 100644 --- a/cpanfile +++ b/cpanfile @@ -15,6 +15,7 @@ requires 'Try::Tiny'; requires 'HTML::Strip'; requires 'HTML::SocialMeta' => '0.72'; requires 'List::Util' => '1.45'; +requires 'Module::Load'; requires 'Readonly'; -requires 'Web::Mention' => '0.6'; +requires 'Web::Mention' => '0.6'; requires 'Mojolicious::Lite'; diff --git a/lib/Plerd.pm b/lib/Plerd.pm index c3fef39..1e6f585 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -12,8 +12,9 @@ use URI; use Carp; use Try::Tiny; +use Module::Load; + use Plerd::Post; -use InstaPlerd::Post; use Plerd::WebmentionQueue; has 'path' => ( @@ -258,6 +259,18 @@ has 'tags_map' => ( clearer => 'clear_tags_map', ); +has 'extensions' => ( + is => 'ro', + isa => 'ArrayRef[Str]', +); + +has 'post_triggers' => ( + is => 'ro', + isa => 'HashRef[Str]', + lazy_build => 1, + ); + + sub BUILD { my $self = shift; @@ -273,6 +286,16 @@ sub BUILD { }; } } + if ($self->extensions){ + foreach my $extension (@{$self->extensions}) { + try { + load $extension; + } + catch { + die "Can't load extension: '$extension'.: $@"; + }; + } + } return $self; } @@ -610,15 +633,23 @@ sub _build_recent_posts { sub _build_posts { my $self = shift; + my @posts; + my $triggers = $self->post_triggers; + + foreach my $file (sort { $a->basename cmp $b->basename } $self->source_directory->children) { + if ($file =~ m/\.(?:markdown|md)$/) { + push @posts, Plerd::Post->new( plerd => $self, source_file => $file ) + } else { + foreach my $trigger (keys %{$triggers}) { + if ($file =~ m/$trigger/i) { + push @posts, $$triggers{$trigger}->new(plerd => $self, source_file => $file); + } + } + } + } - my @posts = sort { $b->date <=> $a->date } - map { Plerd::Post->new( plerd => $self, source_file => $_ ) } - sort { $a->basename cmp $b->basename } - grep { /\.markdown$|\.md$/ } - $self->source_directory->children - ; + return [sort { $b->date <=> $a->date } @posts]; - return \@posts; } sub _build_index_of_post_with_guid { @@ -665,6 +696,19 @@ sub _throw_template_exception { . "template file $template_file: $error\n"; } +sub _build_post_triggers { + my $self = shift; + my %triggers; + if ($self->extensions){ + foreach my $classref (@{$self->extensions}){ + if ($classref->can('file_type')) { + $triggers{ $classref->file_type } = $classref; + } + } + } + return \%triggers; +} + sub generates_post_guids { carp "generates_post_guids() is deprecated. (Also, it doesn't do anything " . "anyway.)"; @@ -955,6 +999,17 @@ tag index HTML files. This is a L object that points to the tag index. It is particularly helpful when creating navigation. +=item extensions + +An arrayref of L objects, representing the plugins to load when a new Pled +instance is created. + +=item post_triggers + +A hashref of L,L objects. The key is used as a regex to deduce what +source file types the particular Post extension using to render pages. +The value is a reference to that particular extension. + =back =head1 OBJECT METHODS From 4fea8e326c1d36c7453d411fae536eaca7a78dd1 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Sat, 10 Nov 2018 00:57:21 +0100 Subject: [PATCH 04/12] Add test for extensions --- t/basic.t | 28 +++++++++++++++++++++++++++- t/lib/TestExtension.pm | 13 +++++++++++++ t/source_model/extension.dm | 4 ++++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 t/lib/TestExtension.pm create mode 100644 t/source_model/extension.dm diff --git a/t/basic.t b/t/basic.t index 4b283f1..081c561 100644 --- a/t/basic.t +++ b/t/basic.t @@ -8,6 +8,7 @@ use DateTime; use FindBin; use lib "$FindBin::Bin/../lib"; +use lib "$FindBin::Bin/lib"; use_ok( 'Plerd' ); @@ -56,7 +57,8 @@ $plerd->publish_all; # The "+5" below accounts for the generated recent, archive, and RSS files, # a index.html symlink, and a tags directory. -my $expected_docroot_count = scalar( $source_dir->children( no_hidden => 1 ) ) + 5; +my $expected_docroot_count = scalar( $source_dir->children( no_hidden => 1 ) ) + 4; + is( scalar( $docroot_dir->children ), $expected_docroot_count, "Correct number of files generated in docroot." @@ -331,6 +333,30 @@ like( $post, 'Metatags: Defined default alt-text', ); +} +{ +### Test extension-support +use lib 'src'; +use TestExtension; +my $extension_plerd = Plerd->new( + path => $FindBin::Bin, + title => 'Test Blog', + author_name => 'Nobody', + author_email => 'nobody@example.com', + extensions => ['TestExtension'], + base_uri => URI->new ( 'http://blog.example.com/' ), + image => URI->new ( 'http://blog.example.com/logo.png' ), + +); + +$extension_plerd->publish_all; + +my $post = Path::Class::File->new( $docroot_dir, "2018-11-10-a-very-special-source-file.html" )->slurp; +like( $post, + qr{.dm which is .md backwards.}, + 'Extensions: Plerd can publish with extensions', +); + } done_testing(); diff --git a/t/lib/TestExtension.pm b/t/lib/TestExtension.pm new file mode 100644 index 0000000..b37d665 --- /dev/null +++ b/t/lib/TestExtension.pm @@ -0,0 +1,13 @@ +package TestExtension; +use Plerd::Post; +use Moose; +use strict; +use warnings FATAL => 'all'; + +extends "Plerd::Post"; + +sub file_type { + 'dm'; +} + +1; diff --git a/t/source_model/extension.dm b/t/source_model/extension.dm new file mode 100644 index 0000000..5069039 --- /dev/null +++ b/t/source_model/extension.dm @@ -0,0 +1,4 @@ +title: A very special source file + + +It's only special because it's file type is .dm which is .md backwards. This is to see if it gets processed by an extension. From 2175ad5f56d24512a0ff3e6b93940d3b6d4f83f7 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Sat, 10 Nov 2018 09:21:10 +0100 Subject: [PATCH 05/12] Clean up superflous code and redundant imports --- lib/Plerd.pm | 29 ++++++++++++++--------------- t/basic.t | 2 -- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index 1e6f585..4fe7af7 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -261,12 +261,12 @@ has 'tags_map' => ( has 'extensions' => ( is => 'ro', - isa => 'ArrayRef[Str]', + isa => 'Maybe[ArrayRef[Str]]', ); has 'post_triggers' => ( is => 'ro', - isa => 'HashRef[Str]', + isa => 'Maybe[HashRef[Str]]', lazy_build => 1, ); @@ -286,15 +286,14 @@ sub BUILD { }; } } - if ($self->extensions){ - foreach my $extension (@{$self->extensions}) { - try { - load $extension; - } - catch { - die "Can't load extension: '$extension'.: $@"; - }; + + foreach my $extension (@{$self->extensions // []}) { + try { + load $extension; } + catch { + die "Can't load extension: '$extension'.: $@"; + }; } return $self; @@ -699,13 +698,13 @@ sub _throw_template_exception { sub _build_post_triggers { my $self = shift; my %triggers; - if ($self->extensions){ - foreach my $classref (@{$self->extensions}){ - if ($classref->can('file_type')) { - $triggers{ $classref->file_type } = $classref; - } + + foreach my $classref (@{$self->extensions // []}){ + if ($classref->can('file_type')) { + $triggers{ $classref->file_type } = $classref; } } + return \%triggers; } diff --git a/t/basic.t b/t/basic.t index 081c561..d9a70a7 100644 --- a/t/basic.t +++ b/t/basic.t @@ -336,8 +336,6 @@ like( $post, } { ### Test extension-support -use lib 'src'; -use TestExtension; my $extension_plerd = Plerd->new( path => $FindBin::Bin, title => 'Test Blog', From 7f6d3aee849f307e0cd20ce62a68955c3896cd51 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Sat, 10 Nov 2018 09:52:16 +0100 Subject: [PATCH 06/12] Make test work tomorrow too :) --- t/basic.t | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/t/basic.t b/t/basic.t index d9a70a7..ed8d90f 100644 --- a/t/basic.t +++ b/t/basic.t @@ -349,7 +349,7 @@ my $extension_plerd = Plerd->new( $extension_plerd->publish_all; -my $post = Path::Class::File->new( $docroot_dir, "2018-11-10-a-very-special-source-file.html" )->slurp; +my $post = Path::Class::File->new( $docroot_dir, "$ymd-a-very-special-source-file.html" )->slurp; like( $post, qr{.dm which is .md backwards.}, 'Extensions: Plerd can publish with extensions', From 4a966b5dadbf935467d93ee543bbaf5b7247f076 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Sat, 10 Nov 2018 09:52:46 +0100 Subject: [PATCH 07/12] Make trigger regex match file ending only. --- lib/Plerd.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index 4fe7af7..c175a49 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -640,7 +640,7 @@ sub _build_posts { push @posts, Plerd::Post->new( plerd => $self, source_file => $file ) } else { foreach my $trigger (keys %{$triggers}) { - if ($file =~ m/$trigger/i) { + if ($file =~ m/\.$trigger$/i) { push @posts, $$triggers{$trigger}->new(plerd => $self, source_file => $file); } } From fe877fffca2a5ecf1c363cadd37463f1ac8640a9 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Sat, 10 Nov 2018 18:24:11 +0100 Subject: [PATCH 08/12] Don't need to split a list for extensions because its a YAML file which has list support alreadty. --- bin/plerdall | 7 ------- bin/plerdwatcher | 7 ------- lib/Plerd.pm | 1 + 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/bin/plerdall b/bin/plerdall index aba971f..9c3844d 100755 --- a/bin/plerdall +++ b/bin/plerdall @@ -57,13 +57,6 @@ foreach (qw( base_uri image ) ) { } } - -my @extensions = $config_ref->{ extensions } - ? split(',', $config_ref->{ extensions }) - : (); - -$config_ref->{ extensions } = \@extensions; - my $plerd = Plerd->new( $config_ref ); if ( $rebuild_webmentions ) { diff --git a/bin/plerdwatcher b/bin/plerdwatcher index 97b287f..4bebb5c 100755 --- a/bin/plerdwatcher +++ b/bin/plerdwatcher @@ -71,13 +71,6 @@ foreach (qw( base_uri image ) ) { } } -my @extensions = $config_ref->{ extensions } - ? split(',', $config_ref->{ extensions }) - : (); - -$config_ref->{ extensions } = \@extensions; - - my $plerd; my $watcher; try { diff --git a/lib/Plerd.pm b/lib/Plerd.pm index c175a49..482e934 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -642,6 +642,7 @@ sub _build_posts { foreach my $trigger (keys %{$triggers}) { if ($file =~ m/\.$trigger$/i) { push @posts, $$triggers{$trigger}->new(plerd => $self, source_file => $file); + last; } } } From 5bc6ba20b7e831ee99a50ae70e4a5b04aaacedca Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Tue, 20 Nov 2018 14:47:04 +0100 Subject: [PATCH 09/12] Add extension_preferences option This is something for the various plugins to read settings from. --- lib/Plerd.pm | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index 482e934..7ea2fc8 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -261,14 +261,19 @@ has 'tags_map' => ( has 'extensions' => ( is => 'ro', - isa => 'Maybe[ArrayRef[Str]]', + isa => 'Maybe[ArrayRef[Str]]' +); + +has 'extension_preferences' => ( + is => 'ro', + isa => 'Maybe[HashRef]', ); has 'post_triggers' => ( is => 'ro', isa => 'Maybe[HashRef[Str]]', lazy_build => 1, - ); +); sub BUILD { @@ -1004,6 +1009,11 @@ particularly helpful when creating navigation. An arrayref of L objects, representing the plugins to load when a new Pled instance is created. +=item extension_preferences + +A hashref of config options for extensions. It is up to each individual extension +to decide how to act upon the contents therein. + =item post_triggers A hashref of L,L objects. The key is used as a regex to deduce what From 99fb2082ab00e6ffab07522d943bcd3bb343d64d Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Mon, 24 Dec 2018 09:29:24 +0100 Subject: [PATCH 10/12] Improve Plerd.pm doc on extension related methods --- lib/Plerd.pm | 4 ++-- t/basic.t | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index 7ea2fc8..bdbbf00 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -1006,7 +1006,7 @@ particularly helpful when creating navigation. =item extensions -An arrayref of L objects, representing the plugins to load when a new Pled +An arrayref of strings, representing the plugins to load when a new Plerd instance is created. =item extension_preferences @@ -1016,7 +1016,7 @@ to decide how to act upon the contents therein. =item post_triggers -A hashref of L,L objects. The key is used as a regex to deduce what +A hashref that maps extensions to file types. The key is used as a regex to deduce what source file types the particular Post extension using to render pages. The value is a reference to that particular extension. diff --git a/t/basic.t b/t/basic.t index ed8d90f..a7429a5 100644 --- a/t/basic.t +++ b/t/basic.t @@ -55,7 +55,7 @@ unlink "$FindBin::Bin/source/no-title.md"; $plerd->publish_all; -# The "+5" below accounts for the generated recent, archive, and RSS files, +# The "+4" below accounts for the generated recent, archive, and RSS files, # a index.html symlink, and a tags directory. my $expected_docroot_count = scalar( $source_dir->children( no_hidden => 1 ) ) + 4; From d878bd8816124b06fc9af68a7c794b749417cdf8 Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Mon, 24 Dec 2018 11:17:03 +0100 Subject: [PATCH 11/12] Print extension error message if present. --- lib/Plerd.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Plerd.pm b/lib/Plerd.pm index bdbbf00..a9d0e73 100644 --- a/lib/Plerd.pm +++ b/lib/Plerd.pm @@ -297,7 +297,8 @@ sub BUILD { load $extension; } catch { - die "Can't load extension: '$extension'.: $@"; + my $error = shift || "Unknown error"; + die "Can't load extension: '$extension': $error\n"; }; } From 8a58182e683b74b0a4856021f4e69cfac9341b3a Mon Sep 17 00:00:00 2001 From: Petter hassberg Date: Mon, 24 Dec 2018 11:18:13 +0100 Subject: [PATCH 12/12] Make TestExtension do something Now it does reverse the source file body... Plus some docs are added too --- t/basic.t | 2 +- t/lib/TestExtension.pm | 55 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/t/basic.t b/t/basic.t index a7429a5..a7a29ab 100644 --- a/t/basic.t +++ b/t/basic.t @@ -351,7 +351,7 @@ $extension_plerd->publish_all; my $post = Path::Class::File->new( $docroot_dir, "$ymd-a-very-special-source-file.html" )->slurp; like( $post, - qr{.dm which is .md backwards.}, + qr{.sdrawkcab dm. si hcihw md.}, 'Extensions: Plerd can publish with extensions', ); diff --git a/t/lib/TestExtension.pm b/t/lib/TestExtension.pm index b37d665..006da3f 100644 --- a/t/lib/TestExtension.pm +++ b/t/lib/TestExtension.pm @@ -2,6 +2,9 @@ package TestExtension; use Plerd::Post; use Moose; use strict; + +use 5.010; + use warnings FATAL => 'all'; extends "Plerd::Post"; @@ -10,4 +13,56 @@ sub file_type { 'dm'; } +around 'body' => sub { + my $orig = shift; + my $self = shift; + if (@_){ + # "Setter" + my $body = shift; + + # first time body is called, reverse it! + $body = reverse $body unless $self->$orig; + + $self->$orig($body); + } else { + # "Getter" + $self->$orig(); + } +}; + 1; + + +=head1 NAME + +TestExtension - A L extension to showcase the extension capabilities of L. + +=head1 DESCRIPTION + +This extension doesn't do anything truly useful. It's sole purpose is showcasing the extension capabilities. + +What it does in fact do, though, is reversing the body of the document (the first time it's set). + +It's rather useless. + +=head1 OBJECT ATTRIBUTES + +=head2 Read-only attributes, set during construction + +=over + +=item file_type + +A regex-compatible string which indicate what file types to associate with the Extension. +This is set to "dm" (which happens to be "md" spelled backwards) + +=item body + +The original L body, except that the first time this attribute is set, it gets reversed. + +=back + +=head2 Other attributes + +All other attributes are inherited from L Please consult that documentation for their docs. +