[MKDoc-commit] Patch from Sam - Headlines Base Document fix.

chris at mkdoc.demon.co.uk chris at mkdoc.demon.co.uk
Tue Aug 2 11:41:59 BST 2005


Log Message:
-----------
Patch from Sam - Headlines Base Document fix.
After applying this patch headline components will store their base
document by document ID, allowing for redirects.  I have also included
an updated update_links.pl script which now updates headlines as well
as link components.

Tags:
----
mkdoc-1-6

Modified Files:
--------------
    mkd/MKDoc/Util:
        LinkParser.pm
    mkd/flo/editor:
        Headlines.pm
    mkd/templates/editor/headlines:
        en.html
    mkd/tools:
        update_links.pl

-------------- next part --------------
Index: LinkParser.pm
===================================================================
RCS file: /var/spool/cvs/mkd/MKDoc/Util/Attic/LinkParser.pm,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -LMKDoc/Util/LinkParser.pm -LMKDoc/Util/LinkParser.pm -u -r1.1.2.4 -r1.1.2.5
--- MKDoc/Util/LinkParser.pm
+++ MKDoc/Util/LinkParser.pm
@@ -96,6 +96,10 @@
 Returns the URI object for the last link parsed.  See L<URI> for more
 details.
 
+=head2 as_path
+
+Produce a string containing just the path for an internal link.
+
 =head2 as_string
 
 Produce a string containing a canonical version of the link.
@@ -216,6 +220,17 @@
     return $uri->as_string;
 }
 
+sub as_path {
+    my $self = shift;
+    # setup path based on document_id if we've got one
+    if ($self->{document_id}) {
+        my $dbh    = lib::sql::DBH->get();
+        my ($path) = $dbh->selectrow_array('SELECT Full_Path FROM Document WHERE ID = ?', undef, $self->{document_id});
+        return $path;
+    }
+    return '';
+}
+
 sub operation { shift->{operation} }
 
 sub is_internal {
Index: Headlines.pm
===================================================================
RCS file: /var/spool/cvs/mkd/flo/editor/Headlines.pm,v
retrieving revision 1.4.2.32
retrieving revision 1.4.2.33
diff -Lflo/editor/Headlines.pm -Lflo/editor/Headlines.pm -u -r1.4.2.32 -r1.4.2.33
--- flo/editor/Headlines.pm
+++ flo/editor/Headlines.pm
@@ -31,6 +31,7 @@
 use MKDoc::CGI;
 use MKDoc::Util::Text2HTML;
 use flo::RedirectManager;
+use MKDoc::Util::LinkParser;
 use strict;
 use utf8;
 
@@ -42,6 +43,8 @@
 	     flo::editor::Mixin::compute_name
 	     flo::editor::Mixin::normalize_name/;
 
+# keep a global link parser around for use with from_path
+my $link_parser = MKDoc::Util::LinkParser->new();
 
 sub preferred_extension { 'html' };
 
@@ -52,12 +55,17 @@
     my $args = $self->cgi_args_multi();
 
     $self->{title}         = $args->{title}           || '';
-    $self->{from_path}     = $args->{'from_path'}     || '';
     $self->{max_headlines} = $args->{'max_headlines'} || '';
     $self->{leaf_only}     = $args->{'leaf_only'}     || '';
     $self->{mode}          = $args->{'mode'}          || 'newest';
     $self->{audience_on}   = $args->{audience_on}     || 0;
 
+    if ($args->{from_path}) {
+        $self->parse_path($args->{from_path});
+    } else {
+        $self->{from_path} = '';
+    }
+
     # set audiences, wrapping a single value in an array ref
     $self->{audiences} = [];
     $self->{audiences} = 
@@ -65,6 +73,39 @@
         if $args->{audiences};
 }
 
+# lookup path using the link-parser, resulting in a document ID
+sub parse_path {
+    my ($self, $url) = @_;
+    $link_parser->parse($url);
+
+    if ($link_parser->is_internal and $link_parser->is_valid) {
+        # store just the document_id, the rest isn't useful
+        $self->{from_document_id} = $link_parser->document_id;
+
+        # store the canonical rendered form in from_path
+        $self->{from_path} = $self->render_from_path;
+    } else {
+        # store the bad path, validate_path will pick it up on save
+        $self->{from_path} = $url;
+    }
+}
+
+# template rendering for the path
+sub render_from_path {
+    my $self = shift;
+    if ($self->{from_document_id}) {
+        # lookup the path for this document
+        my $dbh    = lib::sql::DBH->get;
+        my ($path) = $dbh->selectrow_array('SELECT Full_Path 
+                                            FROM Document WHERE ID = ?',
+                                           undef, $self->{from_document_id});
+        return $path;
+    } else {
+        return $self->{from_path} || '';
+    }
+}
+
+
 # returns an array of audience objects (flo::Record::Audience)
 sub audiences { [ flo::Record::Audience->load( All => 1 ) ] }
 
