Re: [Catalyst] Maybe there is a need for some speedups of 'config' method ?

2009-02-23 Thread Jason Gottshall

Oleg Pronin wrote:

  I use many actions that take params from config in runtime, for example
  sub pay_for_vip : Private {
   ...
   my $price = $c-cfg-{vip}{price};
  }


As I understand it, this is NOT the way config is intended to work. All 
the config for your component (controller in this case) is passed to the 
constructor at setup time; all you need to do is make accessors for 
whatever you want access to:


  __PACKAGE__-mk_accessors(qw/vip/);

  sub pay_for_vip : Private {
  ...
  my $price = $self-vip-{price};
  }

--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] stripping path parts and then redispatch?

2009-02-23 Thread Jason Gottshall

Larry Leszczynski wrote:

Hi Lars -


I have an existing site, and want to add the page language to the URLs
so that caching will work correctly, e.g. /foo/bar would now look like
/en/foo/bar or /fr/foo/bar.

Apart from the missing true return value from auto, this works:

http://lists.scsys.co.uk/pipermail/catalyst/2009-February/021072.html


Thanks for the pointer.  But this approach only seems to work for Local
actions, not Private actions like default().  E.g. using these
controllers:

#

package MyApp::Controller::Foo;
use parent 'Catalyst::Controller';

sub default :Private {
my ($self, $c, @args) = @_;
$c-response-body(Foo args: @args);
}


That construct is deprecated. You can do basically the same thing with:

  sub default : Path {
  ...
  }

See:
http://search.cpan.org/dist/Catalyst-Manual/lib/Catalyst/Manual/Intro.pod#Built-in_Private_Actions

--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] How to clear off request parameter element

2009-02-23 Thread Jason Gottshall

kakim...@tpg.com.au wrote:

hi all


 I have an app with a listing method in the controller. It goes a little
like this:

sub list
{
  # get object from model based on $c-request-param('id');

  IF (object)
  {
   return;
  }
  ELSE
  {
   return all objects belonging to the current user;
  }

return 1;
}



then , i have a deletion method which will delete a given object (by ID
specific in a form via POST method) and list out all objects belonging
to the current user.

sub delete
{
 # get specific object based on ID  ($c-request-param('id');)

  #delete object

 $c-forward( 'list' );
}


The problem here is that sub list will always call the
$c-request-param('id'); which is no longer valid once an object has
been deleted.

 What is the best way to delete the 'id' attribute off $c-request-param??

thank you.

K. akimoto


What if, after the delete is performed, the user decides to bookmark the 
list of items? The bookmark will be the URL to delete, instead of the 
more appropriate URL to list. Instead of forwarding within the current 
request, you should consider an actual redirect to your list page. It 
admittedly does require an extra request cycle, but the user's 
experience will be more correct.


--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] RFC: Catalyst::Controller::RHTMLO

2009-02-03 Thread Jason Gottshall

Zbigniew Lukasiak wrote:

On Mon, Feb 2, 2009 at 7:59 PM, Jason Gottshall jgottsh...@capwiz.com wrote:

Zbigniew Lukasiak wrote:

Maybe I am just being lazy now - but before I start digging too deep -
did you take into accout that some forms require loading stuff from
the DB?  It can happen in to cases:

1) loading SELECT choices lists - this one is easy - because it can be
done at initialisation as it does not depend on th request.

2) loading related forms for one to many relations - where you don't
know how many related forms you need until you have the main object -
i.e. until request time.  See Rose::HTML::Form::Repeatable.

Yes, I'm actually thinking of doing

 my $form = $class-new( app = $c );

so that the form can access model-related stuff as necessary. (This is safe
because RHTMLO automatically weakens any value passed to -app). Would
something like that address your cases?


Hmm - I thought you mentioned something about caching the form objects
between requests?  Passing $c to the creator means you create the
forms on per request basis.   If you like the caching idea - then what
would be needed is a kind of two phase initialisation.  First you
create a prototype - and then you add the necessary repeatable
sub-forms on per request basis to it (of course this is only needed if
you use repeatable sub-forms).


