add a format() method to articles for use in templates
authorTony Cook <tony@develop-help.com>
Tue, 31 Mar 2015 12:42:51 +0000 (23:42 +1100)
committerTony Cook <tony@develop-help.com>
Tue, 31 Mar 2015 12:42:51 +0000 (23:42 +1100)
MANIFEST
site/cgi-bin/modules/BSE/API.pm
site/cgi-bin/modules/BSE/DummyArticle.pm
site/cgi-bin/modules/BSE/Formatter.pm
site/cgi-bin/modules/BSE/Formatter/Article.pm
site/cgi-bin/modules/BSE/FormatterBase.pm [new file with mode: 0644]
site/cgi-bin/modules/BSE/Generate.pm
site/cgi-bin/modules/BSE/TB/Article.pm
site/cgi-bin/modules/BSE/Template.pm
t/060-generate/010-generate.t
t/data/templates/gentest.tmpl [new file with mode: 0644]

index fc76fa2..372743b 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -104,6 +104,7 @@ site/cgi-bin/modules/BSE/FileMetaMeta.pm
 site/cgi-bin/modules/BSE/Formatter.pm
 site/cgi-bin/modules/BSE/Formatter/Article.pm
 site/cgi-bin/modules/BSE/Formatter/Subscription.pm
+site/cgi-bin/modules/BSE/FormatterBase.pm
 site/cgi-bin/modules/BSE/Generate.pm
 site/cgi-bin/modules/BSE/Generate/Article.pm
 site/cgi-bin/modules/BSE/Generate/Catalog.pm
@@ -946,6 +947,7 @@ t/data/importer/basic.csv
 t/data/importer/product-simple.csv
 t/data/known_pod_issues.txt
 t/data/t101.jpg
+t/data/templates/gentest.tmpl
 t/t000load.t
 t/t00smoke.t                   makes a request to most of the scripts
 t/tags/bse.cfg
index 2656e1e..34d6741 100644 (file)
@@ -10,7 +10,7 @@ use Carp qw(confess croak);
 use Fcntl qw(:seek);
 use Cwd;
 
-our $VERSION = "1.011";
+our $VERSION = "1.012";
 
 =head1 NAME
 
