Re: [Catalyst] formfu->JSON

2008-11-10 Thread Charles Bailey
On Mon, Nov 10, 2008 at 3:24 PM, Paul Tichonczuk <[EMAIL PROTECTED]> wrote:
> Hi,
> I'm new to Catalyst.
> I've gone through both the Catalyst Tutorial and the Catalyst book.
>
> I'm trying out FormFu + Jemplate.
>
> Basic problem I've come up to is redering a FormFu form into JSON for
> sending to the client.
>
> I keep getting:
> [error] Caught exception in MyApp::View::JSON->process "encountered
> object 'MyApp::Controller::Books=HASH(0x9f4406c)', but neither
> allow_blessed nor convert_blessed settings are enabled at
> /usr/local/share/perl/5.8.8/JSON/Any.pm line 426."

It looks as though you're trying to render your controller object into
the JSON response.  By default, C::V::JSON tries to serialize all keys
in the stash; have you perhaps stored some object references there?

If your intent is to render only specific values from the hash, you
should look at the expose_stash configuration option to C::V::JSON.

If you do want to serialize object, then you'll need to override the
default encode_json() and use a JSON encoder with the convert_blessed
or allow_blessed options set, perhaps combined with TO_JSON() in the
object class(es).  I've attached a (very underdeveloped and
underdocumented) utility class that I've found helpful  when dealing
with simple hash-based classes.

-- 
Regards,
Charles Bailey
Lists: bailey _dot_ charles _at_ gmail _dot_ com
Other: bailey _at_ newman _dot_ upenn _dot_ edu
#!/usr/local/bin/perl
#

use 5.010;
package JSON::Able;
use Moose::Role;


use Carp qw(croak);
use Scalar::Util qw(blessed reftype refaddr);
use JSON qw();

our($VERSION) = '0.01';
our($REVISION) = '$Revision$' =~ /: (\d+)/ ? $1 : 0;

# Used only for non-Moose consumer classes
our(@EXPORT_OK) = qw(TO_JSON encode_json as_json
 json_key_filter json_value_transform json_pretty);
our(%EXPORT_TAGS) = (all => [ @EXPORT_OK ]);
sub import { require Exporter; goto &Exporter::import; }

# Track configuration options for target packages, since JSON::XS does
# not provide for any way to pass options to TO_JSON.  We could make
# this a wrapper around our own method which does accept options, but
# that would compete with Moose::Role's injection of methods . . .
my(%Config);

sub _get_config_data {
  my($thing,$create) = @_;
  my $pkg = blessed($thing) // $thing;
  if (ref $thing) {
my $oid = (blessed($thing) || reftype($thing)) . '(' . refaddr($thing) . 
')';
return $Config{$oid} if exists $Config{$oid};
return $Config{$pkg} if exists $Config{$pkg};
$Config{$oid} ||= {} if $create;
return $Config{$oid} || {};
  }
  $Config{$pkg} ||= {} if $create;
  return $Config{$pkg} || {};
}

sub _configure_option {
  my($opt,$thing,$val) = @_;
  my $cfg = _get_config_data($thing, @_ > 2);
  my $old = $cfg->{$opt};
  if (@_ > 2) {
$cfg->{$opt} = $val;
  }
  $old;
}
  
sub json_key_filter { _configure_option('KEY_FILTER', @_); }

sub json_value_transform { _configure_option('VALUE_TRANSFORM', @_); }

sub json_pretty { _configure_option('PRETTY', @_); }

sub TO_JSON {
  my $self = shift;
  my $pkg = blessed $self;
  my $vers = $self->VERSION;
  my $cfg = _get_config_data($self);
  my $key_filter = $cfg->{KEY_FILTER} || 
sub { $_[0] =~ /^(?!_)/ };
  my $val_xform = $cfg->{TRANSFORM_VALUES} ||
sub { my($val,$isset) = @_; return $isset ? $val : (); };
  my(%attrs,%tojson);

  # If you implement this interface, we assume you're descended from
  # or behave like Moose
  if ($self->can('meta') and
  $self->meta->can('compute_all_applicable_attributes')) {
%attrs = map {$_->name => $_->has_value($self) }
  $self->meta->compute_all_applicable_attributes;
  }
  elsif (reftype($self) eq 'HASH') {
%attrs = map { $_ => 1 } keys %$self;
  }
  else {
croak("Don't know how to get attributes of \"$self\" for JSON");
  }

  foreach my $k (keys %attrs) {
next unless $key_filter->($k);
my $val = $self->can($k) ? $self->$k : $self->{$k};
my(@rslt) = $val_xform->($val, $attrs{$k});
next unless @rslt;
$val = $rslt[0];
# Special-case DateTime, which is used frequently in the project
# hierarchy.  It doesn't provide a TO_JSON method, but has a
# perfectly serviceable overloading of ""
if (blessed($val) and $val->isa('DateTime')) { $val = "$val"; }
$tojson{$k} = $val;
  }

  # Include some metadata to simplify recreating objects
  # if data ever comes back
  $tojson{_source_class} = $pkg;
  $tojson{_source_class_version} = $vers;

  \%tojson;
}