Yeah, I gave up on caching for now, mostly due to concerns about form 
mutability. And it's a premature optimization that will be harder to 
code for given the other factors I'm dealing with, so I don't want to 
think about it yet.


The example you cite raises precisely one of my concerns: if you start 
with a cached prototype form and add subforms per-request, you have to 
make sure you include some sort of cleanup or reset routine to clear out 
the temporary subforms from the previous request. By extension, many 
various temporary modifications to the form structure (other than merely 
adding subforms) are possible, so we'd need to develop some kind of 
generic mechanism for removing these modifications. My brain isn't ready 
to tackle that problem right now, so I'm blissfully ignoring it :-)



--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] RFC: Catalyst::Controller::RHTMLO

2009-02-02 Thread Jason Gottshall

Zbigniew Lukasiak wrote:

Maybe I am just being lazy now - but before I start digging too deep -
did you take into accout that some forms require loading stuff from
the DB?  It can happen in to cases:

1) loading SELECT choices lists - this one is easy - because it can be
done at initialisation as it does not depend on th request.

2) loading related forms for one to many relations - where you don't
know how many related forms you need until you have the main object -
i.e. until request time.  See Rose::HTML::Form::Repeatable.


Yes, I'm actually thinking of doing

  my $form = $class-new( app = $c );

so that the form can access model-related stuff as necessary. (This is 
safe because RHTMLO automatically weakens any value passed to -app). 
Would something like that address your cases?


--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Re: [RHTMLO] RFC: Catalyst::Controller::RHTMLO

2009-01-27 Thread Jason Gottshall

Jason Gottshall wrote:

John Siracusa wrote:
On Mon, Jan 26, 2009 at 1:43 PM, Jason Gottshall 
jgottsh...@capwiz.com wrote:
Caching sounds wise. The only kink I see is that my controller allows 
for

multiple instances of the same form.


The same form meaning what?  If you store forms keyed by an
arbitrary name string, you can have as many forms as you want so long
as the names are unique.


My implementation is designed to instantiate subclasses of 
Rose::HTML::Form based on the class name, which would likely also be the 
cache key, hence the difficulty in having multiple instances of the same 
form.


Honestly, the only use case I can actually envision for having the same 
form on a page more than once is maybe displaying a simple search form 
both above and below a set of results, and even then you wouldn't 
actually need two instances of the class, you'd just need to render the 
same object twice. Unless anyone can see a use case I'm missing, I think 
the point is moot, and I will just remove that whole same form twice 
concept from the module and be done with it.


I've been thinking some more about the caching issue, and I'm concerned 
about the fact that rose form objects are mutable beyond just setting 
values for the fields. Any code that works with a form object can 
add/delete fields and subforms, monkey with validation routines, etc. 
Unless I can reset a form object to it's new()-like state before I 
reuse it, it seems like I really need a whole new instance to work with 
on each request. I haven't benchmarked yet; is there really that much 
overhead in constructing these form objects?


--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Re: [RHTMLO] RFC: Catalyst::Controller::RHTMLO

2009-01-26 Thread Jason Gottshall

Peter Karman wrote:

Jason Gottshall wrote on 1/22/09 4:52 PM:

[Cross-posted to catalyst-users and rhtmlo lists]

I know there are several modules out there that hook up rhtmlo and 
catalyst, but none of them do what I want. They all seem to do too much: 
connect to a CRUD API, interface with rdbo, build a form object from a 
config file, etc. I really just need a simple glue to load 
rhtmlo-derived form classes into my catalyst controller actions and 
initialize them with any query params, so I created a base controller 
and an action class that take care of the details. It works for me, but 
I thought it might be useful to the larger community, so I made it 
configurable and documented it pretty thoroughly. But before I pollute 
CPAN with one more piece of cruft, I want to be sure it's 
sensible/useful. The two packages are defined below. Comments would be 
appreciated.


As the author of some of the modules that do too much, I like this idea. I
especially like the use of the Action class.


Thanks. I can't take credit for the Action class stuff; I borrowed the 
idea and much of the technique from Catalyst::Controller::FormBuilder.



