tagging: Allow using titles in for related stories.
[matthijs/upstream/blosxom-plugins.git] / xtaran / tagging
index 6b134264b7a0aa43c30334525a51bef26f708a27..0e408a16ff11fafea18606d769fcd9048de904e4 100644 (file)
@@ -145,15 +145,15 @@ use CGI;
 ###
 
 # Where to link story tags (URLs defined below)
-my $link_tag = 'blosxom';
+our $link_tag = 'blosxom' unless defined $link_tag;
 
 # Where to link tags in the tag cloud (URLs defined below)
-my $link_cloud = 'blosxom';
+our $link_cloud = 'blosxom' unless defined $link_cloud;
 
 # Where to link related tags (URLs defined below)
-my $link_rtag = 'blosxom';
+our $link_rtag = 'blosxom' unless defined $link_rtag;
 
-my %base_url = (
+our %base_url = (
                blosxom => "$blosxom::url?-tags=",
                blosxom_tags => "$blosxom::url/tags/",
                technorati => "http://www.technorati.com/tags/",
@@ -180,70 +180,72 @@ my %base_url = (
                wikipedia_nn => "http://nn.wikipedia.org/wiki/",
                wikipedia_lb => "http://lb.wikipedia.org/wiki/",
                wikipedia_simple => "http://simple.wikipedia.org/wiki/",
-               );
+               ) unless defined %base_url;
 
 # Regular expressions
 
-my $tag_re = qr/Tags:\s*/i;
-my $split_re = qr/\s*,\s*/;
+our $tag_re = qr/Tags:\s*/i unless defined $tag_re;
+our $split_re = qr/\s*,\s*/ unless defined $split_re;
 
 # Texts for tags
 
-my $tag_prefix = 'Tagged as: ';
-my $tag_suffix = ''; #' » ';
-my $global_tag_prefix = '<p style="text-align: justify;">'; # '<p>Available tags: ';
-my $global_tag_suffix = '</p>';
-my $current_filter_prefix = '<p><em>Current filter:</em> &raquo;';
-my $current_filter_suffix = '&laquo; (Click tag to exclude it or click a conjunction to switch them.)</p>';
+our $tag_prefix = 'Tagged as: ' unless defined $tag_prefix;
+our $tag_suffix = '' unless defined $tag_suffix; #' &raquo; '
+our $global_tag_prefix = '<p style="text-align: justify;">' unless defined $global_tag_prefix; # '<p>Available tags: '
+our $global_tag_suffix = '</p>' unless defined $global_tag_suffix;
+our $current_filter_prefix = '<p><em>Current filter:</em> &raquo;' unless defined $current_filter_prefix;
+our $current_filter_suffix = '&laquo; (Click tag to exclude it or click a conjunction to switch them.)</p>' unless defined $current_filter_suffix;
 
 # Displaying the tag cloud 
 
-my $min_tag_no = 2;
-my $show_tag_no = 0;
-my $show_tag_no_by_size = 1;
-my $show_tag_no_by_color = 1;
-my $max_size = 250;
-my $min_size = 75;
+our $min_tag_no = 2 unless defined $min_tag_no;
+our $show_tag_no = 0 unless defined $show_tag_no;
+our $show_tag_no_by_size = 1 unless defined $show_tag_no_by_size;
+our $show_tag_no_by_color = 1 unless defined $show_tag_no_by_color;
+our $max_size = 250 unless defined $max_size;
+our $min_size = 75 unless defined $min_size;
 
-my @tag_cloud_blacklist = ('Now Playing', 'Other Blogs', 'Screenshot');
+our @tag_cloud_blacklist = ('Now Playing', 'Other Blogs', 'Screenshot') unless defined @tag_cloud_blacklist;
 
-my $start_color = 'ff9900';
-my $end_color = '991100';
-#my $start_color = '0000ff';
-#my $end_color = 'ff0000';
-#my $start_color = 'ff9900';
-#my $end_color = '0000ff';
+our $start_color = 'ff9900' unless defined $start_color;
+our $end_color = '991100' unless defined $end_color;
+#our $start_color = '0000ff' unless defined $start_color;
+#our $end_color = 'ff0000' unless defined $end_color;
+#our $start_color = 'ff9900' unless defined $start_color;
+#our $end_color = '0000ff' unless defined $end_color;
 
 # Texts for related stories
 
-my @related_stories_tag_blacklist = ('Now Playing', 'Other Blogs', 'Screenshot');
+our @related_stories_tag_blacklist = ('Now Playing', 'Other Blogs', 'Screenshot') unless defined @related_stories_tag_blacklist;
 
-my $min_story_relations = 2;
-my $max_related_stories = 5;
-my $show_shared_tags = 0;
-my $show_number_of_shared_tags = 1;
+our $min_story_relations = 2 unless defined $min_story_relations;
+our $max_related_stories = 5 unless defined $max_related_stories;
+our $show_shared_tags = 0 unless defined $show_shared_tags;
+our $show_number_of_shared_tags = 1 unless defined $show_number_of_shared_tags;
 
-my $related_stories_prefix = '<div class="blosxomstoryfoot" align="left"><h4 class="related_stories">Related stories</h4><ul class="related_stories">'."\n";
-my $related_stories_suffix = "\n</ul></div>\n";
-my $related_story_join     = "\n";
-my $related_story_prefix   = '<li class="related_stories">';
-my $related_story_suffix   = '</li>';
-my $related_story_class    = 'related_stories';
+our $related_stories_prefix = '<div class="blosxomstoryfoot" align="left"><h4 class="related_stories">Related stories</h4><ul class="related_stories">'."\n" unless defined $related_stories_prefix;
+our $related_stories_suffix = "\n</ul></div>\n" unless defined $related_stories_suffix;
+our $related_story_join     = "\n" unless defined $related_story_join;
+our $related_story_prefix   = '<li class="related_stories">' unless defined $related_story_prefix;
+our $related_story_suffix   = '</li>' unless defined $related_story_suffix;
+our $related_story_class    = 'related_stories' unless defined $related_story_class;
+# Use the title of the post for the link instead of the filename
+our $related_story_title    = 0 unless defined $related_story_title;
 
-my $shared_tags_text = 'shared tags';
+our $shared_tags_text = 'shared tags' unless defined $shared_tags_text;
 
 # Related Tags
 
-my $min_tag_relations = 2;
-my $max_related_tags = 5; # 0 to disable;
-my $show_tag_shares = 0;
+our $min_tag_relations = 2 unless defined $min_tag_relations;
+our $max_related_tags = 5 unless defined $max_related_tags; # 0 to disable
+our $show_tag_shares = 0 unless defined $show_tag_shares;
 
-my @related_tags_tag_blacklist = ('Now Playing', 'Other Blogs', 'Screenshot');
+our @related_tags_tag_blacklist = ('Now Playing', 'Other Blogs', 'Screenshot') unless defined @related_tags_tag_blacklist;
 
-my $related_tags_prefix = '<p class="related_tags"><em>Related tags:</em> ';
-my $related_tags_suffix = "\n</p>\n";
-my $related_tag_join     = ", ";
-my $related_tag_class    = 'related_tags';
+our $related_tags_prefix = '<p class="related_tags"><em>Related tags:</em> ' unless defined $related_tags_prefix;
+our $related_tags_suffix = "\n</p>\n" unless defined $related_tags_suffix;
+our $related_tag_join     = ", " unless defined $related_tag_join;
+our $related_tag_class    = 'related_tags' unless defined $related_tag_class;
 
 ###
 ### Init (You can use these variables in templates prefixed with "$tagging::".)
@@ -257,6 +259,7 @@ $related_stories = '';
 $related_tags = '';
 
 %tags = ();
+%titles = ();
 %related_tags = ();
 
 sub start { 
@@ -290,9 +293,7 @@ sub story {
     $tag_list = '';
     my %other_stories = ();
     foreach my $tag (sort { lc($a) cmp lc($b) } keys %localtags) {
-       my $l_tag = &url_escape($tag);
-       $tag_list .= 
-           qq! <a href="$base_url{$link_tag}$l_tag" rel="tag">$tag</a>,!;
+       $tag_list .= " " . make_tag_link($link_tag, $tag, (rel => "tag")) . ",";
 
 #      $tag_list .= qq! <a href="$base_url{blosxom}$tag&-technorati-hack=/$tag" rel="tag" title="Look for tag $tag in this blog"!.($invisible_plugin_tags ? qq! style="display:none;"! : '').qq!>$tag</a>! if $add_plugin_tags;
 
@@ -324,15 +325,21 @@ sub story {
        $opath =~ s!\Q$blosxom::datadir\E!$blosxom::url!;
        $opath =~ s!\Q$blosxom::file_extension\E$!$blosxom::default_flavour!;
 
-       my $title = $other;
-       $title =~ s!^.*/([^/]+)\.$blosxom::file_extension$!$1!;
+       my $title;
+       if ($related_story_title) {
+           $title = $titles{$other};
+       } else {
+           $title = $other;
+           $title =~ s!^.*/([^/]+)\.$blosxom::file_extension$!$1!;
+       }
 
        my $shared_tags_list = join(', ', @{$other_stories{$other}});
        my $shared_tags_number = scalar(@{$other_stories{$other}});
 
-       my $attr_title = "$shared_tags_number $shared_tags_text: $shared_tags_list";
-
-       $related_stories .= qq($related_story_prefix<a href="$opath" class="$related_story_class" title="$attr_title">$title</a>);
+       my $attr_title = blosxom::blosxom_html_escape("$shared_tags_number $shared_tags_text: $shared_tags_list");
+       my $attr_href = blosxom::blosxom_html_escape($opath);
+       my $html_title = blosxom::blosxom_html_escape($title);
+       $related_stories .= qq($related_story_prefix<a href="$attr_href" class="$related_story_class" title="$attr_title">$html_title</a>);
 
        $related_stories .= ' (' 
            if $show_shared_tags || $show_number_of_shared_tags;
@@ -340,7 +347,7 @@ sub story {
            if $show_number_of_shared_tags;
        $related_stories .= $shared_tags_text
            if $show_shared_tags || $show_number_of_shared_tags;
-       $related_stories .= ": $shared_tags_list"
+       $related_stories .= blosxom::blosxom_html_escape(": $shared_tags_list")
            if $show_shared_tags;
        $related_stories .= ')'
            if $show_shared_tags || $show_number_of_shared_tags;
@@ -370,6 +377,10 @@ sub filter {
        my $tags_found = 0;
        my $empty_line_found = 0;
        while ($_ = <FILE>) {
+           # Take the title from the first line
+           if (not defined $titles{$key}) {
+               $titles{$key} = $_;
+           }
            last if /^\s*$/;
            if (m!^$tag_re(.+?)$!) {
                my @localtags = split($split_re, $1);
@@ -411,8 +422,6 @@ sub filter {
     }
 
     my $diff = $max - $min;
-    my $conj = ($filter_conj eq 'and' ? '&-conj=and' : '');
-    my $l_filter_tags = &url_escape($filter_tags);
 
     foreach my $tag (sort { lc($a) cmp lc($b) } keys %tags) {
        next if grep { $_ eq $tag } @tag_cloud_blacklist;
@@ -429,15 +438,8 @@ sub filter {
        $style .= qq!font-size: $tag_percent%;! if $show_tag_no_by_size && $diff;
        $style .= qq!color: #$color;! if $show_tag_no_by_color && $diff;
 
-       my $l_tag = &url_escape($tag);
-       $global_tag_list .= 
-           qq| <a href="$base_url{$link_cloud}|.
-            ((($link_cloud eq 'blosxom') and 
-              ($filter_tags !~ /(^|,)\Q$tag\E($|,)/) and
-              $filter_tags) ?
-             "$l_filter_tags," : '').
-            qq|$l_tag$conj" title="$title" style="$style">$tag</a>|.
-           qq|$tag_no_display,\n|;
+       $global_tag_list .= make_tag_link($link_cloud, $tag, (title => $title, style => $style)).
+                           qq|$tag_no_display,\n|;
     }
 
     $global_tag_list =~ s/,$//;
@@ -454,7 +456,7 @@ sub filter {
       FILES:
        foreach my $file (@$files) {
            # If all tags should match
-           if ($conj) {
+           if ($filter_conj eq 'and') {
                foreach my $ctag (@tags) {
                    if (!grep { $_ eq $file } @{$tags{$ctag}}) {
                        next FILES;
@@ -468,25 +470,18 @@ sub filter {
 
     %$files_ref = %localfiles;
 
-    $current_filter_short = join($conj ? ' + ' : ' | ',
-                                map { s/\&/\&amp;/g; $_; } 
-                                sort { lc($a) cmp lc($b) } 
-                                @tags);
+    $current_filter_short = blosxom::blosxom_html_escape(
+                              join($filter_conj eq 'and' ? ' + ' : ' | ',
+                                  sort { lc($a) cmp lc($b) } @tags
+                           ));
 
-    $conj = ($conj ? 
+    my $l_filter_tags = &url_escape($filter_tags);
+    $conj = ($filter_conj eq 'and' ? 
             qq! <em><a href="$base_url{blosxom}$l_filter_tags">and</a></em> ! : 
             qq! <em><a href="$base_url{blosxom}$l_filter_tags&amp;-conj=and">or</a></em> !);
     $current_filter = ($current_filter_prefix.
                       join($conj,
-                           map {
-                               my $tags = $filter_tags;
-                               $tags =~ s/\Q$_,\E// || $tags =~ s/\Q,$_\E// || $tags =~ s/\Q$_\E//;
-
-                               s/\&/\&amp;/g; 
-
-                               my $l_tags = &url_escape($tags);
-                               qq!<a href="$base_url{blosxom}$l_tags">$_</a>!;
-                           } 
+                           map { make_tag_link('blosxom', $_); } 
                            sort { lc($a) cmp lc($b) } 
                            @tags).
                       $current_filter_suffix);
@@ -500,12 +495,11 @@ sub filter {
                          keys %related_tags) {
            next if ((grep { $_ eq $rtag } @related_tags_tag_blacklist) or
                     $related_tags{$rtag} < $min_tag_relations);
-           my $l_rtag = &url_escape($rtag);
            my $rel_no = $show_tag_shares ? " ($related_tags{$rtag})" : '';
-           $related_tags .= 
-               qq!<a href="$base_url{$link_rtag}$l_rtag" rel="tag" class="$related_tag_class" title="Coincided $related_tags{$rtag} times">$rtag</a>$rel_no$related_tag_join!;
+           $related_tags .= make_tag_link($link_rtag, $rtag, (rel => "tag", class => $related_tag_class, title => "Coincided $related_tags{$rtag} times")).
+                            "$rel_no$related_tag_join";
            last if $i++ >= $max_related_tags;
-           }
+       }
        $related_tags =~ s/\Q$related_tag_join\E$//;
 
        #use Data::Dumper;
@@ -521,6 +515,47 @@ sub filter {
     1;
 }
 
+# Create the url for a given tag. Depending on the tag and link type given,
+# this adds to, removes or replaces the current tag list. The link type given
+# is one of the keys of %base_url
+sub make_tag_link {
+    my ($link, $tag, %attrs) = @_;
+    my $filter_tags = CGI::param('-tags');
+    my $conj = (CGI::param('-conj') eq 'and' ? '&-conj=and' : '');
+    # If we're linking to ourselves, the currently selected tag list is not
+    # empty, and this tag is not in there yet, prefix the link with the
+    # current filter list.
+    my $tags;
+    if (($link_cloud eq 'blosxom') and $filter_tags) {
+       if ($filter_tags =~ /(^|,)\Q$tag\E($|,)/) {
+           # The tag is already in there, remove it
+           $tags = $filter_tags;
+           $tags =~ s/\Q,$tag,\E/,/ || $tags =~ s/(^|,)\Q$tag\E($|,)//;
+       } else {
+           # The tag is not in there, add it
+           $tags = "$filter_tags,$tag";
+       }
+       $tags = &url_escape($tags);
+       $tags .= $conj;
+    } else {
+       # We're linking externally, or don't have a filter yet. Just use the
+       # selected tag as the filter
+       $tags = &url_escape($tag);
+    }
+
+    # Set the href attribute
+    $attrs{href} = "$base_url{$link}$tags";
+
+    # Generate attribute values
+    my $attrs = join('',
+                map { $val = blosxom::blosxom_html_escape($attrs{$_});
+                     qq! $_="$val"!;
+               } keys %attrs);
+
+    return "<a$attrs>" . blosxom::blosxom_html_escape($tag) . "</a>";
+}
+
+
 sub color_calc {
     my ($tag_no, $min, $max) = @_;
     my $diff = $max - $min;