<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array"/>
  <modified type="array">
    <modified>
      <diff>@@ -1,19 +1,82 @@
 package ChatterBox;
 use base 'Squatting';
+use Data::Dump 'pp';
+
+our %state;
+sub service {
+  my ($app, $c, @args) = @_;
+  my $cr = $c-&gt;cr;
+
+  # setup session and vars
+  my $sid = $cr-&gt;{session_id};
+  if (defined $sid) {
+    $c-&gt;state = $state{$sid} ||= {};
+  } 
+  if ($c-&gt;state-&gt;{u}) {
+    $c-&gt;v-&gt;{u} = $c-&gt;state-&gt;{u};
+  }
+
+  $app-&gt;SUPER::service($c, @args);
+}
+
+package Object;
+use strict;
+use selfvars;
+
+our $AUTOLOAD;
+
+sub new {
+  bless { %opts } =&gt; $_[0];
+}
+
+sub clone {
+  bless { %$self, %opts } =&gt; ref($self);
+}
+
+sub AUTOLOAD {
+  my $attr = $AUTOLOAD;
+  $attr =~ s/.*://;
+  if (ref($self-&gt;{$attr}) eq 'CODE') {
+    $self-&gt;{$attr}-&gt;($self, @args)
+  } else {
+    if (@args) {
+      $self-&gt;{$attr} = $args[0];
+    } else {
+      $self-&gt;{$attr};
+    }
+  }
+}
+
+sub DESTROY {
+}
 
 package ChatterBox::Controllers;
 use selfvars;
 use base 'Squatting::Q';
 use Squatting ':controllers';
 
+our @messages;
+
 our @C = (
   C(
     Home =&gt; [ '/' ],
     get  =&gt; sub {
+      my $v = $self-&gt;v;
       $self-&gt;render('chatter_box');
     },
   ),
   C(
+    Id =&gt; [ '/id' ],
+    post =&gt; sub {
+      my $input = $self-&gt;input;
+      if ($input-&gt;{name}) {
+        my $user = Object-&gt;new({name =&gt; $input-&gt;{name}});
+        $self-&gt;state-&gt;{u} = $user;
+      }
+      $self-&gt;redirect(R('Home'));
+    }
+  ),
+  C(
     Widget =&gt; [ '/@widget' ],
     get    =&gt; sub {
     },
@@ -23,6 +86,8 @@ our @C = (
     get   =&gt; sub : Q(chatter_box) {
     },
     post  =&gt; sub {
+      my $input = $self-&gt;input;
+      $self-&gt;redirect(R('Home'));
     },
   )
 );
@@ -45,11 +110,97 @@ sub span {
 our @V = (
   V(
     'html',
+    layout =&gt; sub {
+      my ($v, @content) = @args;
+      html(
+        head(
+          title('ChatterBox'),
+          style(x(&quot;body { background: #456; color: #fff; }&quot;)),
+          style(x($self-&gt;{_css})),
+        ),
+        body( @content )
+      )-&gt;as_HTML;
+    },
     _css =&gt; qq|
+      div#chatter_box {
+        padding: 8px;
+        min-height: 240px;
+        max-width: 320px;
+        background: #122;
+        color: #cfc;
+        font-family: &quot;Trebuchet MS&quot;, sans-serif;
+        font-size: 9pt;
+        border: 1px solid #466;
+        -moz-border-radius: 7px;
+      }
+      div#chatter_box dl {
+        margin: 0;
+        padding: 4px;
+        height: 200px;
+        background: #000;
+        color: #fe8;
+        border: 1px solid #888;
+        overflow-x: hidden;
+        overflow-y: auto;
+      }
+      div#chatter_box dt {
+        font-weight: bold;
+      }
+      div#chatter_box dd {
+        margin-top: -1.25em;
+        margin-left: 5em;
+      }
+      div#chatter_box div.input {
+        margin-top: 0.5em;
+      }
+      div#chatter_box div.input input {
+        font-family: &quot;Trebuchet MS&quot;, sans-serif;
+        font-size: 9pt;
+      }
+      div#chatter_box div.input input.text {
+        width: 260px;
+      }
     |,
-    widget =&gt; sub {
+    _widget =&gt; sub {
+      my ($v) = @args;
+      form({ id=&gt; 'chatter_box_form', method =&gt; 'post', action =&gt; R('Event') },
+        div({ id =&gt; 'chatter_box' },
+          dl(
+            map {
+              dt('beppu'),
+              dd(&quot;what's up? &quot;),
+              dt('pip'),
+              dd('the sky. ' x 10),
+            } (1..20)
+          ),
+          ($v-&gt;{u} 
+            ? 
+            (
+              div({ class =&gt; 'input' },
+                input({ type =&gt; 'text',   name =&gt; 'message', class =&gt; 'text' }),
+                input({ type =&gt; 'submit', name =&gt; 'submit',  value =&gt; 'Say' }),
+              ),
+            ) 
+            : ()
+          )
+        ),
+      )
+    },
+    _id =&gt; sub {
+      my ($v) = @args;
+      unless ($v-&gt;{u}) {
+        form({ method =&gt; 'post', action =&gt; R('Id') },
+          h1(&quot;What's your name?&quot;),
+          input({ type =&gt; 'text', name =&gt; 'name' }),
+          input({ type =&gt; 'submit', name =&gt; 'submit', value =&gt; 'Submit' }),
+        );
+      } else {
+        ()
+      }
     },
     chatter_box =&gt; sub {
+      $self-&gt;_id(@args),
+      $self-&gt;_widget(@args);
     },
   )
 );</diff>
      <filename>eg/ChatterBox.pm</filename>
    </modified>
    <modified>
      <diff>@@ -106,6 +106,10 @@ The constructor takes a name and a hash of attributes and coderefs.
 
 This returns the name of the view.
 
+=head3 $v-&gt;headers
+
+This returns a hashref of the outgoing HTTP headers.
+
 =head2 Template Methods
 
 =head3 $v-&gt;$template($v)</diff>
      <filename>lib/Squatting/View.pm</filename>
    </modified>
    <modified>
      <diff>@@ -43,7 +43,7 @@ our @tests = (
 
   sub {
     my $v = v;
-    can_ok($v, qw(name _render));
+    can_ok($v, qw(name headers _render));
   },
 
   sub {</diff>
      <filename>t/02_view.t</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>2bdd72c0844c820e171ecf37b29f1b737eaf9b71</id>
    </parent>
  </parents>
  <author>
    <name>John Beppu</name>
    <email>beppu@work.(none)</email>
  </author>
  <url>http://github.com/beppu/squatting/commit/2c18f62700dbdae4d24bfc88a5dd6229ba50d8de</url>
  <id>2c18f62700dbdae4d24bfc88a5dd6229ba50d8de</id>
  <committed-date>2008-06-09T02:32:28-07:00</committed-date>
  <authored-date>2008-06-09T02:32:28-07:00</authored-date>
  <message>add</message>
  <tree>2a940343b156bf001b43ce2e933fbb41ba360a07</tree>
  <committer>
    <name>John Beppu</name>
    <email>beppu@work.(none)</email>
  </committer>
</commit>