I second John's suggestion of caching Form objects. I do that in
CatalystX::CRUD::Controller::RHTMLO, and esp for forms that contain select lists
(e.g. state or country names) it saves a huge overhead in form initialization.


Caching sounds wise. The only kink I see is that my controller allows 
for multiple instances of the same form. But I only added that support 
because I was trying to anticipate what would happen if someone actually 
tried it; I haven't yet run into that use case myself. I think I could 
still make it work, even with caching, but if not I think the value 
caching wins out over support for multiple instances of the same form.


I'll have a run at implementing caching before distributing it...

--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Re: [RHTMLO] RFC: Catalyst::Controller::RHTMLO

2009-01-26 Thread Jason Gottshall

John Siracusa wrote:

On Mon, Jan 26, 2009 at 1:43 PM, Jason Gottshall jgottsh...@capwiz.com wrote:

Caching sounds wise. The only kink I see is that my controller allows for
multiple instances of the same form.


The same form meaning what?  If you store forms keyed by an
arbitrary name string, you can have as many forms as you want so long
as the names are unique.


My implementation is designed to instantiate subclasses of 
Rose::HTML::Form based on the class name, which would likely also be the 
cache key, hence the difficulty in having multiple instances of the same 
form.


Honestly, the only use case I can actually envision for having the same 
form on a page more than once is maybe displaying a simple search form 
both above and below a set of results, and even then you wouldn't 
actually need two instances of the class, you'd just need to render the 
same object twice. Unless anyone can see a use case I'm missing, I think 
the point is moot, and I will just remove that whole same form twice 
concept from the module and be done with it.


--
Jason Gottshall
jgottsh...@capwiz.com


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


[Catalyst] RFC: Catalyst::Controller::RHTMLO

2009-01-22 Thread Jason Gottshall
::Action';

sub execute {
my $self = shift;
my ($controller, $c, @args) = @_;

# load forms via base class
$self-next::method(@_);

# do cool stuff
$c-stash-{form}-add_fields(
secure_token = {
type  = 'hidden',
value = $c-some_cool_security_token
}
);
return;
}

=item Cform_attr

Default: 'Form'. Set this to alter the subroutine attribute used to 
indicate

one or more forms to be loaded by a given action, e.g.:

sub edit : Local HasForm('Books') { }

=item Cform_prefix

