return if $method eq 'DESTROY';
- return $self->[0]->$method($self->[1], @args);
+ if (my $sub = $self->[0]->can($method)) {
+ return $sub->($self->[1], @args);
+ }
}
1;
use Carp;
use Template;
-use SL::Presenter::Chart;
-use SL::Presenter::CustomerVendor;
-use SL::Presenter::DeliveryOrder;
-use SL::Presenter::EscapedText;
-use SL::Presenter::Invoice;
-use SL::Presenter::GL;
-use SL::Presenter::Letter;
-use SL::Presenter::Order;
-use SL::Presenter::Part;
-use SL::Presenter::Project;
-use SL::Presenter::Record;
-use SL::Presenter::RequirementSpec;
-use SL::Presenter::RequirementSpecItem;
-use SL::Presenter::RequirementSpecTextBlock;
-use SL::Presenter::SepaExport;
-use SL::Presenter::ShopOrder;
-use SL::Presenter::Text;
-use SL::Presenter::Tag;
-use SL::Presenter::BankAccount;
+use SL::Presenter::EscapedText qw(is_escaped);
use Rose::Object::MakeMethods::Generic (
scalar => [ qw(need_reinit_widgets) ],
if (!$options->{process}) {
# If $template is a reference then don't try to read a file.
my $ref = ref $template;
- return $template if $ref eq 'SL::Presenter::EscapedText';
- return SL::Presenter::EscapedText->new(text => ${ $template }, is_escaped => 1) if $ref eq 'SCALAR';
+ return $template if $ref eq 'SL::Presenter::EscapedText';
+ return is_escaped(${ $template }) if $ref eq 'SCALAR';
# Otherwise return the file's content.
my $file = IO::File->new($source, "r") || croak("Template file ${source} could not be read");
my $content = do { local $/ = ''; <$file> };
$file->close;
- return SL::Presenter::EscapedText->new(text => $content, is_escaped => 1);
+ return is_escaped($content);
}
# Processing was requested. Set up all variables.
my $parser = $self->get_template;
$parser->process($source, \%params, \$output) || croak $parser->error;
- return SL::Presenter::EscapedText->new(text => $output, is_escaped => 1);
+ return is_escaped($output);
}
sub get_template {
return $self->{template};
}
-sub escape {
- my ($self, $text) = @_;
-
- return SL::Presenter::EscapedText->new(text => $text);
-}
-
-sub escaped_text {
- my ($self, $text) = @_;
-
- return SL::Presenter::EscapedText->new(text => $text, is_escaped => 1);
-}
-
-sub escape_js {
- my ($self, $text) = @_;
-
- $text =~ s|\\|\\\\|g;
- $text =~ s|\"|\\\"|g;
- $text =~ s|\n|\\n|g;
-
- return SL::Presenter::EscapedText->new(text => $text, is_escaped => 1);
-}
-
1;
__END__
# Higher-level rendering of certain objects:
use SL::DB::Customer;
- my $linked_customer_name = $presenter->customer($customer, display => 'table-cell');
+ my $linked_customer_name = $customer->presenter->customer(display => 'table-cell');
# Render a list of links to sales/purchase records:
use SL::DB::Order;
+ use SL::Presenter::Record qw(grouped_record_list);
my $quotation = SL::DB::Manager::Order->get_first(where => { quotation => 1 });
my $records = $quotation->linked_records(direction => 'to');
- my $html = $presenter->grouped_record_list($records);
+ my $html = grouped_record_list($records);
=head1 CLASS FUNCTIONS
{ type => 'json', process => 0 }
);
-=item C<escape $text>
-
-Returns an HTML-escaped version of C<$text>. Instead of a string an
-instance of the thin proxy-object L<SL::Presenter::EscapedText> is
-returned.
-
-It is safe to call C<escape> on an instance of
-L<SL::Presenter::EscapedText>. This is a no-op (the same instance will
-be returned).
-
-=item C<escaped_text $text>
-
-Returns an instance of L<SL::Presenter::EscapedText>. C<$text> is
-assumed to be a string that has already been HTML-escaped.
-
-It is safe to call C<escaped_text> on an instance of
-L<SL::Presenter::EscapedText>. This is a no-op (the same instance will
-be returned).
-
-=item C<escape_js $text>
-
-Returns a JavaScript-escaped version of C<$text>. Instead of a string
-an instance of the thin proxy-object L<SL::Presenter::EscapedText> is
-returned.
-
-It is safe to call C<escape> on an instance of
-L<SL::Presenter::EscapedText>. This is a no-op (the same instance will
-be returned).
-
=item C<get_template>
Returns the global instance of L<Template> and creates it if it
--- /dev/null
+package SL::Presenter::ALL;
+
+use strict;
+
+use SL::Presenter::Chart;
+use SL::Presenter::CustomerVendor;
+use SL::Presenter::DeliveryOrder;
+use SL::Presenter::EscapedText;
+use SL::Presenter::Invoice;
+use SL::Presenter::GL;
+use SL::Presenter::Letter;
+use SL::Presenter::Order;
+use SL::Presenter::Part;
+use SL::Presenter::Project;
+use SL::Presenter::Record;
+use SL::Presenter::RequirementSpec;
+use SL::Presenter::RequirementSpecItem;
+use SL::Presenter::RequirementSpecTextBlock;
+use SL::Presenter::SepaExport;
+use SL::Presenter::ShopOrder;
+use SL::Presenter::Text;
+use SL::Presenter::Tag;
+use SL::Presenter::BankAccount;
+
+our %presenters = (
+ chart => 'SL::Presenter::Chart',
+ customer_vendor => 'SL::Presenter::CustomerVendor',
+ delivery_order => 'SL::Presenter::DeliveryOrder',
+ escaped_text => 'SL::Presenter::EscapedText',
+ invoice => 'SL::Presenter::Invoice',
+ gl => 'SL::Presenter::GL',
+ letter => 'SL::Presenter::Letter',
+ order => 'SL::Presenter::Order',
+ part => 'SL::Presenter::Part',
+ project => 'SL::Presenter::Project',
+ record => 'SL::Presenter::Record',
+ requirement_spec => 'SL::Presenter::RequirementSpec',
+ requirement_spec_item => 'SL::Presenter::RequirementSpecItem',
+ requirement_spec_text_block => 'SL::Presenter::RequirementSpecTextBlock',
+ sepa_export => 'SL::Presenter::SepaExport',
+ shop_order => 'SL::Presenter::ShopOrder',
+ text => 'SL::Presenter::Text',
+ tag => 'SL::Presenter::Tag',
+ bank_account => 'SL::Presenter::BankAccount',
+);
+
+sub wrap {
+ bless [ $_[0] ], 'SL::Presenter::ALL::Wrapper';
+}
+
+package SL::Presenter::ALL::Wrapper;
+
+sub AUTOLOAD {
+ our $AUTOLOAD;
+
+ my ($self, @args) = @_;
+
+ my $method = $AUTOLOAD;
+ $method =~ s/.*:://;
+
+ return if $method eq 'DESTROY';
+
+ splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');
+
+ if (my $sub = $self->[0]->can($method)) {
+ return $sub->(@args);
+ }
+}
+
+1;
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape);
use Exporter qw(import);
-our @EXPORT = qw(account_number bank_code);
+our @EXPORT_OK = qw(account_number bank_code);
use Carp;
sub account_number {
- my ($self, $bank_account) = @_;
- return $self->escaped_text($bank_account->account_number);
+ my ($bank_account) = @_;
+ escape($bank_account->account_number);
}
sub bank_code {
- my ($self, $bank_account) = @_;
- return $self->escaped_text($bank_account->bank_code);
+ my ($bank_account) = @_;
+ escape($bank_account->bank_code);
}
1;
use SL::DB::Chart;
use Exporter qw(import);
-use Data::Dumper;
-our @EXPORT = qw(chart_picker chart);
+our @EXPORT_OK = qw(chart_picker chart);
use Carp;
+use Data::Dumper;
+use SL::Presenter::EscapedText qw(escape is_escaped);
+use SL::Presenter::Tag qw(input_tag name_to_id html_tag);
sub chart {
- my ($self, $chart, %params) = @_;
+ my ($chart, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="am.pl?action=edit_account&id=' . $self->escape($chart->id) . '">',
- $self->escape($chart->accno),
+ $params{no_link} ? '' : '<a href="am.pl?action=edit_account&id=' . escape($chart->id) . '">',
+ escape($chart->accno),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+ is_escaped($text);
}
sub chart_picker {
- my ($self, $name, $value, %params) = @_;
+ my ($name, $value, %params) = @_;
$value = SL::DB::Manager::Chart->find_by(id => $value) if $value && !ref $value;
- my $id = delete($params{id}) || $self->name_to_id($name);
+ my $id = delete($params{id}) || name_to_id($name);
my $fat_set_item = delete $params{fat_set_item};
my @classes = $params{class} ? ($params{class}) : ();
push @classes, 'chartpicker_fat_set_item' if $fat_set_item;
my $ret =
- $self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id) .
- join('', map { $params{$_} ? $self->input_tag("", delete $params{$_}, id => "${id}_${_}", type => 'hidden') : '' } qw(type category choose booked)) .
- $self->input_tag("", (ref $value && $value->can('displayable_name')) ? $value->displayable_name : '', id => "${id}_name", %params);
+ input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id) .
+ join('', map { $params{$_} ? input_tag("", delete $params{$_}, id => "${id}_${_}", type => 'hidden') : '' } qw(type category choose booked)) .
+ input_tag("", (ref $value && $value->can('displayable_name')) ? $value->displayable_name : '', id => "${id}_name", %params);
$::request->layout->add_javascripts('autocomplete_chart.js');
$::request->presenter->need_reinit_widgets($id);
- $self->html_tag('span', $ret, class => 'chart_picker');
+ html_tag('span', $ret, class => 'chart_picker');
}
+sub picker { goto &chart_picker }
+
1;
__END__
# Create an html link for editing/opening a chart
my $object = SL::DB::Manager::Chart->get_first;
- my $html = SL::Presenter->get->chart($object, display => 'inline');
+ my $html = SL::Presenter::Chart::chart($object, display => 'inline');
see also L<SL::Presenter>
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
+use SL::Presenter::Tag qw(input_tag html_tag name_to_id select_tag);
use Exporter qw(import);
-our @EXPORT = qw(customer_vendor customer vendor customer_vendor_picker);
+our @EXPORT_OK = qw(customer_vendor customer vendor customer_vendor_picker);
use Carp;
sub customer_vendor {
- my ($self, $customer_vendor, %params) = @_;
- return _customer_vendor($self, $customer_vendor, ref($customer_vendor) eq 'SL::DB::Customer' ? 'customer' : 'vendor', %params);
+ my ($customer_vendor, %params) = @_;
+ return _customer_vendor($customer_vendor, ref($customer_vendor) eq 'SL::DB::Customer' ? 'customer' : 'vendor', %params);
}
sub customer {
- my ($self, $customer, %params) = @_;
- return _customer_vendor($self, $customer, 'customer', %params);
+ my ($customer, %params) = @_;
+ return _customer_vendor($customer, 'customer', %params);
}
sub vendor {
- my ($self, $vendor, %params) = @_;
- return _customer_vendor($self, $vendor, 'vendor', %params);
+ my ($vendor, %params) = @_;
+ return _customer_vendor($vendor, 'vendor', %params);
}
sub _customer_vendor {
- my ($self, $cv, $type, %params) = @_;
+ my ($cv, $type, %params) = @_;
$params{display} ||= 'inline';
my $callback = $params{callback} ? '&callback=' . $::form->escape($params{callback}) : '';
my $text = join '', (
- $params{no_link} ? '' : '<a href="controller.pl?action=CustomerVendor/edit&db=' . $type . '&id=' . $self->escape($cv->id) . '">',
- $self->escape($cv->name),
+ $params{no_link} ? '' : '<a href="controller.pl?action=CustomerVendor/edit&db=' . $type . '&id=' . escape($cv->id) . '">',
+ escape($cv->name),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_escaped($text);
}
sub customer_vendor_picker {
- my ($self, $name, $value, %params) = @_;
+ my ($name, $value, %params) = @_;
croak 'Unknown "type" parameter' unless $params{type} =~ m{^(?:customer|vendor)$};
croak 'Unknown value class' if $value && ref($value) && (ref($value) !~ m{^SL::DB::(?:Customer|Vendor)$});
$value = $class->find_by(id => $value);
}
- my $id = delete($params{id}) || $self->name_to_id($name);
+ my $id = delete($params{id}) || name_to_id($name);
my @classes = $params{class} ? ($params{class}) : ();
push @classes, 'customer_vendor_autocomplete';
my $ret =
- $self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id,
+ input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id,
'data-customer-vendor-picker-data' => JSON::to_json(\%params),
) .
- $self->input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params);
+ input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params);
$::request->layout->add_javascripts('kivi.CustomerVendor.js');
$::request->presenter->need_reinit_widgets($id);
- $self->html_tag('span', $ret, class => 'customer_vendor_picker');
+ html_tag('span', $ret, class => 'customer_vendor_picker');
}
+sub picker { goto &customer_vendor_picker }
+
1;
__END__
# Customers:
my $customer = SL::DB::Manager::Customer->get_first;
- my $html = SL::Presenter->get->customer($customer, display => 'inline');
+ my $html = SL::Presenter::CustomerVendor::customer($customer, display => 'inline');
# Vendors:
my $vendor = SL::DB::Manager::Vendor->get_first;
- my $html = SL::Presenter->get->vendor($customer, display => 'inline');
+ my $html = SL::Presenter::Customer::Vendor::vendor($customer, display => 'inline');
=head1 FUNCTIONS
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(sales_delivery_order purchase_delivery_order);
+our @EXPORT_OK = qw(sales_delivery_order purchase_delivery_order);
use Carp;
sub sales_delivery_order {
- my ($self, $delivery_order, %params) = @_;
+ my ($delivery_order, %params) = @_;
- return _do_record($self, $delivery_order, 'sales_delivery_order', %params);
+ return _do_record($delivery_order, 'sales_delivery_order', %params);
}
sub purchase_delivery_order {
- my ($self, $delivery_order, %params) = @_;
+ my ($delivery_order, %params) = @_;
- return _do_record($self, $delivery_order, 'purchase_delivery_order', %params);
+ return _do_record($delivery_order, 'purchase_delivery_order', %params);
}
sub _do_record {
- my ($self, $delivery_order, $type, %params) = @_;
+ my ($delivery_order, $type, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="do.pl?action=edit&type=' . $type . '&id=' . $self->escape($delivery_order->id) . '">',
- $self->escape($delivery_order->donumber),
+ $params{no_link} ? '' : '<a href="do.pl?action=edit&type=' . $type . '&id=' . escape($delivery_order->id) . '">',
+ escape($delivery_order->donumber),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+ is_escaped($text);
}
1;
# Sales delivery orders:
my $object = SL::DB::Manager::DeliveryOrder->get_first(where => [ is_sales => 1 ]);
- my $html = SL::Presenter->get->sales_delivery_order($object, display => 'inline');
+ my $html = SL::Presenter::DeliveryOrder::sales_delivery_order($object, display => 'inline');
# Purchase delivery orders:
my $object = SL::DB::Manager::DeliveryOrder->get_first(where => [ or => [ is_sales => undef, is_sales => 0 ]]);
- my $html = SL::Presenter->get->purchase_delivery_order($object, display => 'inline');
+ my $html = SL::Presenter::DeliveryOrder::purchase_delivery_order($object, display => 'inline');
=head1 FUNCTIONS
package SL::Presenter::EscapedText;
use strict;
+use Exporter qw(import);
+
+our @EXPORT_OK = qw(escape is_escaped escape_js);
+our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
use JSON ();
-use overload '""' => \&escaped;
+use overload '""' => \&escaped_text;
+# static constructors
sub new {
my ($class, %params) = @_;
return $self;
}
-sub escaped {
+sub escape {
+ __PACKAGE__->new(text => $_[0]);
+}
+
+sub is_escaped {
+ __PACKAGE__->new(text => $_[0], is_escaped => 1);
+}
+
+sub escape_js {
+ my ($text) = @_;
+
+ $text =~ s|\\|\\\\|g;
+ $text =~ s|\"|\\\"|g;
+ $text =~ s|\n|\\n|g;
+
+ __PACKAGE__->new(text => $text, is_escaped => 1);
+}
+
+# internal magic
+sub escaped_text {
my ($self) = @_;
return $self->{text};
}
sub TO_JSON {
- goto &escaped;
+ goto &escaped_text;
}
1;
=head1 NAME
-SL::Presenter::EscapedText - Thin proxy object around HTML-escaped strings
+SL::Presenter::EscapedText - Thin proxy object to invert the burden of escaping HTML output
=head1 SYNOPSIS
- use SL::Presenter::EscapedText;
+ use SL::Presenter::EscapedText qw(escape is_escaped escape_js);
sub blackbox {
my ($text) = @_;
return SL::Presenter::EscapedText->new(text => $text);
+
+ # or shorter:
+ # return escape($text);
}
sub build_output {
escaped -- they should be able to simply escape it again. Without
producing stuff like '&amp;'.
-Stringification is overloaded. It will return the same as L<escaped>.
+Stringification is overloaded. It will return the same as L<escaped_text>.
This works together with the template plugin
L<SL::Template::Plugin::P> and its C<escape> method.
can be overridden by setting C<$params{is_escaped}> to a trueish
value.
-=item C<escaped>
+=item C<escape $text>
+
+Static constructor, can be exported. Equivalent to calling C<< new(text => $text) >>.
+
+=item C<is_escaped $text>
+
+Static constructor, can be exported. Equivalent to calling C<< new(text => $text, escaped => 1) >>.
+
+=item C<escape_js $text>
+
+Static constructor, can be exported. Like C<escape> but also escapes Javascript.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item C<escaped_text>
Returns the escaped string (not an instance of C<EscapedText> but an
actual string).
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(gl_transaction);
+our @EXPORT_OK = qw(gl_transaction);
use Carp;
sub gl_transaction {
- my ($self, $gl_transaction, %params) = @_;
+ my ($gl_transaction, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="gl.pl?action=edit&id=' . $self->escape($gl_transaction->id) . '">',
- $self->escape($gl_transaction->reference),
+ $params{no_link} ? '' : '<a href="gl.pl?action=edit&id=' . escape($gl_transaction->id) . '">',
+ escape($gl_transaction->reference),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_escaped($text);
}
1;
=head1 SYNOPSIS
my $object = SL::DB::Manager::GLTransaction->get_first();
- my $html = SL::Presenter->get->gl_transaction($object, display => 'inline');
+ my $html = SL::Presenter::GL::gl_transaction($object, display => 'inline');
=head1 FUNCTIONS
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(invoice sales_invoice ar_transaction purchase_invoice ap_transaction);
+our @EXPORT_OK = qw(invoice sales_invoice ar_transaction purchase_invoice ap_transaction);
use Carp;
sub invoice {
- my ($self, $invoice, %params) = @_;
+ my ($invoice, %params) = @_;
if ( $invoice->is_sales ) {
if ( $invoice->invoice ) {
- return _is_ir_record($self, $invoice, 'is', %params);
+ return _is_ir_record($invoice, 'is', %params);
} else {
- return _is_ir_record($self, $invoice, 'ar', %params);
+ return _is_ir_record($invoice, 'ar', %params);
}
} else {
if ( $invoice->invoice ) {
- return _is_ir_record($self, $invoice, 'ir', %params);
+ return _is_ir_record($invoice, 'ir', %params);
} else {
- return _is_ir_record($self, $invoice, 'ap', %params);
+ return _is_ir_record($invoice, 'ap', %params);
}
};
};
sub sales_invoice {
- my ($self, $invoice, %params) = @_;
+ my ($invoice, %params) = @_;
- return _is_ir_record($self, $invoice, 'is', %params);
+ _is_ir_record($invoice, 'is', %params);
}
sub ar_transaction {
- my ($self, $invoice, %params) = @_;
+ my ($invoice, %params) = @_;
- return _is_ir_record($self, $invoice, 'ar', %params);
+ _is_ir_record($invoice, 'ar', %params);
}
sub purchase_invoice {
- my ($self, $invoice, %params) = @_;
+ my ($invoice, %params) = @_;
- return _is_ir_record($self, $invoice, 'ir', %params);
+ _is_ir_record($invoice, 'ir', %params);
}
sub ap_transaction {
- my ($self, $invoice, %params) = @_;
+ my ($invoice, %params) = @_;
- return _is_ir_record($self, $invoice, 'ap', %params);
+ _is_ir_record($invoice, 'ap', %params);
}
sub _is_ir_record {
- my ($self, $invoice, $controller, %params) = @_;
+ my ($invoice, $controller, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="' . $controller . '.pl?action=edit&type=invoice&id=' . $self->escape($invoice->id) . '">',
- $self->escape($invoice->invnumber),
+ $params{no_link} ? '' : '<a href="' . $controller . '.pl?action=edit&type=invoice&id=' . escape($invoice->id) . '">',
+ escape($invoice->invnumber),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_escaped($text);
}
1;
# Sales invoices:
my $object = SL::DB::Manager::Invoice->get_first(where => [ invoice => 1 ]);
- my $html = SL::Presenter->get->sales_invoice($object, display => 'inline');
+ my $html = SL::Presenter::Invoice::sales_invoice($object, display => 'inline');
# AR transactions:
my $object = SL::DB::Manager::Invoice->get_first(where => [ or => [ invoice => undef, invoice => 0 ]]);
- my $html = SL::Presenter->get->ar_transaction($object, display => 'inline');
+ my $html = SL::Presenter::Invoice::ar_transaction($object, display => 'inline');
# Purchase invoices:
my $object = SL::DB::Manager::PurchaseInvoice->get_first(where => [ invoice => 1 ]);
- my $html = SL::Presenter->get->purchase_invoice($object, display => 'inline');
+ my $html = SL::Presenter::Invoice::purchase_invoice($object, display => 'inline');
# AP transactions:
my $object = SL::DB::Manager::PurchaseInvoice->get_first(where => [ or => [ invoice => undef, invoice => 0 ]]);
- my $html = SL::Presenter->get->ar_transaction($object, display => 'inline');
+ my $html = SL::Presenter::Invoice::ar_transaction($object, display => 'inline');
# use with any of the above ar/ap/is/ir types:
- my $html = SL::Presenter->get->invoice($object, display => 'inline');
+ my $html = SL::Presenter::Invoice::invoice($object, display => 'inline');
=head1 FUNCTIONS
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(letter);
+our @EXPORT_OK = qw(letter);
use Carp;
sub letter {
- my ($self, $letter, %params) = @_;
+ my ($letter, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="controller.pl?action=Letter/edit&letter.id=' . $self->escape($letter->id) . '">',
- $self->escape($letter->letternumber),
+ $params{no_link} ? '' : '<a href="controller.pl?action=Letter/edit&letter.id=' . escape($letter->id) . '">',
+ escape($letter->letternumber),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+ is_escaped($text);
}
1;
=head1 SYNOPSIS
my $letter = SL::DB::Manager::Letter->get_first(where => [ … ]);
- my $html = SL::Presenter->get->letter($letter, display => 'inline');
+ my $html = SL::Presenter::Letter::letter($letter, display => 'inline');
=head1 FUNCTIONS
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(sales_quotation sales_order request_quotation purchase_order);
+our @EXPORT_OK = qw(sales_quotation sales_order request_quotation purchase_order);
use Carp;
sub sales_quotation {
- my ($self, $order, %params) = @_;
+ my ($order, %params) = @_;
- return _oe_record($self, $order, 'sales_quotation', %params);
+ return _oe_record($order, 'sales_quotation', %params);
}
sub sales_order {
- my ($self, $order, %params) = @_;
+ my ($order, %params) = @_;
- return _oe_record($self, $order, 'sales_order', %params);
+ return _oe_record($order, 'sales_order', %params);
}
sub request_quotation {
- my ($self, $order, %params) = @_;
+ my ($order, %params) = @_;
- return _oe_record($self, $order, 'request_quotation', %params);
+ return _oe_record($order, 'request_quotation', %params);
}
sub purchase_order {
- my ($self, $order, %params) = @_;
+ my ($order, %params) = @_;
- return _oe_record($self, $order, 'purchase_order', %params);
+ return _oe_record($order, 'purchase_order', %params);
}
sub _oe_record {
- my ($self, $order, $type, %params) = @_;
+ my ($order, $type, %params) = @_;
$params{display} ||= 'inline';
my $number_method = $order->quotation ? 'quonumber' : 'ordnumber';
my $text = join '', (
- $params{no_link} ? '' : '<a href="oe.pl?action=edit&type=' . $type . '&id=' . $self->escape($order->id) . '">',
- $self->escape($order->$number_method),
+ $params{no_link} ? '' : '<a href="oe.pl?action=edit&type=' . $type . '&id=' . escape($order->id) . '">',
+ escape($order->$number_method),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_escaped($text);
}
1;
# Sales quotations:
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('sales_quotation') ]);
- my $html = SL::Presenter->get->sales_quotation($object, display => 'inline');
+ my $html = SL::Presenter::Order::sales_quotation($object, display => 'inline');
# Sales orders:
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('sales_order') ]);
- my $html = SL::Presenter->get->sales_order($object, display => 'inline');
+ my $html = SL::Presenter::Order::sales_order($object, display => 'inline');
# Requests for quotations:
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('request_quotation') ]);
- my $html = SL::Presenter->get->request_quotation($object, display => 'inline');
+ my $html = SL::Presenter::Order::request_quotation($object, display => 'inline');
# Purchase orders:
my $object = SL::DB::Manager::Order->get_first(where => [ SL::DB::Manager::Order->type_filter('purchase_order') ]);
- my $html = SL::Presenter->get->purchase_order($object, display => 'inline');
+ my $html = SL::Presenter::Order::purchase_order($object, display => 'inline');
=head1 FUNCTIONS
use SL::DB::Part;
use SL::DB::PartClassification;
use SL::Locale::String qw(t8);
+use SL::Presenter::EscapedText qw(escape is_escaped);
+use SL::Presenter::Tag qw(input_tag html_tag name_to_id select_tag);
use Exporter qw(import);
-our @EXPORT = qw(part_picker part select_classification classification_abbreviation type_abbreviation separate_abbreviation typeclass_abbreviation);
+our @EXPORT_OK = qw(
+ part_picker part select_classification classification_abbreviation
+ type_abbreviation separate_abbreviation typeclass_abbreviation
+);
+our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
use Carp;
sub part {
- my ($self, $part, %params) = @_;
+ my ($part, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="controller.pl?action=Part/edit&part.id=' . $self->escape($part->id) . '">',
- $self->escape($part->partnumber),
+ $params{no_link} ? '' : '<a href="controller.pl?action=Part/edit&part.id=' . escape($part->id) . '">',
+ escape($part->partnumber),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_escaped($text);
}
sub part_picker {
- my ($self, $name, $value, %params) = @_;
+ my ($name, $value, %params) = @_;
$value = SL::DB::Manager::Part->find_by(id => $value) if $value && !ref $value;
- my $id = $params{id} || $self->name_to_id($name);
+ my $id = $params{id} || name_to_id($name);
my @classes = $params{class} ? ($params{class}) : ();
push @classes, 'part_autocomplete';
my $ret =
- $self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id,
+ input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id,
'data-part-picker-data' => JSON::to_json(\%params),
) .
- $self->input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params);
+ input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params);
$::request->layout->add_javascripts('kivi.Part.js');
$::request->presenter->need_reinit_widgets($id);
- $self->html_tag('span', $ret, class => 'part_picker');
+ html_tag('span', $ret, class => 'part_picker');
}
+sub picker { goto &part_picker }
+
#
# shortcut for article type
#
sub type_abbreviation {
- my ($self, $part_type) = @_;
+ my ($part_type) = @_;
return $::locale->text('Assembly (typeabbreviation)') if $part_type eq 'assembly';
return $::locale->text('Part (typeabbreviation)') if $part_type eq 'part';
return $::locale->text('Assortment (typeabbreviation)') if $part_type eq 'assortment';
# shortcut for article type
#
sub classification_abbreviation {
- my ($self, $id) = @_;
+ my ($id) = @_;
SL::DB::Manager::PartClassification->cache_all();
my $obj = SL::DB::PartClassification->load_cached($id);
$obj && $obj->abbreviation ? t8($obj->abbreviation) : '';
}
sub typeclass_abbreviation {
- my ($self, $part) = @_;
+ my ($part) = @_;
return '' if !$part || !$part->isa('SL::DB::Part');
- return $self->type_abbreviation($part->part_type).$self->classification_abbreviation($part->classification_id);
+ return type_abbreviation($part->part_type) . classification_abbreviation($part->classification_id);
}
#
# shortcut for article type
#
sub separate_abbreviation {
- my ($self, $id) = @_;
+ my ($id) = @_;
SL::DB::Manager::PartClassification->cache_all();
my $obj = SL::DB::PartClassification->load_cached($id);
$obj && $obj->abbreviation && $obj->report_separate ? t8($obj->abbreviation) : '';
# generate selection tag
#
sub select_classification {
- my ($self, $name, %attributes) = @_;
+ my ($name, %attributes) = @_;
$attributes{value_key} = 'id';
$attributes{title_key} = 'description';
my $collection = SL::DB::Manager::PartClassification->get_all_sorted( where => $classification_type_filter );
$_->description($::locale->text($_->description)) for @{ $collection };
- return $self->select_tag( $name, $collection, %attributes );
+ select_tag( $name, $collection, %attributes );
}
1;
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
+use SL::Presenter::Tag qw(input_tag html_tag name_to_id select_tag);
use Exporter qw(import);
-our @EXPORT = qw(project project_picker);
+our @EXPORT_OK = qw(project project_picker);
use Carp;
sub project {
- my ($self, $project, %params) = @_;
+ my ($project, %params) = @_;
return '' unless $project;
my $callback = $params{callback} ? '&callback=' . $::form->escape($params{callback}) : '';
my $text = join '', (
- $params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&id=' . $self->escape($project->id) . $callback . '">',
- $self->escape($description),
+ $params{no_link} ? '' : '<a href="controller.pl?action=Project/edit&id=' . escape($project->id) . $callback . '">',
+ escape($description),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+ is_escaped($text);
}
sub project_picker {
- my ($self, $name, $value, %params) = @_;
+ my ($name, $value, %params) = @_;
$value = SL::DB::Manager::Project->find_by(id => $value) if $value && !ref $value;
- my $id = delete($params{id}) || $self->name_to_id($name);
+ my $id = delete($params{id}) || name_to_id($name);
my @classes = $params{class} ? ($params{class}) : ();
push @classes, 'project_autocomplete';
my $ret =
- $self->input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id) .
- join('', map { $params{$_} ? $self->input_tag("", delete $params{$_}, id => "${id}_${_}", type => 'hidden') : '' } qw(customer_id)) .
- $self->input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params);
+ input_tag($name, (ref $value && $value->can('id') ? $value->id : ''), class => "@classes", type => 'hidden', id => $id) .
+ join('', map { $params{$_} ? input_tag("", delete $params{$_}, id => "${id}_${_}", type => 'hidden') : '' } qw(customer_id)) .
+ input_tag("", ref $value ? $value->displayable_name : '', id => "${id}_name", %params);
$::request->layout->add_javascripts('autocomplete_project.js');
$::request->presenter->need_reinit_widgets($id);
- $self->html_tag('span', $ret, class => 'project_picker');
+ html_tag('span', $ret, class => 'project_picker');
}
+sub picker { goto &project_picker };
+
1;
__END__
=head1 SYNOPSIS
my $project = SL::DB::Manager::Project->get_first;
- my $html = SL::Presenter->get->project($project, display => 'inline');
+ my $html = SL::Presenter::Project->project($project, display => 'inline');
=head1 FUNCTIONS
use strict;
-use parent qw(Exporter);
+use SL::Presenter;
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(grouped_record_list empty_record_list record_list record);
+our @EXPORT_OK = qw(grouped_record_list empty_record_list record_list record);
use SL::Util;
}
sub record {
- my ($self, $record, %params) = @_;
+ my ($record, %params) = @_;
my %grouped = _group_records( [ $record ] ); # pass $record as arrayref
my $type = (keys %grouped)[0];
- return $self->sales_invoice( $record, %params) if $type eq 'sales_invoices';
- return $self->purchase_invoice($record, %params) if $type eq 'purchase_invoices';
- return $self->ar_transaction( $record, %params) if $type eq 'ar_transactions';
- return $self->ap_transaction( $record, %params) if $type eq 'ap_transactions';
- return $self->gl_transaction( $record, %params) if $type eq 'gl_transactions';
+ $record->presenter->sales_invoice( $record, %params) if $type eq 'sales_invoices';
+ $record->presenter->purchase_invoice($record, %params) if $type eq 'purchase_invoices';
+ $record->presenter->ar_transaction( $record, %params) if $type eq 'ar_transactions';
+ $record->presenter->ap_transaction( $record, %params) if $type eq 'ap_transactions';
+ $record->presenter->gl_transaction( $record, %params) if $type eq 'gl_transactions';
return '';
}
sub grouped_record_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
%params = map { exists $params{$_} ? ($_ => $params{$_}) : () } qw(edit_record_links with_columns object_id object_model);
my %groups = _sort_grouped_lists(_group_records($list));
my $output = '';
- $output .= _requirement_spec_list( $self, $groups{requirement_specs}, %params) if $groups{requirement_specs};
- $output .= _shop_order_list( $self, $groups{shop_orders}, %params) if $groups{shop_orders};
- $output .= _sales_quotation_list( $self, $groups{sales_quotations}, %params) if $groups{sales_quotations};
- $output .= _sales_order_list( $self, $groups{sales_orders}, %params) if $groups{sales_orders};
- $output .= _sales_delivery_order_list( $self, $groups{sales_delivery_orders}, %params) if $groups{sales_delivery_orders};
- $output .= _sales_invoice_list( $self, $groups{sales_invoices}, %params) if $groups{sales_invoices};
- $output .= _ar_transaction_list( $self, $groups{ar_transactions}, %params) if $groups{ar_transactions};
+ $output .= _requirement_spec_list( $groups{requirement_specs}, %params) if $groups{requirement_specs};
+ $output .= _shop_order_list( $groups{shop_orders}, %params) if $groups{shop_orders};
+ $output .= _sales_quotation_list( $groups{sales_quotations}, %params) if $groups{sales_quotations};
+ $output .= _sales_order_list( $groups{sales_orders}, %params) if $groups{sales_orders};
+ $output .= _sales_delivery_order_list( $groups{sales_delivery_orders}, %params) if $groups{sales_delivery_orders};
+ $output .= _sales_invoice_list( $groups{sales_invoices}, %params) if $groups{sales_invoices};
+ $output .= _ar_transaction_list( $groups{ar_transactions}, %params) if $groups{ar_transactions};
- $output .= _request_quotation_list( $self, $groups{purchase_quotations}, %params) if $groups{purchase_quotations};
- $output .= _purchase_order_list( $self, $groups{purchase_orders}, %params) if $groups{purchase_orders};
- $output .= _purchase_delivery_order_list($self, $groups{purchase_delivery_orders}, %params) if $groups{purchase_delivery_orders};
- $output .= _purchase_invoice_list( $self, $groups{purchase_invoices}, %params) if $groups{purchase_invoices};
- $output .= _ap_transaction_list( $self, $groups{ap_transactions}, %params) if $groups{ap_transactions};
+ $output .= _request_quotation_list( $groups{purchase_quotations}, %params) if $groups{purchase_quotations};
+ $output .= _purchase_order_list( $groups{purchase_orders}, %params) if $groups{purchase_orders};
+ $output .= _purchase_delivery_order_list($groups{purchase_delivery_orders}, %params) if $groups{purchase_delivery_orders};
+ $output .= _purchase_invoice_list( $groups{purchase_invoices}, %params) if $groups{purchase_invoices};
+ $output .= _ap_transaction_list( $groups{ap_transactions}, %params) if $groups{ap_transactions};
- $output .= _gl_transaction_list( $self, $groups{gl_transactions}, %params) if $groups{gl_transactions};
+ $output .= _gl_transaction_list( $groups{gl_transactions}, %params) if $groups{gl_transactions};
- $output .= _bank_transactions( $self, $groups{bank_transactions}, %params) if $groups{bank_transactions};
+ $output .= _bank_transactions( $groups{bank_transactions}, %params) if $groups{bank_transactions};
- $output .= _sepa_collection_list( $self, $groups{sepa_collections}, %params) if $groups{sepa_collections};
- $output .= _sepa_transfer_list( $self, $groups{sepa_transfers}, %params) if $groups{sepa_transfers};
+ $output .= _sepa_collection_list( $groups{sepa_collections}, %params) if $groups{sepa_collections};
+ $output .= _sepa_transfer_list( $groups{sepa_transfers}, %params) if $groups{sepa_transfers};
- $output .= _letter_list( $self, $groups{letters}, %params) if $groups{letters};
+ $output .= _letter_list( $groups{letters}, %params) if $groups{letters};
- $output = $self->render('presenter/record/grouped_record_list', %params, output => $output);
+ $output = SL::Presenter->get->render('presenter/record/grouped_record_list', %params, output => $output);
return $output;
}
+sub grouped_list { goto &grouped_record_list }
+
sub empty_record_list {
- my ($self, %params) = @_;
- return $self->grouped_record_list([], %params);
+ my (%params) = @_;
+ return grouped_record_list([], %params);
}
+sub empty_list { goto &empty_record_list }
+
sub record_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
my @columns;
$cell{value} = $spec->{data}->($obj);
} else {
- $cell{value} = $rel_type && $self->can($rel_type) ? $self->$rel_type($obj->$method, display => 'table-cell')
+ $cell{value} = ref $obj->$method && $obj->$method->isa('SL::DB::Object') && $obj->$method->presenter->can($rel_type) ? $obj->$method->presenter->$rel_type(display => 'table-cell')
: $type eq 'Rose::DB::Object::Metadata::Column::Date' ? $call->($obj, $method . '_as_date')
: $type =~ m/^Rose::DB::Object::Metadata::Column::(?:Float|Numeric|Real)$/ ? $::form->format_amount(\%::myconfig, $call->($obj, $method), 2)
: $type eq 'Rose::DB::Object::Metadata::Column::Boolean' ? $call->($obj, $method . '_as_bool_yn')
alignment => $data[0]->{columns}->[$_]->{alignment},
}, (0..scalar(@columns) - 1);
- return $self->render(
+ return SL::Presenter->get->render(
'presenter/record/record_list',
%params,
TABLE_HEADER => \@header,
);
}
+sub list { goto &record_list }
+
#
# private methods
#
}
sub _requirement_spec_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Requirement specs'),
type => 'requirement_spec',
columns => [
- [ $::locale->text('Requirement spec number'), sub { $self->requirement_spec($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Requirement spec number'), sub { $_[0]->presenter->requirement_spec(display => 'table-cell') } ],
[ $::locale->text('Customer'), 'customer' ],
[ $::locale->text('Title'), 'title' ],
[ $::locale->text('Project'), 'project', ],
}
sub _shop_order_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Shop Orders'),
type => 'shop_order',
columns => [
[ $::locale->text('Shop Order Date'), sub { $_[0]->order_date->to_kivitendo } ],
- [ $::locale->text('Shop Order Number'), sub { $self->shop_order($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Shop Order Number'), sub { $_[0]->presenter->shop_order(display => 'table-cell') } ],
[ $::locale->text('Transfer Date'), 'transfer_date' ],
[ $::locale->text('Amount'), 'amount' ],
],
}
sub _sales_quotation_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Sales Quotations'),
type => 'sales_quotation',
columns => [
[ $::locale->text('Quotation Date'), 'transdate' ],
- [ $::locale->text('Quotation Number'), sub { $self->sales_quotation($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Quotation Number'), sub { $_[0]->presenter->sales_quotation(display => 'table-cell') } ],
[ $::locale->text('Customer'), 'customer' ],
[ $::locale->text('Net amount'), 'netamount' ],
[ $::locale->text('Transaction description'), 'transaction_description' ],
}
sub _request_quotation_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Request Quotations'),
type => 'request_quotation',
columns => [
[ $::locale->text('Quotation Date'), 'transdate' ],
- [ $::locale->text('Quotation Number'), sub { $self->request_quotation($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Quotation Number'), sub { $_[0]->presenter->request_quotation(display => 'table-cell') } ],
[ $::locale->text('Vendor'), 'vendor' ],
[ $::locale->text('Net amount'), 'netamount' ],
[ $::locale->text('Transaction description'), 'transaction_description' ],
}
sub _sales_order_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Sales Orders'),
type => 'sales_order',
columns => [
[ $::locale->text('Order Date'), 'transdate' ],
- [ $::locale->text('Order Number'), sub { $self->sales_order($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Order Number'), sub { $_[0]->presenter->sales_order(display => 'table-cell') } ],
[ $::locale->text('Quotation'), 'quonumber' ],
[ $::locale->text('Customer'), 'customer' ],
[ $::locale->text('Net amount'), 'netamount' ],
}
sub _purchase_order_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Purchase Orders'),
type => 'purchase_order',
columns => [
[ $::locale->text('Order Date'), 'transdate' ],
- [ $::locale->text('Order Number'), sub { $self->purchase_order($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Order Number'), sub { $_[0]->presenter->purchase_order(display => 'table-cell') } ],
[ $::locale->text('Request for Quotation'), 'quonumber' ],
[ $::locale->text('Vendor'), 'vendor' ],
[ $::locale->text('Net amount'), 'netamount' ],
}
sub _sales_delivery_order_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Sales Delivery Orders'),
type => 'sales_delivery_order',
columns => [
[ $::locale->text('Delivery Order Date'), 'transdate' ],
- [ $::locale->text('Delivery Order Number'), sub { $self->sales_delivery_order($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Delivery Order Number'), sub { $_[0]->presenter->sales_delivery_order(display => 'table-cell') } ],
[ $::locale->text('Order Number'), 'ordnumber' ],
[ $::locale->text('Customer'), 'customer' ],
[ $::locale->text('Transaction description'), 'transaction_description' ],
}
sub _purchase_delivery_order_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Purchase Delivery Orders'),
type => 'purchase_delivery_order',
columns => [
[ $::locale->text('Delivery Order Date'), 'transdate' ],
- [ $::locale->text('Delivery Order Number'), sub { $self->purchase_delivery_order($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Delivery Order Number'), sub { $_[0]->presenter->purchase_delivery_order(display => 'table-cell') } ],
[ $::locale->text('Order Number'), 'ordnumber' ],
[ $::locale->text('Vendor'), 'vendor' ],
[ $::locale->text('Transaction description'), 'transaction_description' ],
}
sub _sales_invoice_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Sales Invoices'),
type => 'sales_invoice',
columns => [
[ $::locale->text('Invoice Date'), 'transdate' ],
[ $::locale->text('Type'), sub { $_[0]->displayable_type } ],
- [ $::locale->text('Invoice Number'), sub { $self->sales_invoice($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Invoice Number'), sub { $_[0]->presenter->sales_invoice(display => 'table-cell') } ],
[ $::locale->text('Quotation Number'), 'quonumber' ],
[ $::locale->text('Order Number'), 'ordnumber' ],
[ $::locale->text('Customer'), 'customer' ],
}
sub _purchase_invoice_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Purchase Invoices'),
type => 'purchase_invoice',
columns => [
[ $::locale->text('Invoice Date'), 'transdate' ],
- [ $::locale->text('Invoice Number'), sub { $self->purchase_invoice($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Invoice Number'), sub { $_[0]->presenter->purchase_invoice(display => 'table-cell') } ],
[ $::locale->text('Request for Quotation Number'), 'quonumber' ],
[ $::locale->text('Order Number'), 'ordnumber' ],
[ $::locale->text('Vendor'), 'vendor' ],
}
sub _ar_transaction_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('AR Transactions'),
type => 'ar_transaction',
columns => [
[ $::locale->text('Invoice Date'), 'transdate' ],
[ $::locale->text('Type'), sub { $_[0]->displayable_type } ],
- [ $::locale->text('Invoice Number'), sub { $self->ar_transaction($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Invoice Number'), sub { $_[0]->presenter->ar_transaction(display => 'table-cell') } ],
[ $::locale->text('Customer'), 'customer' ],
[ $::locale->text('Net amount'), 'netamount' ],
[ $::locale->text('Paid'), 'paid' ],
}
sub _ap_transaction_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('AP Transactions'),
type => 'ap_transaction',
columns => [
[ $::locale->text('Invoice Date'), 'transdate' ],
- [ $::locale->text('Invoice Number'), sub { $self->ap_transaction($_[0 ], display => 'table-cell') } ],
+ [ $::locale->text('Invoice Number'), sub { $_[0]->presenter->ap_transaction(display => 'table-cell') } ],
[ $::locale->text('Vendor'), 'vendor' ],
[ $::locale->text('Net amount'), 'netamount' ],
[ $::locale->text('Paid'), 'paid' ],
}
sub _gl_transaction_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('GL Transactions'),
type => 'gl_transaction',
columns => [
[ $::locale->text('Transdate'), 'transdate' ],
[ $::locale->text('Reference'), 'reference' ],
- [ $::locale->text('Description'), sub { $self->gl_transaction($_[0 ], display => 'table-cell') } ],
+ [ $::locale->text('Description'), sub { $_[0]->presenter->gl_transaction(display => 'table-cell') } ],
],
%params,
);
}
sub _bank_transactions {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Bank transactions'),
type => 'bank_transactions',
columns => [
[ $::locale->text('Transdate'), 'transdate' ],
- [ $::locale->text('Local Bank Code'), sub { $self->bank_code($_[0]->local_bank_account) } ],
- [ $::locale->text('Local account number'), sub { $self->account_number($_[0]->local_bank_account) } ],
+ [ $::locale->text('Local Bank Code'), sub { $_[0]->local_bank_account->presenter->bank_code } ],
+ [ $::locale->text('Local account number'), sub { $_[0]->local_bank_account->presenter->account_number } ],
[ $::locale->text('Remote Bank Code'), 'remote_bank_code' ],
[ $::locale->text('Remote account number'),'remote_account_number' ],
[ $::locale->text('Valutadate'), 'valutadate' ],
}
sub _sepa_export_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
my ($source, $destination) = $params{type} eq 'sepa_transfer' ? qw(our vc) : qw(vc our);
$params{title} = $params{type} eq 'sepa_transfer' ? $::locale->text('Bank transfers via SEPA') : $::locale->text('Bank collections via SEPA');
delete $params{edit_record_links};
- return $self->record_list(
+ return record_list(
$list,
columns => [
[ $::locale->text('Export Number'), 'sepa_export', ],
}
sub _sepa_transfer_list {
- my ($self, $list, %params) = @_;
- _sepa_export_list($self, $list, %params, type => 'sepa_transfer');
+ my ($list, %params) = @_;
+ _sepa_export_list($list, %params, type => 'sepa_transfer');
}
sub _sepa_collection_list {
- my ($self, $list, %params) = @_;
- _sepa_export_list($self, $list, %params, type => 'sepa_collection');
+ my ($list, %params) = @_;
+ _sepa_export_list($list, %params, type => 'sepa_collection');
}
sub _letter_list {
- my ($self, $list, %params) = @_;
+ my ($list, %params) = @_;
- return $self->record_list(
+ return record_list(
$list,
title => $::locale->text('Letters'),
type => 'letter',
columns => [
[ $::locale->text('Date'), 'date' ],
- [ $::locale->text('Letternumber'), sub { $self->letter($_[0], display => 'table-cell') } ],
+ [ $::locale->text('Letternumber'), sub { $_[0]->presenter->letter(display => 'table-cell') } ],
[ $::locale->text('Customer'), 'customer' ],
[ $::locale->text('Reference'), 'reference' ],
[ $::locale->text('Subject'), 'subject' ],
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(requirement_spec);
+our @EXPORT_OK = qw(requirement_spec);
use Carp;
sub requirement_spec {
- my ($self, $requirement_spec, %params) = @_;
+ my ($requirement_spec, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="controller.pl?action=RequirementSpec/show&id=' . $self->escape($requirement_spec->id) . '">',
- $self->escape($requirement_spec->id),
+ $params{no_link} ? '' : '<a href="controller.pl?action=RequirementSpec/show&id=' . escape($requirement_spec->id) . '">',
+ escape($requirement_spec->id),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_scaped($text);
}
1;
use strict;
-use parent qw(Exporter);
+use SL::Presenter::Text qw(truncate);
use Exporter qw(import);
-our @EXPORT = qw(requirement_spec_item_tree_node_title requirement_spec_item_jstree_data requirement_spec_item_dependency_list);
+our @EXPORT_OK = qw(requirement_spec_item_tree_node_title requirement_spec_item_jstree_data requirement_spec_item_dependency_list);
use Carp;
sub requirement_spec_item_tree_node_title {
- my ($self, $item) = @_;
+ my ($item) = @_;
- return join(' ', map { $_ || '' } ($item->fb_number, $self->truncate($item->parent_id ? $item->description_as_stripped_html : $item->title, at => 30)));
+ return join(' ', map { $_ || '' } ($item->fb_number, truncate($item->parent_id ? $item->description_as_stripped_html : $item->title, at => 30)));
}
+sub tree_node_title { goto &requirement_spec_item_tree_node_title }
+
sub requirement_spec_item_jstree_data {
- my ($self, $item, %params) = @_;
+ my ($item, %params) = @_;
- my @children = map { $self->requirement_spec_item_jstree_data($_, %params) } @{ $item->children_sorted };
+ my @children = map { requirement_spec_item_jstree_data($_, %params) } @{ $item->children_sorted };
my $type = !$item->parent_id ? 'section' : 'function-block';
my $class = $type . '-context-menu tooltip';
$class .= ' flagged' if $item->is_flagged;
return {
- data => $self->requirement_spec_item_tree_node_title($item),
+ data => requirement_spec_item_tree_node_title($item),
metadata => { id => $item->id, type => $type },
attr => { id => "fb-" . $item->id, href => $params{href} || '#', class => $class, title => $item->content_excerpt },
children => \@children,
};
}
+sub jstree_data { goto &requirement_spec_item_jstree_data }
+
sub requirement_spec_item_dependency_list {
- my ($self, $item) = @_;
+ my ($item) = @_;
$::locale->language_join([ map { $_->fb_number } @{ $item->dependencies } ]);
}
+sub dependency_list { goto &requirement_spec_item_dependency_list }
+
1;
use strict;
-use parent qw(Exporter);
-
use Exporter qw(import);
-our @EXPORT = qw(requirement_spec_text_block_jstree_data);
+our @EXPORT_OK = qw(requirement_spec_text_block_jstree_data);
use Carp;
use SL::JSON;
sub requirement_spec_text_block_jstree_data {
- my ($self, $text_block, %params) = @_;
+ my ($text_block, %params) = @_;
my $class = 'text-block-context-menu tooltip';
$class .= ' flagged' if $text_block->is_flagged;
};
}
+sub jstree_data { goto &requirement_spec_text_block_jstree_data }
+
1;
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(sepa_export);
+our @EXPORT_OK = qw(sepa_export);
use Carp;
sub sepa_export {
- my ($self, $sepa_export, %params) = @_;
+ my ($sepa_export, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="sepa.pl?action=bank_transfer_edit&vc=' . $self->escape($sepa_export->vc) . '&id=' . $self->escape($sepa_export->id) . '">',
- $self->escape($sepa_export->id),
+ $params{no_link} ? '' : '<a href="sepa.pl?action=bank_transfer_edit&vc=' . escape($sepa_export->vc) . '&id=' . escape($sepa_export->id) . '">',
+ escape($sepa_export->id),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+ is_escaped($text);
}
1;
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape is_escaped);
use Exporter qw(import);
-our @EXPORT = qw(shop_order);
+our @EXPORT_OK = qw(shop_order);
use Carp;
sub shop_order {
- my ($self, $shop_order, $type, %params) = @_;
+ my ($shop_order, $type, %params) = @_;
$params{display} ||= 'inline';
croak "Unknown display type '$params{display}'" unless $params{display} =~ m/^(?:inline|table-cell)$/;
my $text = join '', (
- $params{no_link} ? '' : '<a href="controller.pl?action=ShopOrder/show&id='.$self->escape($shop_order->id).'">',
- $self->escape($shop_order->shop_ordernumber),
+ $params{no_link} ? '' : '<a href="controller.pl?action=ShopOrder/show&id='. escape($shop_order->id) .'">',
+ escape($shop_order->shop_ordernumber),
$params{no_link} ? '' : '</a>',
);
- return $self->escaped_text($text);
+
+ is_escaped($text);
}
1;
--- /dev/null
+package SL::Presenter::Simple;
+
+use strict;
+
+use SL::Presenter::Tag qw(:ALL);
+use SL::Presenter::Text qw(:ALL);
+use SL::Presenter::EscapedText qw(:ALL);
+
+1;
+
use strict;
use SL::HTML::Restrict;
-
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape);
use Exporter qw(import);
-our @EXPORT = qw(html_tag input_tag hidden_tag javascript man_days_tag name_to_id select_tag checkbox_tag button_tag submit_tag ajax_submit_tag input_number_tag stringify_attributes restricted_html link);
+our @EXPORT_OK = qw(
+ html_tag input_tag hidden_tag javascript man_days_tag name_to_id select_tag
+ checkbox_tag button_tag submit_tag ajax_submit_tag input_number_tag
+ stringify_attributes restricted_html link
+);
+our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
use Carp;
}
sub stringify_attributes {
- my ($self, %params) = @_;
+ my (%params) = @_;
my @result = ();
while (my ($name, $value) = each %params) {
next unless $name;
next if $_valueless_attributes{$name} && !$value;
$value = '' if !defined($value);
- push @result, $_valueless_attributes{$name} ? $self->escape($name) : $self->escape($name) . '="' . $self->escape($value) . '"';
+ push @result, $_valueless_attributes{$name} ? escape($name) : escape($name) . '="' . escape($value) . '"';
}
return @result ? ' ' . join(' ', @result) : '';
}
sub html_tag {
- my ($self, $tag, $content, %params) = @_;
- my $attributes = $self->stringify_attributes(%params);
+ my ($tag, $content, %params) = @_;
+ my $attributes = stringify_attributes(%params);
return "<${tag}${attributes}>" unless defined($content);
return "<${tag}${attributes}>${content}</${tag}>";
}
sub input_tag {
- my ($self, $name, $value, %attributes) = @_;
+ my ($name, $value, %attributes) = @_;
_set_id_attribute(\%attributes, $name);
$attributes{type} ||= 'text';
- return $self->html_tag('input', undef, %attributes, name => $name, value => $value);
+ html_tag('input', undef, %attributes, name => $name, value => $value);
}
sub hidden_tag {
- my ($self, $name, $value, %attributes) = @_;
- return $self->input_tag($name, $value, %attributes, type => 'hidden');
+ my ($name, $value, %attributes) = @_;
+ input_tag($name, $value, %attributes, type => 'hidden');
}
sub man_days_tag {
- my ($self, $name, $object, %attributes) = @_;
+ my ($name, $object, %attributes) = @_;
my $size = delete($attributes{size}) || 5;
my $method = $name;
$method =~ s/^.*\.//;
- my $time_selection = $self->input_tag( "${name}_as_man_days_string", _call_on($object, "${method}_as_man_days_string"), %attributes, size => $size);
- my $unit_selection = $self->select_tag("${name}_as_man_days_unit", [[ 'h', $::locale->text('h') ], [ 'man_day', $::locale->text('MD') ]],
+ my $time_selection = input_tag("${name}_as_man_days_string", _call_on($object, "${method}_as_man_days_string"), %attributes, size => $size);
+ my $unit_selection = select_tag("${name}_as_man_days_unit", [[ 'h', $::locale->text('h') ], [ 'man_day', $::locale->text('MD') ]],
%attributes, default => _call_on($object, "${method}_as_man_days_unit"));
return $time_selection . $unit_selection;
}
sub name_to_id {
- my ($self, $name) = @_;
+ my ($name) = @_;
$name =~ s/\[\+?\]/ _id() /ge; # give constructs with [] or [+] unique ids
$name =~ s/[^\w_]/_/g;
}
sub select_tag {
- my ($self, $name, $collection, %attributes) = @_;
+ my ($name, $collection, %attributes) = @_;
_set_id_attribute(\%attributes, $name);
push(@options, [$value, $title, $selected{$value} || $default]);
}
- return join '', map { $self->html_tag('option', $self->escape($_->[1]), value => $_->[0], selected => $_->[2]) } @options;
+ return join '', map { html_tag('option', escape($_->[1]), value => $_->[0], selected => $_->[2]) } @options;
};
my $code = '';
- $code .= $self->html_tag('option', $self->escape($empty_title || ''), value => '') if $with_empty;
+ $code .= html_tag('option', escape($empty_title || ''), value => '') if $with_empty;
if (!$with_optgroups) {
$code .= $list_to_code->($collection);
} else {
$code .= join '', map {
my ($optgroup_title, $sub_collection) = @{ $_ };
- $self->html_tag('optgroup', $list_to_code->($sub_collection), label => $optgroup_title)
+ html_tag('optgroup', $list_to_code->($sub_collection), label => $optgroup_title)
} @{ $collection };
}
- return $self->html_tag('select', $code, %attributes, name => $name);
+ html_tag('select', $code, %attributes, name => $name);
}
sub checkbox_tag {
- my ($self, $name, %attributes) = @_;
+ my ($name, %attributes) = @_;
_set_id_attribute(\%attributes, $name);
}
my $code = '';
- $code .= $self->hidden_tag($name, 0, %attributes, id => $attributes{id} . '_hidden') if $for_submit;
- $code .= $self->html_tag('input', undef, %attributes, name => $name, type => 'checkbox');
- $code .= $self->html_tag('label', $label, for => $attributes{id}) if $label;
- $code .= $self->javascript(qq|\$('#$attributes{id}').checkall('$checkall');|) if $checkall;
+ $code .= hidden_tag($name, 0, %attributes, id => $attributes{id} . '_hidden') if $for_submit;
+ $code .= html_tag('input', undef, %attributes, name => $name, type => 'checkbox');
+ $code .= html_tag('label', $label, for => $attributes{id}) if $label;
+ $code .= javascript(qq|\$('#$attributes{id}').checkall('$checkall');|) if $checkall;
return $code;
}
sub button_tag {
- my ($self, $onclick, $value, %attributes) = @_;
+ my ($onclick, $value, %attributes) = @_;
_set_id_attribute(\%attributes, $attributes{name}) if $attributes{name};
$attributes{type} ||= 'button';
$onclick = 'if (!confirm("'. _J(delete($attributes{confirm})) .'")) return false; ' . $onclick if $attributes{confirm};
- return $self->html_tag('input', undef, %attributes, value => $value, onclick => $onclick);
+ html_tag('input', undef, %attributes, value => $value, onclick => $onclick);
}
sub submit_tag {
- my ($self, $name, $value, %attributes) = @_;
+ my ($name, $value, %attributes) = @_;
_set_id_attribute(\%attributes, $attributes{name}) if $attributes{name};
$attributes{onclick} = 'return confirm("'. _J(delete($attributes{confirm})) .'");';
}
- return $self->input_tag($name, $value, %attributes, type => 'submit', class => 'submit');
+ input_tag($name, $value, %attributes, type => 'submit', class => 'submit');
}
sub ajax_submit_tag {
- my ($self, $url, $form_selector, $text, %attributes) = @_;
+ my ($url, $form_selector, $text, %attributes) = @_;
$url = _J($url);
$form_selector = _J($form_selector);
my $onclick = qq|kivi.submit_ajax_form('${url}', '${form_selector}')|;
- return $self->button_tag($onclick, $text, %attributes);
+ button_tag($onclick, $text, %attributes);
}
sub input_number_tag {
- my ($self, $name, $value, %params) = @_;
+ my ($name, $value, %params) = @_;
_set_id_attribute(\%params, $name);
my @onchange = $params{onchange} ? (onChange => delete $params{onchange}) : ();
$::request->layout->add_javascripts('kivi.Validator.js');
$::request->presenter->need_reinit_widgets($params{id});
- return $self->input_tag(
+ input_tag(
$name, $::form->foramt_amount(\%::myconfig, $value),
"data-validate" => "number",
%params,
sub javascript {
- my ($self, $data) = @_;
- return $self->html_tag('script', $data, type => 'text/javascript');
+ my ($data) = @_;
+ html_tag('script', $data, type => 'text/javascript');
}
sub _set_id_attribute {
my ($attributes, $name, $unique) = @_;
if (!delete($attributes->{no_id}) && !$attributes->{id}) {
- $attributes->{id} = name_to_id(undef, $name);
+ $attributes->{id} = name_to_id($name);
$attributes->{id} .= '_' . $attributes->{value} if $unique;
}
- return %{ $attributes };
+ %{ $attributes };
}
my $html_restricter;
sub restricted_html {
- my ($self, $value) = @_;
+ my ($value) = @_;
$html_restricter ||= SL::HTML::Restrict->create;
return $html_restricter->process($value);
}
sub link {
- my ($self, $href, $content, %params) = @_;
+ my ($href, $content, %params) = @_;
$href ||= '#';
- return $self->html_tag('a', $content, %params, href => $href);
+ html_tag('a', $content, %params, href => $href);
}
1;
use strict;
-use parent qw(Exporter);
+use SL::Presenter::EscapedText qw(escape);
use Exporter qw(import);
-our @EXPORT = qw(format_man_days simple_format truncate);
+our @EXPORT_OK = qw(format_man_days simple_format truncate);
+our %EXPORT_TAGS = (ALL => \@EXPORT_OK);
use Carp;
sub truncate {
- my ($self, $text, %params) = @_;
+ my ($text, %params) = @_;
- return Common::truncate($text, %params);
+ escape(Common::truncate($text, %params));
}
sub simple_format {
- my ($self, $text, %params) = @_;
+ my ($text, %params) = @_;
$text = $::locale->quote_special_chars('HTML', $text || '');
}
sub format_man_days {
- my ($self, $value, %params) = @_;
+ my ($value, %params) = @_;
return '---' if $params{skip_zero} && !$value;
- return $self->escape($::locale->text('#1 h', $::form->format_amount(\%::myconfig, $value, 2))) if 8.0 > $value;
+ return escape($::locale->text('#1 h', $::form->format_amount(\%::myconfig, $value, 2))) if 8.0 > $value;
$value /= 8.0;
my $output = $::locale->text('#1 MD', int($value));
my $rest = ($value - int($value)) * 8.0;
$output .= ' ' . $::locale->text('#1 h', $::form->format_amount(\%::myconfig, $rest)) if $rest > 0.0;
- return $self->escape($output);
+ escape($output);
}
1;
use Scalar::Util qw(blessed);
use SL::Presenter;
+use SL::Presenter::ALL;
+use SL::Presenter::Simple;
use SL::Util qw(_hashify);
use strict;
my $presenter = $::request->presenter;
- if (!$presenter->can($method)) {
- $::lxdebug->message(LXDebug::WARN(), "SL::Presenter has no method named '$method'!");
- return '';
+ splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');
+
+ if (my $sub = SL::Presenter::Simple->can($method)) {
+ return $sub->(@args);
}
- splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');
+ if ($presenter->can($method)) {
+ return $presenter->$method(@args);
+ }
- $presenter->$method(@args);
+ $::lxdebug->message(LXDebug::WARN(), "SL::Presenter has no method named '$method'!");
+ return;
}
sub name_to_id { return _call_presenter('name_to_id', @_); }
sub javascript { return _call_presenter('javascript', @_); }
sub truncate { return _call_presenter('truncate', @_); }
sub simple_format { return _call_presenter('simple_format', @_); }
-sub part_picker { return _call_presenter('part_picker', @_); }
-sub chart_picker { return _call_presenter('chart_picker', @_); }
-sub customer_vendor_picker { return _call_presenter('customer_vendor_picker', @_); }
-sub project_picker { return _call_presenter('project_picker', @_); }
sub button_tag { return _call_presenter('button_tag', @_); }
sub submit_tag { return _call_presenter('submit_tag', @_); }
sub ajax_submit_tag { return _call_presenter('ajax_submit_tag', @_); }
use base qw( Template::Plugin );
use SL::Presenter;
+use SL::Presenter::ALL;
+use SL::Presenter::Simple;
use SL::Presenter::EscapedText;
use strict;
our $AUTOLOAD;
my ($self, @args) = @_;
-
my $presenter = SL::Presenter->get;
my $method = $AUTOLOAD;
$method =~ s/.*:://;
return '' if $method eq 'DESTROY';
- if (!$presenter->can($method)) {
- $::lxdebug->message(LXDebug::WARN(), "SL::Presenter has no method named '$method'!");
- return '';
+ splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');
+
+ if ($SL::Presenter::ALL::presenters{$method}) {
+ return SL::Presenter::ALL::wrap($SL::Presenter::ALL::presenters{$method});
}
- splice @args, -1, 1, %{ $args[-1] } if @args && (ref($args[-1]) eq 'HASH');
+ if (my $sub = SL::Presenter::Simple->can($method)) {
+ return $sub->(@args);
+ }
+
+ if ($presenter->can($method)) {
+ return $presenter->$method(@args);
+ }
- $presenter->$method(@args);
+ $::lxdebug->message(LXDebug::WARN(), "SL::Presenter has no method named '$method'!");
+ return;
}
1;
[% USE P %]
- Customer: [% P.customer(customer) %]
+ Customer: [% customer.presenter.customer %]
Linked records:
- [% P.grouped_record_list(RECORDS) %]
+ [% P.record.grouped_list(RECORDS) %]
=head1 FUNCTIONS