@@ -167,8 +208,19 @@
 }
 
 
-sub validate_from_path
-{
+sub validate_from_path {
+    my $self = shift;
+    unless ($self->{from_path}) {
+	new MKDoc::Ouch 'component/headlines/from_path_empty';
+	return 0;
+    }
+
+    $link_parser->parse($self->{from_path});
+    unless ($link_parser->is_internal and $link_parser->is_valid) {
+        new MKDoc::Ouch 'component/headlines/from_path_invalid';
+        return 0;
+    }
+
     return 1;
 }
 
Index: en.html
===================================================================
RCS file: /var/spool/cvs/mkd/templates/editor/headlines/Attic/en.html,v
retrieving revision 1.1.2.18
retrieving revision 1.1.2.19
diff -Ltemplates/editor/headlines/en.html -Ltemplates/editor/headlines/en.html -u -r1.1.2.18 -r1.1.2.19
--- templates/editor/headlines/en.html
+++ templates/editor/headlines/en.html
@@ -178,7 +178,7 @@
         size="20"
         dir="ltr"
         title="Enter the document path from which the headlines should be generated."
-        petal:attributes="name name_from_path; id name_from_path; value self/from_path"
+        petal:attributes="name name_from_path; id name_from_path; value self/render_from_path"
       />
       <br />
     </p>
Index: update_links.pl
===================================================================
RCS file: /var/spool/cvs/mkd/tools/Attic/update_links.pl,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -Ltools/update_links.pl -Ltools/update_links.pl -u -r1.1.2.1 -r1.1.2.2
--- tools/update_links.pl
+++ tools/update_links.pl
@@ -1,3 +1,5 @@
+#!/usr/bin/perl
+
 # ------------------------------------------------------------------
 # update_links.pl
 # ------------------------------------------------------------------
@@ -31,7 +33,6 @@
 # It would be a good idea to make a backup of your database before
 # running this script as it has not been extensively tested.
  
-#!/usr/bin/perl
 use strict;
 use warnings;
 use MKDoc;
@@ -60,9 +61,61 @@
     $editor->parse_xml($doc->{Body}, $document_id);
 
     my $dirty = 0;
+    my @components = $editor->access();
+    $dirty += process_links($document_id, \@components);
+    $dirty += process_headlines($document_id, \@components);
+
+    # if changes were made they need to get updated in the DB.  (It's
+    # hard to believe there isn't a better way to do this, but I'm
+    # pretty sure there isn't.)
+    if ($dirty) {
+        print "*** Updating Document $document_id with $dirty new links.\n";
+        $doc->{Body} = $editor->generate_xml();
+        $doc->save();
+    }
+}
+
+# look at all headline components, evaluating and replacing from_path
+sub process_headlines {
+    my ($document_id, $components) = @_;
+    my $dirty = 0;
+
+    # look at each headline component
+    my @links = grep { $_->isa('flo::editor::Headlines') } @$components;
+    foreach my $link (@links) {
+        # ignore already processed internal links
+        next if $link->{from_document_id};
+
+        # evaluate plain links, ignoring broken ones
+        my $url = $link->{from_path};
+        next unless $url;
+
+        $parser->parse($url);
+
+        # external links stay as-is
+        if (not $parser->is_internal or not $parser->is_valid) {
+            print "!!! Invalid Headline Link ($document_id): $url\n";
+            next;
+        }          
+
+        # update valid internal links
+        $link->{from_document_id} = $parser->document_id;
+        $link->{from_path}        = $parser->as_path;
+        $dirty++;
+        print "+++ Valid Headline Link ($document_id): $url\n"
+    }
+    
+
+    return $dirty;
+}
+
+# look at all links, evaluating and replacing valid internal links
+sub process_links {
+    my ($document_id, $components) = @_;
+    my $dirty = 0;
 
     # look at each link
-    my @links = grep { $_->isa('flo::editor::Link') } $editor->access();
+    my @links = grep { $_->isa('flo::editor::Link') } @$components;
     foreach my $link (@links) {
         # ignore already processed internal links
         next if $link->{internal_link};
@@ -92,13 +145,5 @@
         print "+++ Valid Internal Link ($document_id): $url\n"
     }
 
-    # if changes were made they need to get updated in the DB.  (It's
-    # hard to believe there isn't a better way to do this, but I'm
-    # pretty sure there isn't.)
-    if ($dirty) {
-        print "*** Updating Document $document_id with $dirty new links.\n";
-        $doc->{Body} = $editor->generate_xml();
-        $doc->save();
-    }
+    return $dirty;
 }
-


More information about the MKDoc-commit mailing list