Default: 'MyApp::Form' (using your app's actual name). Set this to the
namespace where your Rose::HTML::Form subclasses live.

=item Cstash_hash_name

Default: 'forms'. Sets the stash key under which all forms for a given 
action

will be stored by class name.

=item Cstash_name

Default: 'form'. Sets the stash key under which the first form for a given
action will be stored.

=head1 PRIOR ART

There are several other modules on CPAN that do similar things, many having
inspired this module in various ways.

=over

=item LCatalyst::Controller::FormBuilder

Provided a lot of insight into how to trigger the form loading process 
with a

custom subroutine attribute. Based on LCGI::FormBuilder rather than
Rose::HTML::Form.

=item LCatalystX::RoseIntegrator

Looks like it uses a CGI::FormBuilder-style config file to construct
Rose::HTML::Form objects on the fly, rather than having static 
subclasses. Also

seems to include direct model integration with LRose::DB::Object.

=item LCatalystX::CRUD::Controller::RHTMLO

A component that enables use of Rose::HTML::Form objects with Peter 
Karman's

cool LCatalystX::CRUD API.

=back

=head1 SEE ALSO

LRose::HTML::Form, LRose::HTML::Objects, LRose::Object,
LCatalyst::Controller, LCatalyst::Action, LCatalyst

=head1 AUTHOR

Jason Gottshall jgottshall att capwiz dott com

=head1 LICENSE

This program is free software; you can redistribute it and/or modify it 
under the same terms as Perl itself.


=cut

sub create_action {
my ($self, %args) = @_;

my $config = $self-config-{'Controller::RHTMLO'};
my $form_attr = $config-{'form_attr'} || 'Form';

if( exists $args{attributes}{$form_attr} ) {
my $action_class = $config-{'action_class'} || 
'Catalyst::Controller::RHTMLO::Action';

push @{ $args{attributes}{ActionClass} }, $action_class;

if(my $val = delete $args{attributes}{$form_attr}) {
$args{_form_class} = $val;
}
}

return $self-next::method(%args);
}

package Catalyst::Controller::RHTMLO::Action;

use strict;
use warnings;

use base 'Catalyst::Action';
use MRO::Compat;
use Catalyst::Utils;

__PACKAGE__-mk_accessors(qw/_form_class/);

sub execute {
my $self = shift;
my ($controller, $c, @args) = @_;

$self-get_forms($c);

return $self-next::method(@_);
}

sub get_forms {
my ($self, $c) = @_;

# sanity check; ensure we actually declared form class
return unless $self-_form_class  ref $self-_form_class eq 'ARRAY';

# form classes are delimited by spaces or commas
my @classes = split /[ ,]+/, $self-_form_class-[0];
unless(@classes) {
$c-log-warn('No form class specified for action ' . 
$self-reverse . '');

return;
}

my $config  = $c-config-{'Controller::RHTMLO'};
my $stash_name  = $config-{'stash_name'}  || 'form';
my $stash_hash  = $config-{'stash_hash_name'} || 'forms';
my $form_prefix = $config-{'form_prefix'} || 
$c-config-{'name'} . '::Form';

$form_prefix .= '::';

foreach my $name (@classes) {
next unless $name; # ignore leading/trailing delimiters

my $class = $name;
# allow for full class names with leading '+'
$class = $form_prefix . $class unless $class =~ s/^\+//;
Catalyst::Utils::ensure_class_loaded($class);
$c-log-debug(Loading form '$class');

# setup form
my $form = $class-new();
$form-params($c-req-params);
$form-init_fields;

# put form in stash under its name
if(my $prev_form = $c-stash-{$stash_hash}-{$name}) {
# multiple instances of same form class are stored in arrayref
$c-stash-{$stash_hash}-{$name} = [$prev_form]
unless ref $prev_form eq 'ARRAY';

push @{$c-stash-{$stash_hash}-{$name}}, $form;
}
else {
$c-stash-{$stash_hash}-{$name} = $form;
}

# create shortcut to main form
$c-stash-{$stash_name} ||= $form;
}

return;
}

1;



___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Example app showing user to item authorization?

2008-12-10 Thread Jason Gottshall

Tomas Doran wrote:


On 9 Dec 2008, at 04:24, bill hauck wrote:
So my question: is there an example application or best practice on 
how to implement a check on all calls to see if the user should be 
accessing a specific item?  I guess this would apply to any type of 
system: blog, auction, cms, etc. -- they all require checking if a 
specific user can edit a specific item.


Assuming that you're using DBIx::Class, then the common way of doing 
this would be to use ResultSet chaining to limit things.


What you do is add a 'limit_by_user' method (name is not important - 
just pick one and stick to it for your entire app) on each ResultSet 
class which you can pass $c-user, and have it return a filtered result 
set..


You then arrange your controllers such that you will call this method on 
all resultsets before actually searching them. The simplest strategy is 
to just have code like:


$c-stash-{project} = 
$c-model('DB::Project')-limit_by_user($c-user)-find_by_foo($foo);


whenever you want to do a search.


You might try using DBIx::Class::Schema::RestrictWithObject to do this 
more centrally. Essentially you put all your limit_by_user filters 
into one central package, then you just pass $c-user to the schema at 
the beginning of the request. RestrictWithObject will intercept all 
searches and tack on the appropriate filter for the requested resultset 
for you.


HTH,
Jason

--
Jason Gottshall
[EMAIL PROTECTED]


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/


Re: [Catalyst] Catalyst Chained talk at Orlando Perl Oasis - January 17th, 2009

2008-11-26 Thread Jason Gottshall

J. Shirley wrote:

You can give information on the conference at http://perloasis.org/opw/


Correct conference URL is http://perloasis.org/opw2009/


--
Jason Gottshall
[EMAIL PROTECTED]


___
List: Catalyst@lists.scsys.co.uk
Listinfo: http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/catalyst@lists.scsys.co.uk/
Dev site: http://dev.catalyst.perl.org/