Skip to content

Commit

Permalink
Item13751: add automatic PRINT_TEMPLATE feature
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelDaum committed Sep 25, 2015
1 parent 58fd8ea commit 58c7a20
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 62 deletions.
47 changes: 26 additions & 21 deletions data/System/AutoTemplatePlugin.txt
@@ -1,6 +1,5 @@
%META:TOPICINFO{author="ProjectContributor" date="1441015297" format="1.1" version="1"}%
---+ <nop>%TOPIC%

%SHORTDESCRIPTION%

%IF{"context 'AutoViewTemplatePluginEnabled' and context 'AutoTemplatePluginEnabled'"
Expand All @@ -16,7 +15,7 @@

---++ Description

This plugin sets the VIEW_TEMPLATE and EDIT_TEMPLATE variables according to a
This plugin sets the VIEW_TEMPLATE, EDIT_TEMPLATE and PRINT_TEMPLATE variables according to a
corresponding form or rule. For example, when you attach a new form to a topic, this
plugin will enable the corresponding view/edit template automatically. This
comes in very handy for applications where users create new topics
Expand Down Expand Up @@ -62,13 +61,13 @@ You have a form called =PurchaseRequestForm=. The plugin will now search for
---+++ Mode "section"

A topic with a =MyForm= will be displayed/editted using the template name
stored in the named section =viewtemplate/edittemplate= . For example given the
stored in the named section =viewtemplate=, =edittemplate=, =printtemplate=. For example given the
=MyForm= form definition topic contains a section =viewtemplate= whose only
content is =MyOtherView=, then this will be used to view the topic. Likewise,
the content of the =edittemplate= section in =MyForm= will read to find the
edit template.

By default existing values for VIEW_TEMPLATE and EDIT_TEMPLATE have priority.
By default existing values for VIEW_TEMPLATE, EDIT_TEMPLATE and PRINT_TEMPLATE have priority.
You can change this behaviour in =configure= so that the form defined templates
have priority.

Expand All @@ -84,6 +83,8 @@ Below this we place the two sections that defines the templates to be used. Note
%STARTSECTION{"viewtemplate"}%ViewFormAtTopTemplate%ENDSECTION{"viewtemplate"}%

%STARTSECTION{"edittemplate"}%EditPurchaseRequest%ENDSECTION{"edittemplate"}%

%STARTSECTION{"printtemplate"}%PrintPurchaseRequest%ENDSECTION{"printtemplate"}%
</verbatim>


Expand Down Expand Up @@ -139,23 +140,18 @@ The following settings can be defined in configure
=rules= for defining the template using the two rule sets below | Default: =rules, exist= |
| {Plugins}{AutoTemplatePlugin}{ViewTemplateRules} | hash of =&lt;pattern>= => '&lt;template name>' rules to be used for =view= | |
| {Plugins}{AutoTemplatePlugin}{EditTemplateRules} | hash of =&lt;pattern>= => '&lt;template name>' rules to be used for =edit= | |
| {Plugins}{AutoTemplatePlugin}{PrintTemplateRules} | hash of =&lt;pattern>= => '&lt;template name>' rules to be used when printing or exporting to pdf | |

---++ Plugin Installation Instructions

---++ Installation Instructions
%$INSTALL_INSTRUCTIONS%

---++ Dependencies
%$DEPENDENCIES%

---++ Plugin Info
---++ Change History

<!--
* Set SHORTDESCRIPTION = Automatically sets VIEW_TEMPLATE and EDIT_TEMPLATE
-->
| Plugin Author: | Foswiki:Main.MichaelDaum |
| Copyright: | &copy; 2008-2015, Oliver Kr&uuml;ger, Michael Daum |
| License: | GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]]) |
| Release: | %$RELEASE% |
| Version: | %$VERSION% |
| Change History: | <!-- versions below in reverse order -->&nbsp; |
%TABLE{columnwidths="7em" tablewidth="100%"}%
| 25 Sep 2015: | added support for PRINT_TEMPLATE |
| 31 Aug 2015: | ignore invalid template warning when section not found |
| 17 Jul 2015: | fixed auto-templating of topics being created; fixed auto-templating when the !DataForm is changed during edit |
| 03 Nov 2014: | implemented public API to get the auto-assigned template |
Expand All @@ -176,8 +172,17 @@ The following settings can be defined in configure
fixed view templates in subwebs (MD) |
| 04 Sep 2007: | Added build script and installer, minor doc changes |
| 05 Jun 2007: | Initial version |
| Foswiki Dependency: | $Foswiki::Plugins::VERSION 1.026 |
| CPAN Dependencies: | none |
| Other Dependencies: | none |
| Home: | Foswiki:Extensions/%TOPIC% |
| Support: | Foswiki:Extensions/%TOPIC% |