@@ -148,7 +148,7 @@ my $cfg;
 
 sub bse_cfg {
   my $path = shift || ".";
-  $cfg ||= BSE::Cfg->new(path => $path);
+  $cfg ||= BSE::Cfg->new(path => $path, @_);
   $cfg->entry('site', 'url')
     or confess "Could not load configuration";
 
index aaae9da..25b53c6 100644 (file)
@@ -1,9 +1,10 @@
 package BSE::DummyArticle;
 use strict;
 use base 'BSE::TB::SiteCommon';
+use base 'BSE::FormatterBase';
 use BSE::TB::Articles;
 
-our $VERSION = "1.004";
+our $VERSION = "1.005";
 
 sub images {
   return;
index 4f4e928..7a7e875 100644 (file)
@@ -3,7 +3,7 @@ use strict;
 use BSE::Util::HTML;
 use Carp 'confess';
 
-our $VERSION = "1.008";
+our $VERSION = "1.010";
 
 use base 'DevHelp::Formatter';
 
@@ -25,7 +25,7 @@ sub new {
 
   $self->{gen} = $opts{gen};
   $self->{acts} = $opts{acts};
-  $self->{articles} = $opts{articles};
+  $self->{articles} = $opts{articles} || "BSE::TB::Articles";
   $self->{abs_urls} = $opts{abs_urls};
   my $dummy;
   $self->{auto_images} = $opts{auto_images} || \$dummy;
@@ -33,7 +33,7 @@ sub new {
   $self->{files} = $opts{files};
   $self->{templater} = $opts{templater};
 
-  my $cfg = $self->{gen}->{cfg};
+  my $cfg = $self->{cfg} = $self->{gen} ? $self->{gen}->{cfg} : BSE::Cfg->single;
   if ($cfg->entry('html', 'mbcs', 0)) {
     $self->{conservative_escape} = 1;
   }
@@ -58,7 +58,7 @@ sub _image {
   my $extras = '';
   my @classes;
   if ($self->{xhtml}) {
-    push @classes, $self->{gen}{cfg}->entry
+    push @classes, $self->{cfg}->entry
       ("html", "formatter_image_class", "bse_image_inline");
   }
   if ($style) {
@@ -78,7 +78,7 @@ sub _image {
 
   return $im->formatted
     (
-     cfg => $self->{gen}{cfg},
+     cfg => $self->{cfg},
      class => "bse_image_inline",
      align => $align,
      extras => $extras,
@@ -133,14 +133,25 @@ sub image {
 sub embed {
   my ($self, $name, $templateid, $maxdepth) = @_;
 
-  $self->{gen}->_embed_low($self->{acts}, $self->{articles}, $name,
-                          $templateid, $maxdepth, $self->{templater});
+  $self->{gen} or return "** cannot embed here - missing gen **";
+
+  my $embed;
+  if ($name =~ /^[1-9][0-9]*$/) {
+    $embed = $self->{articles}->getByPkey($name);
+  }
+  elsif ($name =~ /\A[a-zA-Z0-9_]*[a-zA-Z][a-zA-Z0-9_]*\z/) {
+    $embed = $self->{articles}->getBy(linkAlias => $name);
+  }
+
+  $embed or return "** article $name not found **";
+
+  $self->{gen}->_embed_low($embed, $self->{articles}, $templateid, $maxdepth);
 }
 
 sub _get_article {
   my ($self, $id, $error) = @_;
 
-  my $cfg = $self->{gen}->{cfg}
+  my $cfg = $self->{cfg}
     or confess "cfg not set in acts";
   my $dispid;
   my $art;
@@ -177,7 +188,7 @@ sub doclink {
   my $art = $self->_get_article($id, \$error)
     or return $error;
 
-  my $cfg = $self->{gen}->{cfg}
+  my $cfg = $self->{cfg}
     or confess "cfg not set in acts";
 
   # make the URL absolute if necessary
@@ -191,7 +202,7 @@ sub doclink {
     }
   }
   else {
-    $url = $art->link($self->{gen}{cfg});
+    $url = $art->link($self->{cfg});
   }
 
   unless ($title) {
@@ -379,7 +390,7 @@ sub replace {
 sub formlink {
   my ($self, $id, $type, $text, $target) = @_;
 
-  my $cfg = $self->{gen}{cfg};
+  my $cfg = $self->{cfg};
   my $section = "$id form";
   my $title = escape_html($cfg->entry($section, 'title', "Send us a comment"));
   $text ||= $title;
@@ -418,7 +429,7 @@ sub remove_doclink {
 sub remove_formlink {
   my ($self, $id) = @_;
 
-  return $self->{gen}{cfg}->entry("$id form", 'title', "Send us a comment");
+  return $self->{cfg}->entry("$id form", 'title', "Send us a comment");
 }
 
 sub remove_popimage {
@@ -523,7 +534,7 @@ sub tag_class {
 
   my $default = $type eq 'p' ? '' : $type;
 
-  return $self->{gen}{cfg}->entry('body class', $type, $default);
+  return $self->{cfg}->entry('body class', $type, $default);
 }
 
 1;
index a5ac0ec..eda8edf 100644 (file)
@@ -4,12 +4,12 @@ use base 'BSE::Formatter';
 use BSE::Util::HTML;
 use Digest::MD5 qw(md5_hex);
 
-our $VERSION = "1.003";
+our $VERSION = "1.004";
 
 sub rewrite_url {
   my ($self, $url, $text, $type) = @_;
 
-  my $cfg = $self->{gen}{cfg};
+  my $cfg = $self->{cfg};
 
   require BSE::URL;
   $url = BSE::URL->rewrite_url($cfg, $url);
diff --git a/site/cgi-bin/modules/BSE/FormatterBase.pm b/site/cgi-bin/modules/BSE/FormatterBase.pm
new file mode 100644 (file)
index 0000000..c5d9118
--- /dev/null
@@ -0,0 +1,124 @@
+package BSE::FormatterBase;
+use strict;
+
+our $VERSION = "1.000";
+
+=head1 NAME
+
+BSE::FormatterBase - mixin for adding a format() method.
+
+=head1 SYNOPSIS
+
+  # some article class does
+  use parent "BSE::FormatterClass";
+
+  # some article user does
+  my $html = $self->format
+    (
+     text => ..., # default to $self->body
+     images => ..., # default to $self->images
+     files => ..., # default to $self->files
+     gen => ..., # required for embedding
+     abs_urls => ..., # defaults to FALSE
+    );
+
+=cut
+
+
+sub formatter_class {
+  my ($self) = @_;
+
+  require BSE::Formatter::Article;
+  return "BSE::Formatter::Article";
+}
+
+=head1 METHODS
+
+=over
+
+=item format()
+
+Format in a body text sort of way.
+
+Parameters:
+
+=over
+
+=item *
+
+C<text> - the body text to format, defaults to the article's body text
+
+=item *
+
+C<images> - the images to use for the image[] tags, defaults to the
+article's images.
+
+=item *
+
+C<files> - the files to use for the file[] tags, defaults to the
+article's files.
+
+=item *
+
+C<gen> - must be set to the parent generator object for embedding to
+work.
+
+=item *
+
+C<articles> - the articles collection class.  Internal use only.
+
+=item *
+
+C<abs_urls> - whether to use absolute URLs.  Default: FALSE.
+
+=item *
+
+C<cfg> - the config object.  Defaults to the global config object.
+
+=back
+
+Template use:
+
+  <:# generator only available in static replacement :>
+  <:= article.format("gen", generator) :>
+
+=cut
+
+sub format {
+  my ($self, %opts) = @_;
+
+  my $cfg = $opts{cfg} || BSE::Cfg->single;
+
+  my $text = $opts{text};
+  defined $text or $text = $self->body;
+  my $images = $opts{images};
+  defined $images or $images = [ $self->images ];
+  my $files = $opts{files};
+  defined $files or $files = [ $self->files ];
+  my $gen = $opts{gen};
+  my $articles = $opts{articles} || "BSE::TB::Articles";
+  my $abs_urls = $opts{abs_urls};
+  defined $abs_urls or $abs_urls = 0;
+
+  my $formatter_class = $self->formatter_class;
+
+  my $auto_images;
+  my $formatter = $formatter_class->new(gen => $gen, 
+                                       articles => $articles,
+                                       abs_urls => $abs_urls, 
+                                       auto_images => \$auto_images,
+                                       images => $images, 
+                                       files => $files);
+
+  return $formatter->format($text);
+}
+
+1;
+
+=back
+
+=head1 AUTHOR
+
+Tony Cook <tony@develop-help.com>
+
+=cut
index 69a2cfc..db7f03d 100644 (file)
@@ -313,7 +313,7 @@ Conditional tag, true if the current article is being embedded.
 
 =cut
 
-our $VERSION = "1.025";
+our $VERSION = "1.026";
 
 my $excerptSize = 300;
 
@@ -471,7 +471,7 @@ sub _make_html {
   return unescape_html($_[0]);
 }
 
-sub _embed_low {
+sub _embed_tag {
   my ($self, $acts, $articles, $what, $template, $maxdepth, $templater) = @_;
 
   $maxdepth = $self->{maxdepth} 
@@ -513,6 +513,12 @@ sub _embed_low {
       or return "** Cannot find article $id to be embedded **";;
   }
 
+  return $self->_embed_low($embed, $articles, $template, $maxdepth);
+}
+
+sub _embed_low {
+  my ($self, $embed, $articles, $template, $maxdepth) = @_;
+
   my $gen = $self;
   if (ref($self) ne $embed->{generator}) {
     my $genname = $embed->{generator};
@@ -1180,7 +1186,7 @@ sub baseActs {
        return '' if $args eq 'start' || $args eq 'end';
        my ($what, $template, $maxdepth) = split ' ', $args;
        undef $maxdepth if defined $maxdepth && $maxdepth !~ /^\d+/;
-       return $self->_embed_low($acts, $articles, $what, $template, $maxdepth, $templater);
+       return $self->_embed_tag($acts, $articles, $what, $template, $maxdepth, $templater);
      },
      ifCanEmbed=> sub { $self->{depth} <= $self->{maxdepth} },
 
index 4056347..a010fe3 100644 (file)
@@ -4,11 +4,12 @@ use strict;
 use Squirrel::Row;
 use BSE::TB::SiteCommon;
 use BSE::TB::TagOwner;
+use BSE::FormatterBase;
 use vars qw/@ISA/;
-@ISA = qw/Squirrel::Row BSE::TB::SiteCommon BSE::TB::TagOwner/;
+@ISA = qw/Squirrel::Row BSE::TB::SiteCommon BSE::TB::TagOwner BSE::FormatterBase/;
 use Carp 'confess';
 
-our $VERSION = "1.027";
+our $VERSION = "1.028";
 
 =head1 NAME
 
index f7bc8b4..2fc78a8 100644 (file)
@@ -4,7 +4,7 @@ use Squirrel::Template;
 use Carp qw(confess cluck);
 use Config ();
 
-our $VERSION = "1.013";
+our $VERSION = "1.014";
 
 my %formats =
   (
@@ -244,6 +244,11 @@ sub template_dirs {
     unshift @dirs, split /\Q$path_sep/,
       $cfg->entryVar('paths', 'local_templates');
   }
+  my $section = "template paths";
+  my @keys = $cfg->order($section);
+  for my $key (reverse sort @keys) {
+    unshift @dirs, $cfg->entryVar($section, $key);
+  }
 
   @dirs;
 }
index 37c3a34..184e090 100644 (file)
@@ -1,7 +1,7 @@
 #!perl -w
 use strict;
 use BSE::Test ();
-use Test::More tests=>167;
+use Test::More tests=>173;
 use File::Spec;
 use FindBin;
 use Cwd;
@@ -14,9 +14,12 @@ BEGIN {
 }
 use BSE::API qw(bse_init bse_cfg bse_make_article bse_add_global_image);
 
-bse_init(".");
+my $cfg = bse_cfg(".", extra_text => <<CFG);
+[template paths]
+0000test=$start_dir/t/data/templates
+CFG
 
-my $cfg = bse_cfg();
+bse_init(".");
 
 use BSE::Util::SQL qw/sql_datetime/;
 use DevHelp::Date qw(dh_strftime_sql_datetime);
@@ -24,6 +27,8 @@ use DevHelp::Date qw(dh_strftime_sql_datetime);
 sub template_test($$$$);
 sub dyn_template_test($$$$);
 
+my $alias_id = int(time);
+
 my $parent = add_article
   (
    title=>'Parent', 
@@ -64,16 +69,20 @@ two
 BODY
    lastModified => '2004-09-23 06:00:00',
    threshold => 2,
+   linkAlias => "p$alias_id",
   );
 ok($parent, "create section");
 my @kids;
+my $kid_alias = "a";
 for my $name ('One', 'Two', 'Three') {
   my $kid = add_article
     (
      title => $name, parentid => $parent->{id}, 
      body => "b[$name] - alpha, beta, gamma, delta, epsilon",
      summaryLength => 35,
+     linkAlias => "$kid_alias$alias_id",
     );
+  ++$kid_alias;
   ok($kid, "creating kid $name");
   push(@kids, $kid);
 }
@@ -728,6 +737,19 @@ Embedded: [0]
 Dynamic: [0]
 EXPECTED
 
+template_test "format", $parent, <<TEMPLATE, <<EXPECTED;
+<:= article.format("text", "test") | raw :>
+TEMPLATE
+<p>test</p>
+EXPECTED
+
+template_test "format embed", $parent, <<TEMPLATE, <<EXPECTED;
+<:= article.format("text", "embed[a$alias_id,gentest]", "gen", generator) | raw :>
+TEMPLATE
+<div class="title">One</div>
+<p>Embedded</p>
+EXPECTED
+
 ############################################################
 # Cleanup
 
diff --git a/t/data/templates/gentest.tmpl b/t/data/templates/gentest.tmpl
new file mode 100644 (file)
index 0000000..e58d77e
--- /dev/null
@@ -0,0 +1,2 @@
+<div class="title"><:= article.title :></div>
+<p>Embedded</p>
\ No newline at end of file