root/all-keywords/tags/0.11/all-keywords.pl

Revision 20, 9.2 kB (checked in by ogawa, 4 years ago)

Add case_sensitive option

Line 
1# A plugin for adding keywords-handling tags
2#
3# Release 0.11 (Mar 20, 2005)
4#
5# This software is provided as-is. You may use it for commercial or
6# personal use. If you distribute it, please keep this notice intact.
7#
8# Copyright (c) 2005 Hirotaka Ogawa
9
10use strict;
11use MT::Template::Context;
12
13eval("use Storable;");
14if (!$@ && MT->can('add_plugin')) {
15    require MT::Plugin;
16    my $plugin = new MT::Plugin();
17    $plugin->name("AllKeywords Plugin 0.11");
18    $plugin->description("Add MTAllKeywords tags for listing blog-wide keywords and entry keywords");
19    $plugin->doc_link("http://as-is.net/hacks/2005/03/allkeywords_plugin.html");
20    MT->add_plugin($plugin);
21}
22
23MT::Template::Context->add_container_tag('AllKeywords' => \&all_keywords);
24MT::Template::Context->add_container_tag('EntryAllKeywords' => \&entry_all_keywords);
25MT::Template::Context->add_tag('AllKeyword' => \&all_keyword);
26MT::Template::Context->add_tag('AllKeywordCount' => \&all_keyword_count);
27MT::Template::Context->add_tag('AllKeywordsTotal' => \&all_keywords_total);
28MT::Template::Context->add_tag('AllKeywordsTotalSum' => \&all_keywords_total_sum);
29MT::Template::Context->add_container_tag('EntriesWithKeywords' => \&entries_with_keywords);
30MT::Template::Context->add_container_tag('MostRelatedEntries' => \&most_related_entries);
31
32sub all_keywords {
33    my ($ctx, $args, $cond) = @_;
34
35    # sort_by option (keyword/count, default = keyword)
36    my $sort_by = $args->{sort_by} || 'keyword';
37    # sort_order option (ascend/descend, default = ascend)
38    my $sort_order = $args->{sort_order} || 'ascend';
39    # lastn option (default = 0, no cutoff)
40    my $lastn = $args->{lastn} || 0;
41    # delimiter option (default = space characters)
42    my $delimiter = $args->{delimiter} || '';
43    # case_sensitive option (0/1, default = 1)
44    my $case_sensitive = $args->{case_sensitive} || 1;
45
46    my $blog_id = $ctx->stash('blog_id');
47    require MT::Entry;
48    my $iter = MT::Entry->load_iter({ blog_id => $blog_id,
49                                      status => MT::Entry::RELEASE() });
50    my %all_keywords = ();
51    while (my $e = $iter->()) {
52        next unless $e->keywords;
53        my $e_keywords = $case_sensitive ? $e->keywords : lc $e->keywords;
54        my @keywords = $delimiter ?
55            split($delimiter, $e_keywords) : split(/\s+/, $e_keywords);
56        foreach my $keyword (@keywords) {
57            if (exists($all_keywords{$keyword})) {
58                $all_keywords{$keyword}++;
59            } else {
60                $all_keywords{$keyword} = 1;
61            }
62        }
63    }
64    my $res = '';
65    my $builder = $ctx->stash('builder');
66    my $tokens = $ctx->stash('tokens');
67
68    my @list;
69    if ($sort_by eq 'keyword') {
70        @list = $sort_order eq 'ascend' ?
71            sort { $a cmp $b } keys %all_keywords :
72            sort { $b cmp $a } keys %all_keywords;
73    } else {
74        @list = $sort_order eq 'ascend' ?
75            sort { $all_keywords{$a} <=> $all_keywords{$b} } keys %all_keywords :
76            sort { $all_keywords{$b} <=> $all_keywords{$a} } keys %all_keywords;
77    }
78
79    $ctx->stash('all_keywords_total', scalar(@list));
80
81    my $total_sum = 0;
82    foreach (@list) {
83        $total_sum += $all_keywords{$_};
84    }
85    $ctx->stash('all_keywords_total_sum', $total_sum);
86
87    my $i = 0;
88    foreach (@list) {
89        last if $lastn && $i >= $lastn;
90        $ctx->stash('all_keyword', $case_sensitive ? $_ : ucfirst $_);
91        $ctx->stash('all_keyword_count', $all_keywords{$_});
92        defined(my $out = $builder->build($ctx, $tokens))
93            or return $ctx->error($ctx->errstr);
94        $res .= $out;
95        $i++;
96    }
97    $res;
98}
99
100sub entry_all_keywords {
101    my ($ctx, $args, $cond) = @_;
102    my $e = $ctx->stash('entry')
103        or return $ctx->_no_entry_error('MTEntryAllKeywords');
104    return '' unless $e->keywords;
105
106    # delimiter option (default = space characters)
107    my $delimiter = $args->{delimiter} || '';
108    # case_sensitive option (0/1, default = 1)
109    my $case_sensitive = $args->{case_sensitive} || 1;
110
111    my $e_keywords = $case_sensitive ? $e->keywords : lc $e->keywords;
112    my @keywords = $delimiter ?
113        split($delimiter, $e_keywords) : split(/\s+/, $e_keywords);
114    my $res = '';
115    my $builder = $ctx->stash('builder');
116    my $tokens = $ctx->stash('tokens');
117    my $total = scalar(@keywords);
118    $ctx->stash('all_keywords_total', $total);
119    $ctx->stash('all_keywords_total_sum', $total);
120    foreach (@keywords) {
121        $ctx->stash('all_keyword', $case_sensitive ? $_ : ucfirst $_);
122        $ctx->stash('all_keyword_count', 1);
123        defined(my $out = $builder->build($ctx, $tokens))
124            or return $ctx->error($ctx->errstr);
125        $res .= $out;
126    }
127    $res;
128}
129
130sub all_keyword {
131    $_[0]->stash('all_keyword');
132}
133
134sub all_keyword_count {
135    $_[0]->stash('all_keyword_count');
136}
137
138sub all_keywords_total {
139    $_[0]->stash('all_keywords_total');
140}
141
142sub all_keywords_total_sum {
143    $_[0]->stash('all_keywords_total_sum');
144}
145
146sub entries_with_keywords {
147    my ($ctx, $args, $cond) = @_;
148
149    # keywords option (must be specified)
150    my $keywords = $args->{keywords} or return '';
151    # delimiter option (default = space characters)
152    my $delimiter = $args->{delimiter} || '';
153    # case_sensitive option (0/1, default = 0)
154    my $case_sensitive = $args->{case_sensitive} || 0;
155    # sort_by option (title/status/created_on/modified_on/author_id/excerpt, default = created_on)
156    my $sort_by = $args->{sort_by} || 'created_on';
157    # sort_order option (ascend/descend, default = ascend)
158    my $sort_order = $args->{sort_order} || 'descend';
159    # lastn option (default = 0, no cutoff)
160    my $lastn = $args->{lastn} || 0;
161
162    my $blog_id = $ctx->stash('blog_id');
163    require MT::Entry;
164    my $iter = MT::Entry->load_iter({ blog_id => $blog_id,
165                                      status => MT::Entry::RELEASE() },
166                                    { sort => $sort_by,
167                                      direction => $sort_order });
168    my @entries;
169    $keywords = lc $keywords unless $case_sensitive;
170    my @patterns = $delimiter ?
171        split($delimiter, $keywords) : split(/\s+/, $keywords);
172    my $i = 0;
173    while (my $e = $iter->()) {
174        last if $lastn && $i >= $lastn;
175        next unless $e->keywords;
176        my $e_keywords = $case_sensitive ? $e->keywords : lc $e->keywords;
177        my @keywords = $delimiter ?
178            split($delimiter, $e_keywords) : split(/\s+/, $e_keywords);
179        my $check = 1;
180        foreach my $pattern (@patterns) {
181            unless (scalar grep { $_ eq $pattern } @keywords) {
182                $check = 0;
183                last;
184            }
185        }
186        if ($check) {
187            push @entries, $e;
188            $i++;
189        }
190    }
191    return '' unless @entries;
192
193    my $res = '';
194    my $tokens = $ctx->stash('tokens');
195    my $builder = $ctx->stash('builder');
196    $i = 0;
197    for my $e (@entries) {
198        local $ctx->{__stash}{entry} = $e;
199        local $ctx->{current_timestamp} = $e->created_on;
200        local $ctx->{modification_timestamp} = $e->modified_on;
201        my $out = $builder->build($ctx, $tokens, {
202            %$cond,
203            EntryIfExtended => $e->text_more ? 1 : 0,
204            EntryIfAllowComments => $e->allow_comments,
205            EntryIfCommentsOpen => $e->allow_comments && $e->allow_comments eq '1',
206            EntryIfAllowPings => $e->allow_pings,
207            EntriesHeader => !$i,
208            EntriesFooter => !defined $entries[$i+1]
209            });
210        return $ctx->error($ctx->errstr) unless defined $out;
211        $res .= $out;
212        $i++;
213    }
214    $res;
215}
216
217sub most_related_entries {
218    my ($ctx, $args, $cond) = @_;
219    my $entry = $ctx->stash('entry')
220        or return $ctx->_no_entry_error('MTMostRelatedEntries');
221    return '' unless $entry->keywords;
222
223    # delimiter option (default = space characters)
224    my $delimiter = $args->{delimiter} || '';
225    # case_sensitive option (0/1, default = 0)
226    my $case_sensitive = $args->{case_sensitive} || 0;
227    # lastn option (default = 0, no cutoff)
228    my $lastn = $args->{lastn} || 0;
229
230    my $entry_keywords = $case_sensitive ? $entry->keywords : lc $entry->keywords;
231    my @patterns = $delimiter ?
232        split($delimiter, $entry_keywords) : split(/\s+/, $entry_keywords);
233
234    my $blog_id = $ctx->stash('blog_id');
235    require MT::Entry;
236    my $iter = MT::Entry->load_iter({ blog_id => $blog_id,
237                                      status => MT::Entry::RELEASE() },
238                                    { sort => 'created_on',
239                                      direction => 'descend' });
240    my @entries;
241    my %matches = ();
242    while (my $e = $iter->()) {
243        next unless $e->keywords;
244        next if $e->id == $entry->id;
245        my $e_keywords = $case_sensitive ? $e->keywords : lc $e->keywords;
246        my @keywords = $delimiter ?
247            split($delimiter, $e_keywords) : split(/\s+/, $e_keywords);
248        my $count = 0;
249        foreach my $pattern (@patterns) {
250            $count++ if (scalar grep { $_ eq $pattern } @keywords);
251        }
252        if ($count) {
253            push @entries, $e;
254            $matches{ $e->id } = $count;
255        }
256    }
257    return '' unless @entries;
258
259    @entries = sort { $matches{$b->id} <=> $matches{$a->id} } @entries;
260    splice(@entries, $lastn) if $lastn && (scalar @entries > $lastn);
261
262    my $res = '';
263    my $tokens = $ctx->stash('tokens');
264    my $builder = $ctx->stash('builder');
265    my $i = 0;
266    for my $e (@entries) {
267        local $ctx->{__stash}{entry} = $e;
268        local $ctx->{current_timestamp} = $e->created_on;
269        local $ctx->{modification_timestamp} = $e->modified_on;
270        my $out = $builder->build($ctx, $tokens, {
271            %$cond,
272            EntryIfExtended => $e->text_more ? 1 : 0,
273            EntryIfAllowComments => $e->allow_comments,
274            EntryIfCommentsOpen => $e->allow_comments && $e->allow_comments eq '1',
275            EntryIfAllowPings => $e->allow_pings,
276            EntriesHeader => !$i,
277            EntriesFooter => !defined $entries[$i+1]
278            });
279        return $ctx->error($ctx->errstr) unless defined $out;
280        $res .= $out;
281        $i++;
282    }
283    $res;
284}
285
2861;
Note: See TracBrowser for help on using the browser.