<!--
* Set SHORTDESCRIPTION = Automatically sets VIEW_TEMPLATE and EDIT_TEMPLATE
-->

%META:FORM{name="PackageForm"}%
%META:FIELD{name="Author" title="Author" value="Foswiki:Main.MichaelDaum"}%
%META:FIELD{name="Copyright" title="Copyright" value="&copy; 2008-2015, Oliver Kr&uuml;ger, Michael Daum"}%
%META:FIELD{name="Home" title="Home" value="Foswiki:Extensions/%TOPIC%"}%
%META:FIELD{name="License" title="License" value="GPL ([[http://www.gnu.org/copyleft/gpl.html][GNU General Public License]])"}%
%META:FIELD{name="Release" title="Release" value="%$RELEASE%"}%
%META:FIELD{name="Repository" title="Repository" value="https://github.com/foswiki/AutoTemplatePlugin"}%
%META:FIELD{name="Support" title="Support" value="Foswiki:Extensions/%TOPIC%"}%
%META:FIELD{name="Version" title="Version" value="%$VERSION%"}%
93 changes: 58 additions & 35 deletions lib/Foswiki/Plugins/AutoTemplatePlugin.pm
Expand Up @@ -15,28 +15,24 @@ package Foswiki::Plugins::AutoTemplatePlugin;
use strict;
use warnings;

our $VERSION = '4.01';
our $RELEASE = '4.01';
our $SHORTDESCRIPTION = 'Automatically sets VIEW_TEMPLATE and EDIT_TEMPLATE';
our $VERSION = '5.00';
our $RELEASE = '25 Sep 2015';
our $SHORTDESCRIPTION = 'Automatically sets VIEW_TEMPLATE, EDIT_TEMPLATE and PRINT_TEMPLATE';
our $NO_PREFS_IN_TOPIC = 1;
our $debug;
our %knownTemplate = ();

