[Catalyst] Templates in the database

apv apv at sedition.com
Thu Jan 18 23:37:36 GMT 2007


On Jan 18, 2007, at 3:22 PM, Bill Moseley wrote:
> I do maintain a history of these pages, and I have a crude "diff" view
> using Algorithm::Diff.  I have a table that holds the history of the
> content and use triggers to write to it on update.
>
> Is this how you are (or would) do this?

I am doing post history/revision with a similar, but crude, interface  
to what wikimedia uses.
Doing it with Algorithm::Diff and Algorithm::Diff::Apply (and YAML).  
I'm not confident my code is clean or something to emulate but I put  
part of it in the foot. Not including the TT stuff but I'll send it  
to you if you're curious.

The only thing I'd also suggest (which I'm not actually doing yet) is  
doing a compilation of the edited template before saving it. Only  
save it and catch the revision if it compiles (i.e. the editor  
working on it hasn't broken it). There would be no reason to allow  
broken templates into your history. It would just gum up the revision  
process.


-Ashley
-- 

# IN the table's schema
sub store_column {
     my ( $self, $name, $value ) = @_;
     $value =~ s/[^[:print:]\s]//g; # not sure this is a good idea  
321 222
     if ( $name eq "body"
          and $self->in_storage
          and $self->body )
     {
         my @original = split /\n/, $self->body;
         my @new = split /\n/, $value;
         chomp( @original, @new );
         my @diff = Algorithm::Diff::diff( \@new, \@original );
         $self->add_to_revisions({ diff => YAML::freeze(\@diff) })
             if @diff;
     }
     $self->next::method($name, $value);
}


# IN the table's editor/admin
sub rev : Chained("/article/article") : Args(1) {
     my ( $self, $c, $rev ) = @_;
     my $article = $c->stash->{article};

     my @revisions = $article->revisions;
     @revisions >= $rev ||
         die "RC_404: no such revision to article " . $article->id;

     my ( @reverted, @tmp );
     my @body = split /\n/, $article->body;
     @tmp = @body;

     for ( my $i = @revisions; $i >= $rev; )
     {
         $i--;
         my $diff = YAML::thaw($revisions[$i]->diff);
         @tmp = @reverted if @reverted;
         @reverted = Algorithm::Diff::Apply::apply_diff(\@tmp, $diff);
     }
     chomp(@reverted);
     chomp(@body);
     s/$CRLF|$LF|$CR// for @reverted, @body;
     my @sdiff = Algorithm::Diff::sdiff( \@reverted, \@body );

     my %english = (
                    '+' => 'added',
                    '-' => 'removed', # removed-ish
                    'u' => 'unmodified',
                    'c' => 'changed',
                    );

     $_->[0] = $english{$_->[0]} for @sdiff;

     $c->stash(
               template => 'admin/article/edit.tt',
               nosidebar => 1,
               revision => $rev,
               sdiff => \@sdiff,
               body => join("\n", @reverted)
               );
}






More information about the Catalyst mailing list