root/branches/release-39/lib/MT/Template/Context/Search.pm @ 2420

Revision 2420, 7.9 kB (checked in by fumiakiy, 19 months ago)

Typo.

  • Property svn:keywords set to Id Date Author Revision
Line 
1# Movable Type (r) Open Source (C) 2001-2008 Six Apart, Ltd.
2# This program is distributed under the terms of the
3# GNU General Public License, version 2.
4#
5# $Id$
6
7package MT::Template::Context::Search;
8
9use strict;
10use base qw( MT::Template::Context );
11use MT::Util qw( encode_url decode_html );
12
13sub load_core_tags {
14    require MT::Template::Context;
15    return {
16        function => {
17            SearchString => \&_hdlr_search_string,
18            SearchResultCount => \&_hdlr_result_count,
19            MaxResults => \&_hdlr_max_results,
20            SearchIncludeBlogs => \&_hdlr_include_blogs,
21            SearchTemplateID => \&_hdlr_template_id,
22        },
23        block => {
24            SearchResults => \&_hdlr_results,
25            'IfTagSearch?' => sub { MT->instance->mode eq 'tag' },
26            'IfStraightSearch?' => sub { MT->instance->mode eq 'default' },
27            'NoSearchResults?' => sub { $_[0]->stash('count') ? 0 : 1; },
28            'NoSearch?' => sub { ( $_[0]->stash('search_string') &&
29                                   $_[0]->stash('search_string') =~ /\S/ ) ? 0 : 1 },
30            SearchResultsHeader => \&MT::Template::Context::_hdlr_pass_tokens,
31            SearchResultsFooter => \&MT::Template::Context::_hdlr_pass_tokens,
32            BlogResultHeader => \&MT::Template::Context::_hdlr_pass_tokens,
33            BlogResultFooter => \&MT::Template::Context::_hdlr_pass_tokens,
34            'IfMaxResultsCutoff?' => \&MT::Template::Context::_hdlr_pass_tokens,
35        },
36    };
37}
38
39###########################################################################
40
41=head2 SearchResultsHeader
42
43The content of this block tag is rendered when the item in context
44from search results are the first item of the result set.  You can
45use the block to render headings and titles of the result table,
46for example.
47
48This tag is only recognized in SearchResults block.
49
50=for tags search
51
52=cut
53
54###########################################################################
55
56=head2 SearchResultsFooter
57
58The content of this block tag is rendered when the item in context
59from search results are the last item of the result set.  You can
60use the block to render closeing tags of a HTML element, for example.
61
62This tag is only recognized in SearchResults block.
63
64=for tags search
65
66=cut
67
68###########################################################################
69
70=head2 BlogResultHeader
71
72The contents of this container tag will be displayed when the blog id of
73the entry in context from search results differs from the previous entry's
74blog id.
75
76This tag is only recognized in search templates.
77
78=for tags search
79
80=cut
81
82###########################################################################
83
84=head2 BlogResultFooter
85
86The contents of this container tag will be displayed when the blog id of
87the entry in context from search results differs from the next entry's
88blog id.
89
90This tag is only recognized in search templates.
91
92=for tags search
93
94=cut
95
96###########################################################################
97
98=head2 IfMaxResultsCutOff
99
100NOTE: this tag only applies if you are using older Movable Type than
101version 4.15, or you set up your search script so it instantiates
102MT::App::Search::Legacy, the older search script.  Under the default
103search script in Movable Type, this tag will never be evaluated as true and
104therefore the contents will never be rendered.
105
106A conditional tag that returns true when the number of search results
107per blog exceeds the maximium limit specified in MaxResults configuration
108directive.
109
110This tag is only recognized in search templates.
111
112=cut
113
114###########################################################################
115
116=head2 MaxResults
117
118Returns the value of SearchMaxResults, specified either in configuration
119(via C<SearchMaxResults> configuration directive) or in the search query
120parameter in the URL.
121
122This tag is only recognized in search templates.
123
124=cut
125
126sub _hdlr_include_blogs { $_[0]->stash('include_blogs') || '' }
127sub _hdlr_search_string { $_[0]->stash('search_string') || '' }
128sub _hdlr_template_id { $_[0]->stash('template_id') || '' }
129sub _hdlr_max_results { $_[0]->stash('maxresults') || '' }
130
131sub _hdlr_result_count {
132    my $results = $_[0]->stash('count');
133    $results ? $results : 0;
134}
135
136sub _hdlr_results {
137    my($ctx, $args, $cond) = @_;
138
139    ## If there are no results, return the empty string, knowing
140    ## that the handler for <MTNoSearchResults> will fill in the
141    ## no results message.
142    my $iter = $ctx->stash('results') or return '';
143    my $count = $ctx->stash('count') or return '';
144    my $max = $ctx->stash('maxresults');
145    my $stash_key = $ctx->stash('stash_key') || 'entry';
146
147    my $output = '';
148    my $build = $ctx->stash('builder');
149    my $tokens = $ctx->stash('tokens');
150    my $blog_header = 1;
151    my $blog_footer = 0;
152    my $footer = 0;
153    my $count_per_blog = 0;
154    my $max_reached = 0;
155    my ( $this_object, $next_object );
156    $this_object = $iter->();
157    return '' unless $this_object;
158    for ( my $i = 0; $i < $count; $i++) {
159        $count_per_blog++;
160        $ctx->stash($stash_key, $this_object);
161        local $ctx->{__stash}{blog} = $this_object->blog
162            if $this_object->can('blog');
163        my $ts;
164        if ( $this_object->isa('MT::Entry') ) {
165            $ts = $this_object->authored_on;
166        }
167        elsif ( $this_object->properties->{audit} ) {
168            $ts = $this_object->created_on;
169        }
170        local $ctx->{current_timestamp} = $ts;
171
172        # TODO: per blog max objects?
173        #if ( $count_per_blog >= $max ) {
174        #    while (1) {
175        #        if ( $count > $i + 1 ) {
176        #            $next_object = $results->[$i + 1];
177        #            if ( $next_object->blog_id ne $this_object->blog_id ) {
178        #                $blog_footer = 1;
179        #                last;
180        #            }
181        #            else {
182        #                $max_reached = 1;
183        #            }
184        #        }
185        #        else {
186        #            $next_object = undef;
187        #            $blog_footer = 1;
188        #            last;
189        #        }
190        #        $i++;
191        #    }
192        #}
193        #elsif ( $count > $i + 1 ) {
194        #    $next_object = $results->[$i + 1];
195        #    $blog_footer = $next_object->blog_id ne $this_object->blog_id ? 1 : 0;
196        #}
197        #else {
198        #    $blog_footer = 1;
199        #}
200        if ( $next_object = $iter->() ) {
201            $blog_footer = $next_object->blog_id ne $this_object->blog_id ? 1 : 0;
202        }
203        else {
204            $blog_footer = 1;
205            $footer      = 1;
206        }
207
208        defined(my $out = $build->build($ctx, $tokens,
209            { %$cond, 
210                SearchResultsHeader => $i == 0,
211                SearchResultsFooter => $footer,
212                BlogResultHeader => $blog_header,
213                BlogResultFooter => $blog_footer,
214                IfMaxResultsCutoff => $max_reached,
215            }
216            )) or return $ctx->error( $build->errstr );
217        $output .= $out;
218
219        $this_object = $next_object;
220        last unless $this_object;
221        $blog_header = $blog_footer ? 1 : 0;
222    }
223    $output;
224}
225
226sub context_script {
227        my ( $ctx, $args, $cond ) = @_;
228
229    my $search_string = decode_html( $ctx->stash('search_string') ) ;
230    my $cgipath = $ctx->_hdlr_cgi_path($args);
231    my $script = $ctx->{config}->SearchScript;
232    my $link = $cgipath.$script . '?search=' . encode_url( $search_string );
233    if ( my $mode = $ctx->stash('mode') ) {
234        $mode = encode_url($mode);
235        $link .= "&__mode=$mode";
236    }
237    if ( my $type = $ctx->stash('type') ) {
238        $type = encode_url($type);
239        $link .= "&type=$type";
240    }
241    if ( my $include_blogs = $ctx->stash('include_blogs') ) {
242        $link .= "&IncludeBlogs=$include_blogs";
243    }
244    elsif ( my $blog_id = $ctx->stash('blog_id') ) {
245        $link .= "&blog_id=$blog_id";
246    }
247    if ( my $format = $ctx->stash('format') ) {
248        $link .= '&format=' . encode_url($format);
249    }
250        $link;
251}
252
2531;
254__END__
255
Note: See TracBrowser for help on using the browser.