sub initPlugin {
my( $topic, $web, $user, $installWeb ) = @_;

# check for Plugins.pm versions
if( $Foswiki::Plugins::VERSION < 1.026 ) {
Foswiki::Func::writeWarning( "Version mismatch between AutoTemplatePlugin and Plugins.pm" );
return 0;
}
%knownTemplate = ();

# get configuration
my $override = $Foswiki::cfg{Plugins}{AutoTemplatePlugin}{Override} || 0;
$debug = $Foswiki::cfg{Plugins}{AutoTemplatePlugin}{Debug} || 0;

# is this an edit action?
my $isEditAction = Foswiki::Func::getContext()->{edit};
my $templateVar = $isEditAction?'EDIT_TEMPLATE':'VIEW_TEMPLATE';
my $templateVar = _isEditAction()?'EDIT_TEMPLATE':_isPrintAction()?'PRINT_TEMPLATE':'VIEW_TEMPLATE';

# back off if there is a view template already and we are not in override mode
my $currentTemplate = Foswiki::Func::getPreferencesValue($templateVar);
Expand All @@ -60,7 +56,7 @@ sub initPlugin {
return 1 unless $templateName;

# in edit mode, try to read the template to check if it exists
if ($isEditAction && !Foswiki::Func::readTemplate($templateName)) {
if (_isEditAction() && !Foswiki::Func::readTemplate($templateName)) {
writeDebug("edit tempalte not found");
return 1;
}
Expand All @@ -77,6 +73,7 @@ sub initPlugin {
writeDebug("$templateVar set to: $templateName");
}
}
$templateVar =~ s/^PRINT_/VIEW_/g; #sneak in VIEW again
if ($Foswiki::Plugins::VERSION >= 2.1 ) {
Foswiki::Func::setPreferencesValue($templateVar, $templateName);
} else {
Expand All @@ -88,21 +85,26 @@ sub initPlugin {
}

sub getTemplateName {
my ($web, $topic) = @_;
my ($web, $topic, $action) = @_;

$action ||= _isEditAction()?'edit':_isPrintAction()?'print':'view';

my $templateName = "";
my $modeList = $Foswiki::cfg{Plugins}{AutoTemplatePlugin}{Mode} || "rules, exist";
foreach my $mode (split(/\s*,\s*/, $modeList)) {
if ( $mode eq "section" ) {
$templateName = _getTemplateFromSectionInclude( $web, $topic );
$templateName = _getTemplateFromSectionInclude( $web, $topic, $action );
} elsif ( $mode eq "exist" ) {
$templateName = _getTemplateFromTemplateExistence( $web, $topic );
$templateName = _getTemplateFromTemplateExistence( $web, $topic, $action );
} elsif ( $mode eq "rules" ) {
$templateName = _getTemplateFromRules( $web, $topic );
$templateName = _getTemplateFromRules( $web, $topic, $action );
}
last if $templateName;
}

# fall back to view for print template
return getTemplateName($web, $topic, "view") if !defined($templateName) && $action eq 'print';

return $templateName;
}

Expand All @@ -122,7 +124,7 @@ sub _getFormName {
}

sub _getTemplateFromSectionInclude {
my ($web, $topic) = @_;
my ($web, $topic, $action) = @_;

my $formName = _getFormName($web, $topic);
return unless $formName;
Expand All @@ -132,20 +134,44 @@ sub _getTemplateFromSectionInclude {
my ($formweb, $formtopic) = Foswiki::Func::normalizeWebTopicName($web, $formName);

# SMELL: This can be done much faster, if the formdefinition topic is read directly
my $isEditAction = Foswiki::Func::getContext()->{edit};
my $sectionName = $isEditAction?'edittemplate':'viewtemplate';
my $sectionName = $action."template";
my $templateName = "%INCLUDE{ \"$formweb.$formtopic\" section=\"$sectionName\" warn=\"off\"}%";
$templateName = Foswiki::Func::expandCommonVariables( $templateName, $topic, $web );

return $templateName;
return $templateName if _templateExists($templateName);

return undef;
}

sub _isPrintAction {
my $request = Foswiki::Func::getCgiQuery();
my $contentType = $request->param("contenttype") || '';
my $cover = $request->param("cover") || '';
return $contentType eq 'application/pdf' || $cover =~ /print/ ? 1:0;
}

sub _isEditAction {
return Foswiki::Func::getContext()->{edit}?1:0;
}

sub _templateExists {
my $name = shift;

return unless defined $name;

unless (defined $knownTemplate{$name}) {
my $text = Foswiki::Func::readTemplate($name);
$knownTemplate{$name} = $text?1:0;
}

return $knownTemplate{$name};
}

# replaces Web.MyForm with Web.MyViewTemplate and returns Web.MyViewTemplate if it exists otherwise nothing
sub _getTemplateFromTemplateExistence {
my ($web, $topic) = @_;
my ($web, $topic, $action) = @_;

my $formName = _getFormName($web, $topic);
my $isEditAction = Foswiki::Func::getContext()->{edit}?1:0;
return unless $formName;

writeDebug("called _getTemplateFromTemplateExistence($formName, $topic, $web)");
Expand All @@ -154,20 +180,20 @@ sub _getTemplateFromTemplateExistence {
$templateWeb =~ s/\//\./go;
my $templateName = $templateWeb.'.'.$templateTopic;
$templateName =~ s/Form$//;
$templateName .= $isEditAction?'Edit':'View';
$templateName .= ucfirst($action);

return $templateName;

return $templateName if _templateExists($templateName);
return undef;
}

sub _getTemplateFromRules {
my ($web, $topic) = @_;
my ($web, $topic, $action) = @_;

writeDebug("called _getTemplateFromRules($web, $topic)");

# read template rules from preferences
my $isEditAction = Foswiki::Func::getContext()->{edit};
my $rules = Foswiki::Func::getPreferencesValue(
$isEditAction?'EDIT_TEMPLATE_RULES':'VIEW_TEMPLATE_RULES');
my $rules = Foswiki::Func::getPreferencesValue(uc($action."_TEMPLATE_RULES"));

if ($rules) {
$rules =~ s/^\s+//;
Expand All @@ -178,32 +204,30 @@ sub _getTemplateFromRules {
if ($rule =~ /^(.*?)\s*=>\s*(.*?)$/) {
my $pattern = $1;
my $template = $2;
return $template if "$web.$topic" =~ /^($pattern)$/;
return $template if "$web.$topic" =~ /^($pattern)$/ && _templateExists($template);
}
}
# check topic name only
foreach my $rule (split(/\s*,\s*/, $rules)) {
if ($rule =~ /^(.*?)\s*=>\s*(.*?)$/) {
my $pattern = $1;
my $template = $2;
return $template if $topic =~ /^($pattern)$/ ;
return $template if $topic =~ /^($pattern)$/ && _templateExists($template);
}
}
}

# read template rules from config
$rules = $isEditAction?
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{EditTemplateRules}:
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{ViewTemplateRules};
$rules = $Foswiki::cfg{Plugins}{AutoTemplatePlugin}{ucfirst($action).'TemplateRules'};

if($rules) {
# check full qualified topic name first
foreach my $pattern (keys %$rules) {
return $rules->{$pattern} if "$web.$topic" =~ /^($pattern)$/;
return $rules->{$pattern} if "$web.$topic" =~ /^($pattern)$/ && _templateExists($rules->{$pattern});
}
# check topic name only
foreach my $pattern (keys %$rules) {
return $rules->{$pattern} if $topic =~ /^($pattern)$/;
return $rules->{$pattern} if $topic =~ /^($pattern)$/ && _templateExists($rules->{$pattern});
}
}

Expand All @@ -216,5 +240,4 @@ sub writeDebug {
print STDERR "- AutoTemplatePlugin - $_[0]\n";
}


1;
16 changes: 10 additions & 6 deletions lib/Foswiki/Plugins/AutoTemplatePlugin/Config.spec
Expand Up @@ -21,8 +21,8 @@ $Foswiki::cfg{Plugins}{AutoTemplatePlugin}{Override} = 0;
# </ul>
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{Mode} = 'rules, exist';

# **PERL LABEL="ViewTemplate Rules"**
# Rule set used to derive the view template name. This is a list of rules of the form
# **PERL LABEL="ViewTemplate Rules" CHECK="undefok emptyok"**
# Rules to derive the view template name. This is a list of rules of the form
# <code>'pattern' => 'template'</code>. The current topic is matched against each of the
# patterns in the given order. The first matching pattern determines the concrete view template.
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{ViewTemplateRules} = {
Expand All @@ -43,10 +43,14 @@ $Foswiki::cfg{Plugins}{AutoTemplatePlugin}{ViewTemplateRules} = {
'WikiUsers' => 'WikiUsersView',
};

# **PERL LABEL="EditTemplate Rules"**
# Rule set used to derive the edit template name. The format is the same as for the <code>{ViewTempalteRules}</code>
# **PERL LABEL="EditTemplate Rules" CHECK="undefok emptyok"**
# Rules to derive the edit template name. The format is the same as for the <code>{ViewTempalteRules}</code>
# configuration. This rule set is used during edit.
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{EditTemplateRules} = {
};
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{EditTemplateRules} = { };

# **PERL LABEL="PrintTemplate Rules" CHECK="undefok emptyok"**
# Rules to set the print template when exporting PDF or the like. The format is the same as for the <code>{ViewTempalteRules}</code>
# configuration.
$Foswiki::cfg{Plugins}{AutoTemplatePlugin}{PrintTemplateRules} = { };

1;

0 comments on commit 58c7a20

Please sign in to comment.