sub encode_json {
  my $cfg = _get_config_data($_[0]);
  JSON->new->pretty($cfg->{PRETTY} // 1)->
convert_blessed->encode(shift);
}

*as_js

Re: [Catalyst] [Announce] Catalyst-Runtime 5.7099_01 - Developer Release

2008-09-10 Thread Charles Bailey
On Mon, Sep 8, 2008 at 4:57 AM, Jan Henning Thorsen <[EMAIL PROTECTED]> wrote:
> On Sun, Aug 24, 2008 at 8:01 PM, Matt S Trout <[EMAIL PROTECTED]> wrote:
>>
>> The dispatcher change is sadly insufficient.
>>
>> Because visit() returns, you really need to reset action and namespace.
>>
>> local is one option, simple code to do so another.

Argh -- of course.

> Here's another *go* on "go" and "visit":
> http://flodhest.net/files/perl/catalyst-go/
>
> All tests succeed. I've also added some tests that check if you're
> trying to ->go() to a view/model.

Thanks -- that's a step beyond the fix I was about to send.

-- 
Regards,
Charles Bailey
Lists: bailey _dot_ charles _at_ gmail _dot_ com
Other: bailey _at_ newman _dot_ upenn _dot_ edu

___
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] [Announce] Catalyst-Runtime 5.7099_01 - Developer Release

2008-08-12 Thread Charles Bailey
On Mon, Jul 21, 2008 at 5:32 PM, Matt S Trout <[EMAIL PROTECTED]> wrote:
> On Mon, Jul 21, 2008 at 07:13:37AM -0400, Charles Bailey wrote:
>> Agreed.  I've had it on TODO for the past two weeks, but getting
>> hammered at dayjob. Will try to do this week.
>
> We're one more dev release short of shipping. Please try because otherwise
> it'll probably have to wait until 5.80

Patch attached, following a severe tuit drought. I'm sorry I was
unable to turn it around faster, but I hope it's useful for the
future.

The dispatcher change is trivial; most of the size is tests.  These
are modelled closely on existing tests, with the thought that
consistency in the test suite is better than streamlining each case.

-- 
Regards,
Charles Bailey
Lists: bailey _dot_ charles _at_ gmail _dot_ com
Other: bailey _at_ newman _dot_ upenn _dot_ edu


Catalyst_visit.patch
Description: Binary data
___
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] [Announce] Catalyst-Runtime 5.7099_01 - Developer Release

2008-07-21 Thread Charles Bailey
Agreed.  I've had it on TODO for the past two weeks, but getting
hammered at dayjob. Will try to do this week.

Regards,
Charlie



On 7/19/08, Matt S Trout <[EMAIL PROTECTED]> wrote:
> On Thu, Jun 26, 2008 at 06:50:58PM -0400, Charles Bailey wrote:
>> On Wed, Jun 25, 2008 at 4:57 PM, Marcus Ramberg <[EMAIL PROTECTED]>
>> wrote:
>> >
>> > The feature to note here is 'go', which works like an internal
>> > redispatch to
>> > another action, while retaining the stash intact. Being able to do this
>> > means that in practice you don't ever need to set the template name in
>> > stash, but can depend on using go when you want to render the template
>> > of
>> > the other action, rather than the one you dispatched to.
>>
>> Would it make sense to include a function analogous to forward() (say,
>> "visit()") in the same way that go() is analogous to detach()?  Seems
>> like it'd be a nice way to "wrap" an action that uses auto() or end()
>> in its controller to handle tasks common to several actions there.
>
> Maybe. How about doing up a patch for catalyst-dev@ ?
>
> --
>   Matt S Trout   Need help with your Catalyst or DBIx::Class
> project?
>Technical Director
> http://www.shadowcat.co.uk/catalyst/
>  Shadowcat Systems Ltd.  Want a managed development or deployment platform?
> http://chainsawblues.vox.com/http://www.shadowcat.co.uk/servers/
>
> ___
> 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/
>


-- 
Regards,
Charles Bailey
Lists: bailey _dot_ charles _at_ gmail _dot_ com
Other: bailey _at_ newman _dot_ upenn _dot_ edu

___
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] [Announce] Catalyst-Runtime 5.7099_01 - Developer Release

2008-06-26 Thread Charles Bailey
On Wed, Jun 25, 2008 at 4:57 PM, Marcus Ramberg <[EMAIL PROTECTED]> wrote:
>
> The feature to note here is 'go', which works like an internal redispatch to
> another action, while retaining the stash intact. Being able to do this
> means that in practice you don't ever need to set the template name in
> stash, but can depend on using go when you want to render the template of
> the other action, rather than the one you dispatched to.

Would it make sense to include a function analogous to forward() (say,
"visit()") in the same way that go() is analogous to detach()?  Seems
like it'd be a nice way to "wrap" an action that uses auto() or end()
in its controller to handle tasks common to several actions there.

I've found myself in similar circumstances doing something like

sub test_wrapper : Local {
my($self,$c) = @_;

# Setup as needed
$c->forward($target, 'auto');
$c->forward($target, 'foo');
$c->forward($target, 'end');
$c->stash->{whatever} = $c->res->body;
$c->stash->{template} = 'test/foowrapper.tt';
$c->res->content_type('');  # Clear so View::TT will set it
}

and it'd be nice to have the first three calls handled by the
dispatcher, rather than having to know about $target's structure.

-- 
Regards,
Charles Bailey
Lists: bailey _dot_ charles _at_ gmail _dot_ com
Other: bailey _at_ newman _dot_ upenn _dot_ edu

___
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/