Author: earle Date: 2005-11-24 20:01:09 +0000 (Thu, 24 Nov 2005) New Revision: 716
Added: trunk/lib/OpenGuides/Search.pm trunk/search.cgi trunk/t/31_search.t trunk/t/32_search_simple_metadata.t trunk/t/33_search_advanced_search.t trunk/t/33_search_advanced_search_utm.t trunk/t/34_search_paging.t trunk/t/35_search_two_searches.t trunk/t/36_search_order.t trunk/t/37_search_summaries.t trunk/t/38_search_params.t trunk/t/39_search_form.t trunk/templates/search.tt Removed: trunk/lib/OpenGuides/SuperSearch.pm trunk/supersearch.cgi trunk/t/31_supersearch.t trunk/t/32_supersearch_simple_metadata.t trunk/t/33_supersearch_advanced_search.t trunk/t/33_supersearch_advanced_search_utm.t trunk/t/34_supersearch_paging.t trunk/t/35_supersearch_two_searches.t trunk/t/36_supersearch_order.t trunk/t/37_supersearch_summaries.t trunk/t/38_supersearch_params.t trunk/t/39_supersearch_form.t trunk/templates/supersearch.tt Modified: trunk/Changes trunk/MANIFEST trunk/t/01_load.t trunk/templates/differences.tt trunk/templates/footer.tt trunk/templates/navbar.tt trunk/templates/node.tt Log: Renaming OpenGuides::SuperSearch to OpenGuides::Search and supersearch.cgi to search.cgi - bug #17.
Modified: trunk/Changes =================================================================== --- trunk/Changes 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/Changes 2005-11-24 20:01:09 UTC (rev 716) @@ -1,4 +1,9 @@ -0.52 Fix missing bracket in node.tt. +0.52 + IMPORTANT CHANGE: "supersearch.cgi" is now simply "search.cgi". If you + have customisations to your templates, you may need to make changes + to reflect this. + Rename OpenGuides::SuperSearch to OpenGuides::Search. + Fix missing bracket in node.tt. Add custom_node template just below main content in node.tt.
0.51 15 November 2005
Modified: trunk/MANIFEST =================================================================== --- trunk/MANIFEST 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/MANIFEST 2005-11-24 20:01:09 UTC (rev 716) @@ -17,14 +17,14 @@ lib/OpenGuides/CGI.pm lib/OpenGuides/Config.pm lib/OpenGuides/RDF.pm -lib/OpenGuides/SuperSearch.pm +lib/OpenGuides/Search.pm lib/OpenGuides/Template.pm lib/OpenGuides/Test.pm lib/OpenGuides/Utils.pm lib/OpenGuides.pm newpage.cgi preferences.cgi -supersearch.cgi +search.cgi templates/backlink_results.tt templates/banner.tt templates/delete_confirm.tt @@ -49,7 +49,7 @@ templates/recent_changes.tt templates/search_results.tt templates/site_index.tt -templates/supersearch.tt +templates/search.tt templates/userstats.tt templates/wanted_pages.tt t/01_load.t @@ -64,16 +64,16 @@ t/25_write_geo_data.t t/26_geo_data_search_form.t t/27_geo_data_edit_form.t -t/31_supersearch.t -t/32_supersearch_simple_metadata.t -t/33_supersearch_advanced_search.t -t/33_supersearch_advanced_search_utm.t -t/34_supersearch_paging.t -t/35_supersearch_two_searches.t -t/36_supersearch_order.t -t/37_supersearch_summaries.t -t/38_supersearch_params.t -t/39_supersearch_form.t +t/31_search.t +t/32_search_simple_metadata.t +t/33_search_advanced_search.t +t/33_search_advanced_search_utm.t +t/34_search_paging.t +t/35_search_two_searches.t +t/36_search_order.t +t/37_search_summaries.t +t/38_search_params.t +t/39_search_form.t t/41_deletion.t t/51_display_node.t t/52_display_diffs.t
Copied: trunk/lib/OpenGuides/Search.pm (from rev 715, trunk/lib/OpenGuides/SuperSearch.pm) =================================================================== --- trunk/lib/OpenGuides/SuperSearch.pm 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/lib/OpenGuides/Search.pm 2005-11-24 20:01:09 UTC (rev 716) @@ -0,0 +1,746 @@ +package OpenGuides::Search; +use strict; +our $VERSION = '0.10'; + +use CGI qw( :standard ); +use CGI::Wiki::Plugin::Locator::Grid; +use File::Spec::Functions qw(:ALL); +use OpenGuides::Template; +use OpenGuides::Utils; +use Parse::RecDescent; + +=head1 NAME + +OpenGuides::Search - Search form generation and processing for OpenGuides. + +=head1 DESCRIPTION + +Does search stuff for OpenGuides. Distributed and installed as part of +the OpenGuides project, not intended for independent installation. +This documentation is probably only useful to OpenGuides developers. + +=head1 SYNOPSIS + + use CGI; + use OpenGuides::Config; + use OpenGuides::Search; + + my $config = OpenGuides::Config->new( file => "wiki.conf" ); + my $search = OpenGuides::Search->new( config => $config ); + my %vars = CGI::Vars(); + $search->run( vars => %vars ); + +=head1 METHODS + +=over 4 + +=item B<new> + + my $config = OpenGuides::Config->new( file => "wiki.conf" ); + my $search = OpenGuides::Search->new( config => $config ); + +=cut + +sub new { + my ($class, %args) = @_; + my $config = $args{config}; + my $self = { config => $config }; + bless $self, $class; + + my $wiki = OpenGuides::Utils->make_wiki_object( config => $config ); + + $self->{wiki} = $wiki; + $self->{wikimain} = $config->script_url . $config->script_name; + $self->{css} = $config->stylesheet_url; + $self->{head} = $config->site_name . " Search"; + + my $geo_handler = $config->geo_handler; + my %locator_params; + if ( $geo_handler == 1 ) { + %locator_params = ( x => "os_x", y => "os_y" ); + } elsif ( $geo_handler == 2 ) { + %locator_params = ( x => "osie_x", y => "osie_y" ); + } elsif ( $geo_handler == 3 ) { + %locator_params = ( x => "easting", y => "northing" ); + } + + my $locator = CGI::Wiki::Plugin::Locator::Grid->new( %locator_params ); + $wiki->register_plugin( plugin => $locator ); + $self->{locator} = $locator; + + return $self; +} + +=item B<wiki> + + my $wiki = $search->wiki; + +An accessor; returns the underlying LCGI::Wiki object. + +=cut + +sub wiki { + my $self = shift; + return $self->{wiki}; +} + +=item B<config> + + my $config = $search->config; + +An accessor; returns the underlying LOpenGuides::Config object. + +=cut + +sub config { + my $self = shift; + return $self->{config}; +} + +=item B<run> + + my %vars = CGI::Vars(); + $search->run( + vars => %vars, + return_output => 1, # defaults to 0 + return_tt_vars => 1, # defaults to 0 + ); + +The C<return_output> parameter is optional. If supplied and true, the +stuff that would normally be printed to STDOUT will be returned as a +string instead. + +The C<return_tt_vars> parameter is also optional. If supplied and +true, the template is not processed and the variables that would have +been passed to it are returned as a hash. This parameter takes +precedence over C<return_output>. + +These two parameters exist to make testing easier; you probably don't +want to use them in production. + +=back + +=cut + +sub run { + my ($self, %args) = @_; + $self->{return_output} = $args{return_output} || 0; + $self->{return_tt_vars} = $args{return_tt_vars} || 0; + + $self->process_params( $args{vars} ); + if ( $self->{error} ) { + warn $self->{error}; + my %tt_vars = ( error_message => $self->{error} ); + $self->process_template( tt_vars => %tt_vars ); + return; + } + + my %tt_vars = ( + ss_version => $VERSION, + ss_info_url => 'http://openguides.org/page/search_help' + ); + + my $doing_search; + + # Run a text search if we have a search string. + if ( $self->{search_string} ) { + $doing_search = 1; + $tt_vars{search_terms} = $self->{search_string}; + $self->run_text_search; + } + + # Run a distance search if we have sufficient criteria. + if ( defined $self->{distance_in_metres} + && defined $self->{x} && defined $self->{y} ) { + $doing_search = 1; + # Make sure to pass the criteria to the template. + $tt_vars{dist} = $self->{distance_in_metres}; + $tt_vars{latitude} = $self->{latitude}; + $tt_vars{longitude} = $self->{longitude}; + if ( $self->config->geo_handler eq 1 ) { + $tt_vars{coord_field_1_value} = $self->{os_x}; + $tt_vars{coord_field_2_value} = $self->{os_y}; + } elsif ( $self->config->geo_handler eq 2 ) { + $tt_vars{coord_field_1_value} = $self->{osie_x}; + $tt_vars{coord_field_2_value} = $self->{osie_y}; + } elsif ( $self->config->geo_handler eq 3 ) { + $tt_vars{coord_field_1_value} = $self->{latitude}; + $tt_vars{coord_field_2_value} = $self->{longitude}; + } + $self->run_distance_search; + } + + # If we're not doing a search then just print the search form. + unless ( $doing_search ) { + return $self->process_template( tt_vars => %tt_vars ); + } + + # At this point either $self->{error} or $self->{results} will be filled. + if ( $self->{error} ) { + $tt_vars{error_message} = $self->{error}; + $self->process_template( tt_vars => %tt_vars ); + return; + } + + # So now we know that we have been asked to perform a search, and we + # have performed it. + # + # $self->{results} will be a hash of refs to hashes like so: + # 'Node Name' => { + # name => 'Node Name', + # distance => $distance_from_origin_if_any, + # score => $relevance_to_search_string + # } + + my %results_hash = %{ $self->{results} || [] }; + my @results = values %results_hash; + my $numres = scalar @results; + + # If we only have a single hit, and the title is a good enough match + # to the search string, redirect to that node. + # (Don't try a fuzzy search on a blank search string - Plucene chokes.) + if ( $self->{search_string} && $numres == 1 && !$self->{return_tt_vars}) { + my %fuzzies = $self->wiki->fuzzy_title_match($self->{search_string}); + if ( scalar keys %fuzzies ) { + my $node = $results[0]{name}; + my $formatter = $self->wiki->formatter; + my $node_param = CGI::escape( + $formatter->node_name_to_node_param( $node ) + ); + my $output = CGI::redirect( $self->{wikimain} . "?$node_param" ); + return $output if $self->{return_output}; + print $output; + return; + } + } + + # If we had no hits then go straight to the template. + if ( $numres == 0 ) { + %tt_vars = ( + %tt_vars, + first_num => 0, + results => [], + ); + return $self->process_template( tt_vars => %tt_vars ); + } + + # Otherwise, we browse through the results a page at a time. + + # Figure out which results we're going to be showing on this + # page, and what the first one for the next page will be. + my $startpos = $args{vars}{next} || 0; + $tt_vars{first_num} = $numres ? $startpos + 1 : 0; + $tt_vars{last_num} = $numres > $startpos + 20 ? $startpos + 20 : $numres; + $tt_vars{total_num} = $numres; + if ( $numres > $startpos + 20 ) { + $tt_vars{next_page_startpos} = $startpos + 20; + } + + # Sort the results - by distance if we're searching on that + # or by score otherwise. + if ( $self->{distance_in_metres} ) { + @results = sort { $a->{distance} <=> $b->{distance} } @results; + } else { + @results = sort { $b->{score} <=> $a->{score} } @results; + } + + # Now snip out just the ones for this page. The -1 is because + # arrays index from 0 and people from 1. + my $from = $tt_vars{first_num} ? $tt_vars{first_num} - 1 : 0; + my $to = $tt_vars{last_num} - 1; # kludge to empty arr for no results + @results = @results[ $from .. $to ]; + + # Add the URL to each result hit. + my $formatter = $self->wiki->formatter; + foreach my $i ( 0 .. $#results ) { + my $name = $results[$i]{name}; + + # Add the one-line summary of the node, if there is one. + my %node = $self->wiki->retrieve_node($name); + $results[$i]{summary} = $node{metadata}{summary}[0]; + + my $node_param = $formatter->node_name_to_node_param( $name ); + $results[$i]{url} = $self->{wikimain} . "?$node_param"; + } + + # Finally pass the results to the template. + $tt_vars{results} = @results; + $self->process_template( tt_vars => %tt_vars ); +} + +sub run_text_search { + my $self = shift; + my $searchstr = $self->{search_string}; + my $wiki = $self->wiki; + + # Create parser to parse the search string. + my $parser = Parse::RecDescent->new( q{ + + search: list eostring {$return = $item[1]} + + list: comby(s) + {$return = (@{$item[1]}>1) ? ['AND', @{$item[1]}] : $item[1][0]} + + comby: <leftop: term ',' term> + {$return = (@{$item[1]}>1) ? ['OR', @{$item[1]}] : $item[1][0]} + + term: '(' list ')' {$return = $item[2]} + | '-' term {$return = ['NOT', @{$item[2]}]} + | '"' word(s) '"' {$return = ['phrase', join " ", @{$item[2]}]} + | word {$return = ['word', $item[1]]} + | '[' word(s) ']' {$return = ['title', @{$item[2]}]} + + word: /[\w'*%]+/ {$return = $item[1]} + + eostring: /^\Z/ + + } ); + + unless ( $parser ) { + warn $@; + $self->{error} = "Can't create parse object - $@"; + return $self; + } + + # Run parser over search string. + my $tree = $parser->search( $searchstr ); + unless ( $tree ) { + $self->{error} = "Syntax error in search: $searchstr"; + return $self; + } + + # Run the search over the generated search tree. + my %results = $self->_run_search_tree( tree => $tree ); + $self->{results} = %results; + return $self; +} + +sub _run_search_tree { + my ($self, %args) = @_; + my $tree = $args{tree}; + my @tree_arr = @$tree; + my $op = shift @tree_arr; + my $method = "_run_" . $op . "_search"; + return $self->can($method) ? $self->$method(@tree_arr) : undef; +} + +=head1 INPUT + +=over + +=item B<word> + +a single word will be matched as-is. For example, a search on + + escalator + +will return all pages containing the word "escalator". + +=cut + +sub _run_word_search { + my ($self, $word) = @_; + # A word is just a small phrase. + return $self->_run_phrase_search( $word ); +} + +=item B<AND searches> + +A list of words with no punctuation will be ANDed, for example: + + restaurant vegetarian + +will return all pages containing both the word "restaurant" and the word +"vegetarian". + +=cut + +sub _run_AND_search { + my ($self, @subsearches) = @_; + + # Do the first subsearch. + my %results = $self->_run_search_tree( tree => $subsearches[0] ); + + # Now do the rest one at a time and remove from the results anything + # that doesn't come up in each subsearch. Results that survive will + # have a score that's the sum of their score in each subsearch. + foreach my $tree ( @subsearches[ 1 .. $#subsearches ] ) { + my %subres = $self->_run_search_tree( tree => $tree ); + my @pages = keys %results; + foreach my $page ( @pages ) { + if ( exists $subres{$page} ) { + $results{$page}{score} += $subres{$page}{score}; + } else { + delete $results{$page}; + } + } + } + + return %results; +} + +=item B<OR searches> + +A list of words separated by commas (and optional spaces) will be ORed, +for example: + + restaurant, cafe + +will return all pages containing either the word "restaurant" or the +word "cafe". + +=cut + +sub _run_OR_search { + my ($self, @subsearches) = @_; + + # Do all the searches. Results will have a score that's the sum + # of their score in each subsearch. + my %results; + foreach my $tree ( @subsearches ) { + my %subres = $self->_run_search_tree( tree => $tree ); + foreach my $page ( keys %subres ) { + if ( $results{$page} ) { + $results{$page}{score} += $subres{$page}{score}; + } else { + $results{$page} = $subres{$page}; + } + } + } + return %results; +} + +=item B<phrase searches> + +Enclose phrases in double quotes, for example: + + "meat pie" + +will return all pages that contain the exact phrase "meat pie" - not pages +that only contain, for example, "apple pie and meat sausage". + +=cut + +sub _run_phrase_search { + my ($self, $phrase) = @_; + my $wiki = $self->wiki; + + # Search title and body. + my %contents_res = $wiki->search_nodes( $phrase ); + + # Rationalise the scores a little. The scores returned by + # CGI::Wiki::Search::Plucene are simply a ranking. + my $num_results = scalar keys %contents_res; + foreach my $node ( keys %contents_res ) { + $contents_res{$node} = int( $contents_res{$node} / $num_results ) + 1; + } + + # It'll be a real phrase (as opposed to a word) if it has a space in it. + # In this case, dump out the nodes that don't match the search exactly. + # I don't know why the phrase searching isn't working properly. Fix later. + if ( $phrase =~ /\s/ ) { + my @tmp = keys %contents_res; + foreach my $node ( @tmp ) { + my $content = $wiki->retrieve_node( $node ); + unless ( $content =~ /$phrase/i || $node =~ /$phrase/i ) { + delete $contents_res{$node}; + } + } + } + + my %results = map { $_ => { name => $_, score => $contents_res{$_} } } + keys %contents_res; + + # Bump up the score if the title matches. + foreach my $node ( keys %results ) { + $results{$node}{score} += 10 if $node =~ /$phrase/i; + } + + # Search categories. + my @catmatches = $wiki->list_nodes_by_metadata( + metadata_type => "category", + metadata_value => $phrase, + ignore_case => 1, + ); + + foreach my $node ( @catmatches ) { + if ( $results{$node} ) { + $results{$node}{score} += 3; + } else { + $results{$node} = { name => $node, score => 3 }; + } + } + + # Search locales. + my @locmatches = $wiki->list_nodes_by_metadata( + metadata_type => "locale", + metadata_value => $phrase, + ignore_case => 1, + ); + + foreach my $node ( @locmatches ) { + if ( $results{$node} ) { + $results{$node}{score} += 3; + } else { + $results{$node} = { name => $node, score => 3 }; + } + } + + return %results; +} + +=back + +=head1 SEARCHING BY DISTANCE + +To perform a distance search, you need to supply one of the following +sets of criteria to specify the distance to search within, and the +origin (centre) of the search: + +=over + +=item B<os_dist, os_x, and os_y> + +Only works if you chose to use British National Grid in wiki.conf + +=item B<osie_dist, osie_x, and osie_y> + +Only works if you chose to use Irish National Grid in wiki.conf + +=item B<latlong_dist, latitude, and longitude> + +Should always work, but has a habit of "finding" things a couple of +metres away from themselves. + +=back + +You can perform both pure distance searches and distance searches in +combination with text searches. + +=cut + +# Note this is called after any text search is run, and it is only called +# if there are sufficient criteria to perform the search. +sub run_distance_search { + my $self = shift; + my $x = $self->{x}; + my $y = $self->{y}; + my $dist = $self->{distance_in_metres}; + + my @close = $self->{locator}->find_within_distance( + x => $x, + y => $y, + metres => $dist, + ); + + if ( $self->{results} ) { + my %close_hash = map { $_ => 1 } @close; + my %results = %{ $self->{results} }; + my @candidates = keys %results; + foreach my $node ( @candidates ) { + if ( exists $close_hash{$node} ) { + my $distance = $self->_get_distance( + node => $node, + x => $x, + y => $y, + ); + $results{$node}{distance} = $distance; + } else { + delete $results{$node}; + } + } + $self->{results} = %results; + } else { + my %results; + foreach my $node ( @close ) { + my $distance = $self->_get_distance ( + node => $node, + x => $x, + y => $y, + ); + $results{$node} = { + name => $node, + distance => $distance, + }; + } + $self->{results} = %results; + } + return $self; +} + +sub _get_distance { + my ($self, %args) = @_; + my ($node, $x, $y) = @args{ qw( node x y ) }; + return $self->{locator}->distance( + from_x => $x, + from_y => $y, + to_node => $node, + unit => "metres" + ); +} + +sub process_params { + my ($self, $vars_hashref) = @_; + my %vars = %{ $vars_hashref || {} }; + + # Make sure that we don't have any data left over from previous invocation. + # This is useful for testing purposes at the moment and will be essential + # for mod_perl implementations. + delete $self->{x}; + delete $self->{y}; + delete $self->{distance_in_metres}; + delete $self->{search_string}; + + # Strip out any non-digits from distance and OS co-ords. + foreach my $param ( qw( os_x os_y osie_x osie_y + osie_dist os_dist latlong_dist ) ) { + if ( defined $vars{$param} ) { + $vars{$param} =~ s/[^0-9]//g; + # 0 is an allowed value but the empty string isn't. + delete $vars{$param} if $vars{$param} eq ""; + } + } + + # Latitude and longitude are also allowed '-' and '.' + foreach my $param( qw( latitude longitude ) ) { + if ( defined $vars{$param} ) { + $vars{$param} =~ s/[^-.0-9]//g; + # 0 is an allowed value but the empty string isn't. + delete $vars{$param} if $vars{$param} eq ""; + } + } + + # Set $self->{distance_in_metres}, $self->{x}, $self->{y}, + # depending on whether we got + # OS co-ords or lat/long. Only store parameters if they're complete, + # and supported by our method of distance calculation. + if ( defined $vars{os_x} && defined $vars{os_y} && defined $vars{os_dist} + && $self->config->geo_handler eq 1 ) { + $self->{x} = $vars{os_x}; + $self->{y} = $vars{os_y}; + $self->{distance_in_metres} = $vars{os_dist}; + } elsif ( defined $vars{osie_x} && defined $vars{osie_y} + && defined $vars{osie_dist} + && $self->config->geo_handler eq 2 ) { + $self->{x} = $vars{osie_x}; + $self->{y} = $vars{osie_y}; + $self->{distance_in_metres} = $vars{osie_dist}; + } elsif ( defined $vars{latitude} && defined $vars{longitude} + && defined $vars{latlong_dist} ) { + # All handlers can do lat/long, but they all do it differently. + if ( $self->config->geo_handler eq 1 ) { + require Geography::NationalGrid::GB; + my $point = Geography::NationalGrid::GB->new( + Latitude => $vars{latitude}, + Longitude => $vars{longitude}, + ); + $self->{x} = $point->easting; + $self->{y} = $point->northing; + } elsif ( $self->config->geo_handler eq 2 ) { + require Geography::NationalGrid::IE; + my $point = Geography::NationalGrid::IE->new( + Latitude => $vars{latitude}, + Longitude => $vars{longitude}, + ); + $self->{x} = $point->easting; + $self->{y} = $point->northing; + } elsif ( $self->config->geo_handler eq 3 ) { + require Geo::Coordinates::UTM; + my ($zone, $x, $y) = Geo::Coordinates::UTM::latlon_to_utm( + $self->config->ellipsoid, + $vars{latitude}, + $vars{longitude}, + ); + $self->{x} = $x; + $self->{y} = $y; + } + $self->{distance_in_metres} = $vars{latlong_dist}; + } + + # Store os_x etc so we can pass them to template. + foreach my $param ( qw( os_x os_y osie_x osie_y latitude longitude ) ) { + $self->{$param} = $vars{$param}; + } + + # Strip leading and trailing whitespace from search text. + $vars{search} ||= ""; # avoid uninitialised value warning + $vars{search} =~ s/^\s*//; + $vars{search} =~ s/\s*$//; + + # Check for only valid characters in tainted search param + # (quoted literals are OK, as they are escaped) + # This regex copied verbatim from Ivor's old supersearch. + if ( $vars{search} + && $vars{search} !~ /^("[^"]*"|[\w -',()!*%[]])+$/i) { + $self->{error} = "Search expression $vars{search} contains invalid character(s)"; + return $self; + } + $self->{search_string} = $vars{search}; + + return $self; +} + +# thin wrapper around OpenGuides::Template +sub process_template { + my ($self, %args) = @_; + + my $tt_vars = $args{tt_vars} || {}; + $tt_vars->{not_editable} = 1; + $tt_vars->{not_deletable} = 1; + return %$tt_vars if $self->{return_tt_vars}; + my $output = OpenGuides::Template->output( + wiki => $self->wiki, + config => $self->config, + template => "search.tt", + vars => $tt_vars, + ); + return $output if $self->{return_output}; + + print $output; + return 1; +} + +=head1 OUTPUT + +Results will be put into some form of relevance ordering. These are +the rules we have tests for so far (and hence the only rules that can +be relied on): + +=over + +=item * + +A match on page title will score higher than a match on page category +or locale. + +=item * + +A match on page category or locale will score higher than a match on +page content. + +=item * + +Two matches in the title beats one match in the title and one in the content. + +=back + +=cut + +=head1 AUTHOR + +The OpenGuides Project (openguides-dev@openguides.org) + +=head1 COPYRIGHT + + Copyright (C) 2003-2004 The OpenGuides Project. All Rights Reserved. + +The OpenGuides distribution is free software; you can redistribute it +and/or modify it under the same terms as Perl itself. + +=head1 SEE ALSO + +L<OpenGuides> + +=cut + +1;
Deleted: trunk/lib/OpenGuides/SuperSearch.pm =================================================================== --- trunk/lib/OpenGuides/SuperSearch.pm 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/lib/OpenGuides/SuperSearch.pm 2005-11-24 20:01:09 UTC (rev 716) @@ -1,746 +0,0 @@ -package OpenGuides::SuperSearch; -use strict; -our $VERSION = '0.10'; - -use CGI qw( :standard ); -use CGI::Wiki::Plugin::Locator::Grid; -use File::Spec::Functions qw(:ALL); -use OpenGuides::Template; -use OpenGuides::Utils; -use Parse::RecDescent; - -=head1 NAME - -OpenGuides::SuperSearch - Search form generation and processing for OpenGuides. - -=head1 DESCRIPTION - -Does search stuff for OpenGuides. Distributed and installed as part of -the OpenGuides project, not intended for independent installation. -This documentation is probably only useful to OpenGuides developers. - -=head1 SYNOPSIS - - use CGI; - use OpenGuides::Config; - use OpenGuides::SuperSearch; - - my $config = OpenGuides::Config->new( file => "wiki.conf" ); - my $search = OpenGuides::SuperSearch->new( config => $config ); - my %vars = CGI::Vars(); - $search->run( vars => %vars ); - -=head1 METHODS - -=over 4 - -=item B<new> - - my $config = OpenGuides::Config->new( file => "wiki.conf" ); - my $search = OpenGuides::SuperSearch->new( config => $config ); - -=cut - -sub new { - my ($class, %args) = @_; - my $config = $args{config}; - my $self = { config => $config }; - bless $self, $class; - - my $wiki = OpenGuides::Utils->make_wiki_object( config => $config ); - - $self->{wiki} = $wiki; - $self->{wikimain} = $config->script_url . $config->script_name; - $self->{css} = $config->stylesheet_url; - $self->{head} = $config->site_name . " Search"; - - my $geo_handler = $config->geo_handler; - my %locator_params; - if ( $geo_handler == 1 ) { - %locator_params = ( x => "os_x", y => "os_y" ); - } elsif ( $geo_handler == 2 ) { - %locator_params = ( x => "osie_x", y => "osie_y" ); - } elsif ( $geo_handler == 3 ) { - %locator_params = ( x => "easting", y => "northing" ); - } - - my $locator = CGI::Wiki::Plugin::Locator::Grid->new( %locator_params ); - $wiki->register_plugin( plugin => $locator ); - $self->{locator} = $locator; - - return $self; -} - -=item B<wiki> - - my $wiki = $search->wiki; - -An accessor; returns the underlying LCGI::Wiki object. - -=cut - -sub wiki { - my $self = shift; - return $self->{wiki}; -} - -=item B<config> - - my $config = $search->config; - -An accessor; returns the underlying LOpenGuides::Config object. - -=cut - -sub config { - my $self = shift; - return $self->{config}; -} - -=item B<run> - - my %vars = CGI::Vars(); - $search->run( - vars => %vars, - return_output => 1, # defaults to 0 - return_tt_vars => 1, # defaults to 0 - ); - -The C<return_output> parameter is optional. If supplied and true, the -stuff that would normally be printed to STDOUT will be returned as a -string instead. - -The C<return_tt_vars> parameter is also optional. If supplied and -true, the template is not processed and the variables that would have -been passed to it are returned as a hash. This parameter takes -precedence over C<return_output>. - -These two parameters exist to make testing easier; you probably don't -want to use them in production. - -=back - -=cut - -sub run { - my ($self, %args) = @_; - $self->{return_output} = $args{return_output} || 0; - $self->{return_tt_vars} = $args{return_tt_vars} || 0; - - $self->process_params( $args{vars} ); - if ( $self->{error} ) { - warn $self->{error}; - my %tt_vars = ( error_message => $self->{error} ); - $self->process_template( tt_vars => %tt_vars ); - return; - } - - my %tt_vars = ( - ss_version => $VERSION, - ss_info_url => 'http://openguides.org/page/search_help' - ); - - my $doing_search; - - # Run a text search if we have a search string. - if ( $self->{search_string} ) { - $doing_search = 1; - $tt_vars{search_terms} = $self->{search_string}; - $self->run_text_search; - } - - # Run a distance search if we have sufficient criteria. - if ( defined $self->{distance_in_metres} - && defined $self->{x} && defined $self->{y} ) { - $doing_search = 1; - # Make sure to pass the criteria to the template. - $tt_vars{dist} = $self->{distance_in_metres}; - $tt_vars{latitude} = $self->{latitude}; - $tt_vars{longitude} = $self->{longitude}; - if ( $self->config->geo_handler eq 1 ) { - $tt_vars{coord_field_1_value} = $self->{os_x}; - $tt_vars{coord_field_2_value} = $self->{os_y}; - } elsif ( $self->config->geo_handler eq 2 ) { - $tt_vars{coord_field_1_value} = $self->{osie_x}; - $tt_vars{coord_field_2_value} = $self->{osie_y}; - } elsif ( $self->config->geo_handler eq 3 ) { - $tt_vars{coord_field_1_value} = $self->{latitude}; - $tt_vars{coord_field_2_value} = $self->{longitude}; - } - $self->run_distance_search; - } - - # If we're not doing a search then just print the search form. - unless ( $doing_search ) { - return $self->process_template( tt_vars => %tt_vars ); - } - - # At this point either $self->{error} or $self->{results} will be filled. - if ( $self->{error} ) { - $tt_vars{error_message} = $self->{error}; - $self->process_template( tt_vars => %tt_vars ); - return; - } - - # So now we know that we have been asked to perform a search, and we - # have performed it. - # - # $self->{results} will be a hash of refs to hashes like so: - # 'Node Name' => { - # name => 'Node Name', - # distance => $distance_from_origin_if_any, - # score => $relevance_to_search_string - # } - - my %results_hash = %{ $self->{results} || [] }; - my @results = values %results_hash; - my $numres = scalar @results; - - # If we only have a single hit, and the title is a good enough match - # to the search string, redirect to that node. - # (Don't try a fuzzy search on a blank search string - Plucene chokes.) - if ( $self->{search_string} && $numres == 1 && !$self->{return_tt_vars}) { - my %fuzzies = $self->wiki->fuzzy_title_match($self->{search_string}); - if ( scalar keys %fuzzies ) { - my $node = $results[0]{name}; - my $formatter = $self->wiki->formatter; - my $node_param = CGI::escape( - $formatter->node_name_to_node_param( $node ) - ); - my $output = CGI::redirect( $self->{wikimain} . "?$node_param" ); - return $output if $self->{return_output}; - print $output; - return; - } - } - - # If we had no hits then go straight to the template. - if ( $numres == 0 ) { - %tt_vars = ( - %tt_vars, - first_num => 0, - results => [], - ); - return $self->process_template( tt_vars => %tt_vars ); - } - - # Otherwise, we browse through the results a page at a time. - - # Figure out which results we're going to be showing on this - # page, and what the first one for the next page will be. - my $startpos = $args{vars}{next} || 0; - $tt_vars{first_num} = $numres ? $startpos + 1 : 0; - $tt_vars{last_num} = $numres > $startpos + 20 ? $startpos + 20 : $numres; - $tt_vars{total_num} = $numres; - if ( $numres > $startpos + 20 ) { - $tt_vars{next_page_startpos} = $startpos + 20; - } - - # Sort the results - by distance if we're searching on that - # or by score otherwise. - if ( $self->{distance_in_metres} ) { - @results = sort { $a->{distance} <=> $b->{distance} } @results; - } else { - @results = sort { $b->{score} <=> $a->{score} } @results; - } - - # Now snip out just the ones for this page. The -1 is because - # arrays index from 0 and people from 1. - my $from = $tt_vars{first_num} ? $tt_vars{first_num} - 1 : 0; - my $to = $tt_vars{last_num} - 1; # kludge to empty arr for no results - @results = @results[ $from .. $to ]; - - # Add the URL to each result hit. - my $formatter = $self->wiki->formatter; - foreach my $i ( 0 .. $#results ) { - my $name = $results[$i]{name}; - - # Add the one-line summary of the node, if there is one. - my %node = $self->wiki->retrieve_node($name); - $results[$i]{summary} = $node{metadata}{summary}[0]; - - my $node_param = $formatter->node_name_to_node_param( $name ); - $results[$i]{url} = $self->{wikimain} . "?$node_param"; - } - - # Finally pass the results to the template. - $tt_vars{results} = @results; - $self->process_template( tt_vars => %tt_vars ); -} - -sub run_text_search { - my $self = shift; - my $searchstr = $self->{search_string}; - my $wiki = $self->wiki; - - # Create parser to parse the search string. - my $parser = Parse::RecDescent->new( q{ - - search: list eostring {$return = $item[1]} - - list: comby(s) - {$return = (@{$item[1]}>1) ? ['AND', @{$item[1]}] : $item[1][0]} - - comby: <leftop: term ',' term> - {$return = (@{$item[1]}>1) ? ['OR', @{$item[1]}] : $item[1][0]} - - term: '(' list ')' {$return = $item[2]} - | '-' term {$return = ['NOT', @{$item[2]}]} - | '"' word(s) '"' {$return = ['phrase', join " ", @{$item[2]}]} - | word {$return = ['word', $item[1]]} - | '[' word(s) ']' {$return = ['title', @{$item[2]}]} - - word: /[\w'*%]+/ {$return = $item[1]} - - eostring: /^\Z/ - - } ); - - unless ( $parser ) { - warn $@; - $self->{error} = "Can't create parse object - $@"; - return $self; - } - - # Run parser over search string. - my $tree = $parser->search( $searchstr ); - unless ( $tree ) { - $self->{error} = "Syntax error in search: $searchstr"; - return $self; - } - - # Run the search over the generated search tree. - my %results = $self->_run_search_tree( tree => $tree ); - $self->{results} = %results; - return $self; -} - -sub _run_search_tree { - my ($self, %args) = @_; - my $tree = $args{tree}; - my @tree_arr = @$tree; - my $op = shift @tree_arr; - my $method = "_run_" . $op . "_search"; - return $self->can($method) ? $self->$method(@tree_arr) : undef; -} - -=head1 INPUT - -=over - -=item B<word> - -a single word will be matched as-is. For example, a search on - - escalator - -will return all pages containing the word "escalator". - -=cut - -sub _run_word_search { - my ($self, $word) = @_; - # A word is just a small phrase. - return $self->_run_phrase_search( $word ); -} - -=item B<AND searches> - -A list of words with no punctuation will be ANDed, for example: - - restaurant vegetarian - -will return all pages containing both the word "restaurant" and the word -"vegetarian". - -=cut - -sub _run_AND_search { - my ($self, @subsearches) = @_; - - # Do the first subsearch. - my %results = $self->_run_search_tree( tree => $subsearches[0] ); - - # Now do the rest one at a time and remove from the results anything - # that doesn't come up in each subsearch. Results that survive will - # have a score that's the sum of their score in each subsearch. - foreach my $tree ( @subsearches[ 1 .. $#subsearches ] ) { - my %subres = $self->_run_search_tree( tree => $tree ); - my @pages = keys %results; - foreach my $page ( @pages ) { - if ( exists $subres{$page} ) { - $results{$page}{score} += $subres{$page}{score}; - } else { - delete $results{$page}; - } - } - } - - return %results; -} - -=item B<OR searches> - -A list of words separated by commas (and optional spaces) will be ORed, -for example: - - restaurant, cafe - -will return all pages containing either the word "restaurant" or the -word "cafe". - -=cut - -sub _run_OR_search { - my ($self, @subsearches) = @_; - - # Do all the searches. Results will have a score that's the sum - # of their score in each subsearch. - my %results; - foreach my $tree ( @subsearches ) { - my %subres = $self->_run_search_tree( tree => $tree ); - foreach my $page ( keys %subres ) { - if ( $results{$page} ) { - $results{$page}{score} += $subres{$page}{score}; - } else { - $results{$page} = $subres{$page}; - } - } - } - return %results; -} - -=item B<phrase searches> - -Enclose phrases in double quotes, for example: - - "meat pie" - -will return all pages that contain the exact phrase "meat pie" - not pages -that only contain, for example, "apple pie and meat sausage". - -=cut - -sub _run_phrase_search { - my ($self, $phrase) = @_; - my $wiki = $self->wiki; - - # Search title and body. - my %contents_res = $wiki->search_nodes( $phrase ); - - # Rationalise the scores a little. The scores returned by - # CGI::Wiki::Search::Plucene are simply a ranking. - my $num_results = scalar keys %contents_res; - foreach my $node ( keys %contents_res ) { - $contents_res{$node} = int( $contents_res{$node} / $num_results ) + 1; - } - - # It'll be a real phrase (as opposed to a word) if it has a space in it. - # In this case, dump out the nodes that don't match the search exactly. - # I don't know why the phrase searching isn't working properly. Fix later. - if ( $phrase =~ /\s/ ) { - my @tmp = keys %contents_res; - foreach my $node ( @tmp ) { - my $content = $wiki->retrieve_node( $node ); - unless ( $content =~ /$phrase/i || $node =~ /$phrase/i ) { - delete $contents_res{$node}; - } - } - } - - my %results = map { $_ => { name => $_, score => $contents_res{$_} } } - keys %contents_res; - - # Bump up the score if the title matches. - foreach my $node ( keys %results ) { - $results{$node}{score} += 10 if $node =~ /$phrase/i; - } - - # Search categories. - my @catmatches = $wiki->list_nodes_by_metadata( - metadata_type => "category", - metadata_value => $phrase, - ignore_case => 1, - ); - - foreach my $node ( @catmatches ) { - if ( $results{$node} ) { - $results{$node}{score} += 3; - } else { - $results{$node} = { name => $node, score => 3 }; - } - } - - # Search locales. - my @locmatches = $wiki->list_nodes_by_metadata( - metadata_type => "locale", - metadata_value => $phrase, - ignore_case => 1, - ); - - foreach my $node ( @locmatches ) { - if ( $results{$node} ) { - $results{$node}{score} += 3; - } else { - $results{$node} = { name => $node, score => 3 }; - } - } - - return %results; -} - -=back - -=head1 SEARCHING BY DISTANCE - -To perform a distance search, you need to supply one of the following -sets of criteria to specify the distance to search within, and the -origin (centre) of the search: - -=over - -=item B<os_dist, os_x, and os_y> - -Only works if you chose to use British National Grid in wiki.conf - -=item B<osie_dist, osie_x, and osie_y> - -Only works if you chose to use Irish National Grid in wiki.conf - -=item B<latlong_dist, latitude, and longitude> - -Should always work, but has a habit of "finding" things a couple of -metres away from themselves. - -=back - -You can perform both pure distance searches and distance searches in -combination with text searches. - -=cut - -# Note this is called after any text search is run, and it is only called -# if there are sufficient criteria to perform the search. -sub run_distance_search { - my $self = shift; - my $x = $self->{x}; - my $y = $self->{y}; - my $dist = $self->{distance_in_metres}; - - my @close = $self->{locator}->find_within_distance( - x => $x, - y => $y, - metres => $dist, - ); - - if ( $self->{results} ) { - my %close_hash = map { $_ => 1 } @close; - my %results = %{ $self->{results} }; - my @candidates = keys %results; - foreach my $node ( @candidates ) { - if ( exists $close_hash{$node} ) { - my $distance = $self->_get_distance( - node => $node, - x => $x, - y => $y, - ); - $results{$node}{distance} = $distance; - } else { - delete $results{$node}; - } - } - $self->{results} = %results; - } else { - my %results; - foreach my $node ( @close ) { - my $distance = $self->_get_distance ( - node => $node, - x => $x, - y => $y, - ); - $results{$node} = { - name => $node, - distance => $distance, - }; - } - $self->{results} = %results; - } - return $self; -} - -sub _get_distance { - my ($self, %args) = @_; - my ($node, $x, $y) = @args{ qw( node x y ) }; - return $self->{locator}->distance( - from_x => $x, - from_y => $y, - to_node => $node, - unit => "metres" - ); -} - -sub process_params { - my ($self, $vars_hashref) = @_; - my %vars = %{ $vars_hashref || {} }; - - # Make sure that we don't have any data left over from previous invocation. - # This is useful for testing purposes at the moment and will be essential - # for mod_perl implementations. - delete $self->{x}; - delete $self->{y}; - delete $self->{distance_in_metres}; - delete $self->{search_string}; - - # Strip out any non-digits from distance and OS co-ords. - foreach my $param ( qw( os_x os_y osie_x osie_y - osie_dist os_dist latlong_dist ) ) { - if ( defined $vars{$param} ) { - $vars{$param} =~ s/[^0-9]//g; - # 0 is an allowed value but the empty string isn't. - delete $vars{$param} if $vars{$param} eq ""; - } - } - - # Latitude and longitude are also allowed '-' and '.' - foreach my $param( qw( latitude longitude ) ) { - if ( defined $vars{$param} ) { - $vars{$param} =~ s/[^-.0-9]//g; - # 0 is an allowed value but the empty string isn't. - delete $vars{$param} if $vars{$param} eq ""; - } - } - - # Set $self->{distance_in_metres}, $self->{x}, $self->{y}, - # depending on whether we got - # OS co-ords or lat/long. Only store parameters if they're complete, - # and supported by our method of distance calculation. - if ( defined $vars{os_x} && defined $vars{os_y} && defined $vars{os_dist} - && $self->config->geo_handler eq 1 ) { - $self->{x} = $vars{os_x}; - $self->{y} = $vars{os_y}; - $self->{distance_in_metres} = $vars{os_dist}; - } elsif ( defined $vars{osie_x} && defined $vars{osie_y} - && defined $vars{osie_dist} - && $self->config->geo_handler eq 2 ) { - $self->{x} = $vars{osie_x}; - $self->{y} = $vars{osie_y}; - $self->{distance_in_metres} = $vars{osie_dist}; - } elsif ( defined $vars{latitude} && defined $vars{longitude} - && defined $vars{latlong_dist} ) { - # All handlers can do lat/long, but they all do it differently. - if ( $self->config->geo_handler eq 1 ) { - require Geography::NationalGrid::GB; - my $point = Geography::NationalGrid::GB->new( - Latitude => $vars{latitude}, - Longitude => $vars{longitude}, - ); - $self->{x} = $point->easting; - $self->{y} = $point->northing; - } elsif ( $self->config->geo_handler eq 2 ) { - require Geography::NationalGrid::IE; - my $point = Geography::NationalGrid::IE->new( - Latitude => $vars{latitude}, - Longitude => $vars{longitude}, - ); - $self->{x} = $point->easting; - $self->{y} = $point->northing; - } elsif ( $self->config->geo_handler eq 3 ) { - require Geo::Coordinates::UTM; - my ($zone, $x, $y) = Geo::Coordinates::UTM::latlon_to_utm( - $self->config->ellipsoid, - $vars{latitude}, - $vars{longitude}, - ); - $self->{x} = $x; - $self->{y} = $y; - } - $self->{distance_in_metres} = $vars{latlong_dist}; - } - - # Store os_x etc so we can pass them to template. - foreach my $param ( qw( os_x os_y osie_x osie_y latitude longitude ) ) { - $self->{$param} = $vars{$param}; - } - - # Strip leading and trailing whitespace from search text. - $vars{search} ||= ""; # avoid uninitialised value warning - $vars{search} =~ s/^\s*//; - $vars{search} =~ s/\s*$//; - - # Check for only valid characters in tainted search param - # (quoted literals are OK, as they are escaped) - # This regex copied verbatim from Ivor's old supersearch. - if ( $vars{search} - && $vars{search} !~ /^("[^"]*"|[\w -',()!*%[]])+$/i) { - $self->{error} = "Search expression $vars{search} contains invalid character(s)"; - return $self; - } - $self->{search_string} = $vars{search}; - - return $self; -} - -# thin wrapper around OpenGuides::Template -sub process_template { - my ($self, %args) = @_; - - my $tt_vars = $args{tt_vars} || {}; - $tt_vars->{not_editable} = 1; - $tt_vars->{not_deletable} = 1; - return %$tt_vars if $self->{return_tt_vars}; - my $output = OpenGuides::Template->output( - wiki => $self->wiki, - config => $self->config, - template => "supersearch.tt", - vars => $tt_vars, - ); - return $output if $self->{return_output}; - - print $output; - return 1; -} - -=head1 OUTPUT - -Results will be put into some form of relevance ordering. These are -the rules we have tests for so far (and hence the only rules that can -be relied on): - -=over - -=item * - -A match on page title will score higher than a match on page category -or locale. - -=item * - -A match on page category or locale will score higher than a match on -page content. - -=item * - -Two matches in the title beats one match in the title and one in the content. - -=back - -=cut - -=head1 AUTHOR - -The OpenGuides Project (openguides-dev@openguides.org) - -=head1 COPYRIGHT - - Copyright (C) 2003-2004 The OpenGuides Project. All Rights Reserved. - -The OpenGuides distribution is free software; you can redistribute it -and/or modify it under the same terms as Perl itself. - -=head1 SEE ALSO - -L<OpenGuides> - -=cut - -1;
Copied: trunk/search.cgi (from rev 715, trunk/supersearch.cgi) =================================================================== --- trunk/supersearch.cgi 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/search.cgi 2005-11-24 20:01:09 UTC (rev 716) @@ -0,0 +1,14 @@ +#!/usr/local/bin/perl + +use warnings; +use strict; + +use CGI; +use OpenGuides::Config; +use OpenGuides::Search; + +my $config_file = $ENV{OPENGUIDES_CONFIG_FILE} || "wiki.conf"; +my $config = OpenGuides::Config->new( file => $config_file ); +my $search = OpenGuides::Search->new( config => $config ); +my %vars = CGI::Vars(); +$search->run( vars => %vars );
Deleted: trunk/supersearch.cgi =================================================================== --- trunk/supersearch.cgi 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/supersearch.cgi 2005-11-24 20:01:09 UTC (rev 716) @@ -1,14 +0,0 @@ -#!/usr/local/bin/perl - -use warnings; -use strict; - -use CGI; -use OpenGuides::Config; -use OpenGuides::SuperSearch; - -my $config_file = $ENV{OPENGUIDES_CONFIG_FILE} || "wiki.conf"; -my $config = OpenGuides::Config->new( file => $config_file ); -my $search = OpenGuides::SuperSearch->new( config => $config ); -my %vars = CGI::Vars(); -$search->run( vars => %vars );
Modified: trunk/t/01_load.t =================================================================== --- trunk/t/01_load.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/01_load.t 2005-11-24 20:01:09 UTC (rev 716) @@ -4,6 +4,6 @@ use_ok( "OpenGuides::CGI" ); use_ok( "OpenGuides::Config" ); use_ok( "OpenGuides::RDF" ); -use_ok( "OpenGuides::SuperSearch" ); +use_ok( "OpenGuides::Search" ); use_ok( "OpenGuides::Template" ); use_ok( "OpenGuides::Utils" );
Copied: trunk/t/31_search.t (from rev 715, trunk/t/31_supersearch.t)
Deleted: trunk/t/31_supersearch.t =================================================================== --- trunk/t/31_supersearch.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/31_supersearch.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,154 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::SuperSearch; -use OpenGuides::Test; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} else { - plan tests => 18; - - # Clear out the database from any previous runs. - unlink "t/node.db"; - unlink <t/indexes/*>; - - CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); - my $config = OpenGuides::Test->make_basic_config; - $config->script_name( "wiki.cgi" ); - $config->script_url( "http://example.com/" ); - - # Plucene is the recommended searcher now. - eval { require CGI::Wiki::Search::Plucene; }; - if ( $@ ) { $config->use_plucene( 0 ) }; - - my $search = OpenGuides::SuperSearch->new( config => $config ); - isa_ok( $search, "OpenGuides::SuperSearch" ); - - my $output = $search->run( return_output => 1 ); - unlike( $output, qr/no items matched/i, - "doesn't output 'no items matched' if no terms supplied" ); - unlike( $output, qr/action=edit/, - "doesn't offer edit link" ); - - my %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "banana" }, - ); - is( $tt_vars{first_num}, 0, "first_num set to 0 when no hits" ); - is( scalar @{ $tt_vars{results} }, 0, "...and results array empty" ); - - $output = $search->run( - return_output => 1, - vars => { search => "banana" } - ); - like( $output, qr/no items matched/i, - "outputs 'no items matched' if term not found" ); - unlike( $output, qr/matches found, showing/i, - "doesn't output 'matches found, showing' if term not found" ); - - # Pop some data in and search again. - my $wiki = $search->{wiki}; # white boxiness - $wiki->write_node( "Banana", "banana" ); - $wiki->write_node( "Monkey", "banana brains" ); - $wiki->write_node( "Monkey Brains", "BRANES" ); - $wiki->write_node( "Want Pie Now", "weebl" ); - $wiki->write_node( "Punctuation", "*" ); - $wiki->write_node( "Choice", "Eenie meenie minie mo"); - - # Test with two hits first - simpler. - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "banana" }, - ); - my @found = map { $_->{name} } @{ $tt_vars{results} || [] }; - is( scalar @found, 2, "search finds single word twice" ); - is_deeply( [ sort @found ], [ "Banana", "Monkey" ], - "...in the right places" ); - print "# Found in $_\n" foreach @found; - - # Make sure that $output matches too - we're testing the template here. - $output = $search->run( - return_output => 1, - vars => { search => "banana" }, - ); - like( $output, qr/<a href="http:\/\/example.com\/wiki.cgi\?Banana">/, - "...and link is included in template output" ); - - # One hit in body only should show result list. - $output = $search->run( - return_output => 1, - vars => { search => "weebl" }, - ); - unlike( $output, qr/Status: 302 Moved/, - "no redirect if match only in body"); - - # One hit in title should redirect to that page. - $output = $search->run( - return_output => 1, - vars => { search => "want pie now" }, - ); - like( $output, qr/Status: 302 Moved/, - "prints redirect on single hit and match in title" ); - # Old versions of CGI.pm mistakenly print location: instead of Location: - like( $output, - qr/[lL]ocation: http://example.com/wiki.cgi?Want_Pie_Now/, - "...and node name munged correctly in URL" ); - - # Test the AND search - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "monkey banana" }, - ); - @found = map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Monkey" ], "AND search returns right results" ); - - # Test the OR search - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "brains, pie" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Monkey", "Monkey Brains", "Want Pie Now" ], - "OR search returns right results" ); - print "# Found in $_\n" foreach @found; - - SKIP: { - skip "NOT search not done yet", 1; - # Test the NOT search - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "banana -monkey" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Banana" ], "NOT search returns right results" ); - } # end of SKIP - - # Test the phrase search - $output = $search->run( - return_output => 1, - vars => { search => '"monkey brains"' }, - ); - like( $output, - qr/[lL]ocation: http://example.com/wiki.cgi?Monkey_Brains/, - "phrase search returns right results and redirects to page" - ); - - ##### - ##### Test numbering when we have more than a page of results. - ##### - - foreach my $i ( 1 .. 30 ) { - $wiki->write_node( "Node $i", "wombat" ) or die "Can't write Node $i"; - } - $output = $search->run( - return_output => 1, - vars => { - search => "wombat", - next => 20, - }, - ); - like( $output, qr/ol start="21"/, - "second page of results starts with right numbering" ); -}
Copied: trunk/t/32_search_simple_metadata.t (from rev 715, trunk/t/32_supersearch_simple_metadata.t)
Deleted: trunk/t/32_supersearch_simple_metadata.t =================================================================== --- trunk/t/32_supersearch_simple_metadata.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/32_supersearch_simple_metadata.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,129 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use Test::More tests => 10; - -eval { require DBD::SQLite; }; -my $have_sqlite = $@ ? 0 : 1; - -SKIP: { - skip "DBD::SQLite not installed - no database to test with", 10 - unless $have_sqlite; - - # Clear out the database from any previous runs. - unlink "t/node.db"; - unlink <t/indexes/*>; - - CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); - my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - } - ); - - # Plucene is the recommended searcher now. - eval { require CGI::Wiki::Search::Plucene; }; - if ( $@ ) { $config->use_plucene( 0 ) }; - - my $search = OpenGuides::SuperSearch->new( config => $config ); - - # Add some data. We write it twice to avoid hitting the redirect. - my $wiki = $search->{wiki}; # white boxiness - $wiki->write_node( "Calthorpe Arms", "Serves beer.", undef, - { category => "Pubs", locale => "Holborn" } ); - $wiki->write_node( "Penderel's Oak", "Serves beer.", undef, - { category => "Pubs", locale => "Holborn" } ); - $wiki->write_node( "British Museum", "Huge museum, lots of artifacts.", undef, - { category => ["Museums", "Major Attractions"] - , locale => ["Holborn", "Bloomsbury"] } ); - - # Check that a search on its category works. - my %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Pubs" }, - ); - my @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Calthorpe Arms", "Penderel's Oak" ], - "simple search looks in category" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "pubs" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Calthorpe Arms", "Penderel's Oak" ], - "...and is case-insensitive" ); - - # Check that a search on its locale works. - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Holborn" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "British Museum", "Calthorpe Arms", "Penderel's Oak" ], - "simple search looks in locale" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "holborn" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "British Museum", "Calthorpe Arms", "Penderel's Oak" ], - "...and is case-insensitive" ); - - # Test AND search in various combinations. - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Holborn Pubs" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Calthorpe Arms", "Penderel's Oak" ], - "AND search works between category and locale" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Holborn Penderel" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Penderel's Oak" ], - "AND search works between title and locale" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Pubs Penderel" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Penderel's Oak" ], - "AND search works between title and category" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Holborn beer" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Calthorpe Arms", "Penderel's Oak" ], - "...and between body and locale" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "Pubs beer" }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "Calthorpe Arms", "Penderel's Oak" ], - "...and between body and category" ); - - %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => '"major attractions"' }, - ); - @found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; - is_deeply( @found, [ "British Museum", ], - "Multi word category name" ); -}
Copied: trunk/t/33_search_advanced_search.t (from rev 715, trunk/t/33_supersearch_advanced_search.t)
Copied: trunk/t/33_search_advanced_search_utm.t (from rev 715, trunk/t/33_supersearch_advanced_search_utm.t)
Deleted: trunk/t/33_supersearch_advanced_search.t =================================================================== --- trunk/t/33_supersearch_advanced_search.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/33_supersearch_advanced_search.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,182 +0,0 @@ -use strict; -use CGI::Wiki::Plugin::Locator::Grid; # use directly to help debug -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use OpenGuides::Test; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} - -eval { require Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; -} - -eval { require Geography::NationalGrid::GB; }; -if ( $@ ) { - plan skip_all => "Geography::NationalGrid::GB not installed"; -} - -plan tests => 8; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); - -my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - use_plucene => 1, - geo_handler => 1, - } -); -my $search = OpenGuides::SuperSearch->new( config => $config ); -my $guide = OpenGuides->new( config => $config ); - -# Write some data. -OpenGuides::Test->write_data( - guide => $guide, - node => "Crabtree Tavern", - os_x => 523465, - os_y => 177490, - categories => "Pubs", - ); - -OpenGuides::Test->write_data( - guide => $guide, - node => "Blue Anchor", - os_x => 522909, - os_y => 178232, - categories => "Pubs", - ); - -OpenGuides::Test->write_data( - guide => $guide, - node => "Star Tavern", - os_x => 528107, - os_y => 179347, - categories => "Pubs", - ); - -OpenGuides::Test->write_data( - guide => $guide, - node => "Hammersmith Bridge", - os_x => 522983, - os_y => 178118, - ); - -# Sanity check. -print "# Distances should be:\n"; -my $locator = CGI::Wiki::Plugin::Locator::Grid->new(x => "os_x", y => "os_y"); -my $wiki = $guide->wiki; -$wiki->register_plugin( plugin => $locator ); -foreach my $node ( "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge"){ - print "# $node: " . $locator->distance( from_x => 523450, - from_y => 177650, - to_node => $node ) . "\n"; -} - -# Check that a lat/long distance search finds them. -my %tt_vars = $search->run( - return_tt_vars => 1, - vars => { - latitude => 51.484320, - longitude => -0.223484, - latlong_dist => 1000, - }, - ); -my @ordered = map { $_->{name} } @{ $tt_vars{results} || [] }; -my @found = sort @ordered; -is_deeply( @found, - [ "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge" ], - "distance search finds the right things" ); -is_deeply( @ordered, - [ "Crabtree Tavern", "Hammersmith Bridge", "Blue Anchor" ], - "...and returns them in the right order" ); - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { - latitude => 51.484320, - longitude => -0.223484, - latlong_dist => 1000, - search => " ", - }, - ); -@ordered = map { $_->{name} } @{ $tt_vars{results} || [] }; -@found = sort @ordered; -is_deeply( @found, - [ "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge" ], - "...still works if whitespace-only search text supplied" ); - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { - os_x => 523450, - os_y => 177650, - os_dist => 1000, - search => " ", - }, - ); -@ordered = map { $_->{name} } @{ $tt_vars{results} || [] }; -@found = sort @ordered; -is_deeply( @found, - [ "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge" ], - "...works with OS co-ords" ); - -%tt_vars = eval { - $search->run( - return_tt_vars => 1, - vars => { - os_x => 523450, - os_y => 177650, - os_dist => 1000, - search => " ", - latitude => " ", - longitude => " ", - }, - ); -}; -is( $@, "", "...works with OS co-ords and whitespace-only lat/long" ); -@ordered = map { $_->{name} } @{ $tt_vars{results} || [] }; -@found = sort @ordered; -is_deeply( @found, - [ "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge" ], - "...returns the right stuff" ); - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { - latitude => 51.484320, - longitude => -0.223484, - latlong_dist => 1000, - search => "pubs", - }, - ); -@found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; -is_deeply( @found, [ "Blue Anchor", "Crabtree Tavern", ], - "distance search in combination with text search works" ); - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { - os_x => 523450, - os_y => 177650, - os_dist => 1000, - search => "pubs", - }, - ); -@found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; -is_deeply( @found, [ "Blue Anchor", "Crabtree Tavern", ], - "...works with OS co-ords too" );
Deleted: trunk/t/33_supersearch_advanced_search_utm.t =================================================================== --- trunk/t/33_supersearch_advanced_search_utm.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/33_supersearch_advanced_search_utm.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,132 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use OpenGuides::Test; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} - -eval { require Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; -} - -eval { require Geo::Coordinates::UTM; }; -if ( $@ ) { - plan skip_all => "Geo::Coordinates::UTM not installed"; -} - -plan tests => 4; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); - -my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - use_plucene => 1, - geo_handler => 3, - ellipsoid => "Airy", - } -); -my $search = OpenGuides::SuperSearch->new( config => $config ); -my $guide = OpenGuides->new( config => $config ); - -# Write some data. -OpenGuides::Test->write_data( - guide => $guide, - node => "Crabtree Tavern", - latitude => 51.482385, - longitude => -0.221743, - categories => "Pubs", - ); - -OpenGuides::Test->write_data( - guide => $guide, - node => "Blue Anchor", - latitude => 51.489176, - longitude => -0.229488, - categories => "Pubs", - ); - -OpenGuides::Test->write_data( - guide => $guide, - node => "Star Tavern", - latitude => 51.498043, - longitude => -0.154247, - categories => "Pubs", - ); - -OpenGuides::Test->write_data( - guide => $guide, - node => "Hammersmith Bridge", - latitude => 51.488135, - longitude => -0.228463, - ); - -# Sanity check. -print "# Distances should be round about:\n"; -my $locator = $guide->locator; -foreach my $node ( "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge"){ - print "# $node: " . $locator->distance( from_x => 692756, - from_y => 5706917, - to_node => $node ) . "\n"; -} - -# Check that a lat/long distance search finds them. -my %tt_vars = $search->run( - return_tt_vars => 1, - vars => { - latitude => 51.484320, - longitude => -0.223484, - latlong_dist => 1000, - }, - ); -my @ordered = map { $_->{name} } @{ $tt_vars{results} || [] }; -my @found = sort @ordered; -is_deeply( @found, - [ "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge" ], - "distance search finds the right things" ); -is_deeply( @ordered, - [ "Crabtree Tavern", "Hammersmith Bridge", "Blue Anchor" ], - "...and returns them in the right order" ); - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { - latitude => 51.484320, - longitude => -0.223484, - latlong_dist => 1000, - search => " ", - }, - ); -@ordered = map { $_->{name} } @{ $tt_vars{results} || [] }; -@found = sort @ordered; -is_deeply( @found, - [ "Blue Anchor", "Crabtree Tavern", "Hammersmith Bridge" ], - "...still works if whitespace-only search text supplied" ); - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { - latitude => 51.484320, - longitude => -0.223484, - latlong_dist => 1000, - search => "pubs", - }, - ); -@found = sort map { $_->{name} } @{ $tt_vars{results} || [] }; -is_deeply( @found, [ "Blue Anchor", "Crabtree Tavern", ], - "distance search in combination with text search works" );
Copied: trunk/t/34_search_paging.t (from rev 715, trunk/t/34_supersearch_paging.t)
Deleted: trunk/t/34_supersearch_paging.t =================================================================== --- trunk/t/34_supersearch_paging.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/34_supersearch_paging.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,130 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use OpenGuides::Test; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} - -eval { require Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; -} - -plan tests => 9; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); - -my $config = OpenGuides::Test->make_basic_config; -$config->use_plucene( 1 ); -my $search = OpenGuides::SuperSearch->new( config => $config ); -my $guide = OpenGuides->new( config => $config ); - -# Test with OS co-ords. -eval { require Geography::NationalGrid::GB; }; -SKIP: { - skip "Geography::NationalGrid::GB not installed", 3 if $@; - $config->geo_handler( 1 ); - - foreach my $i ( 1 .. 30 ) { - OpenGuides::Test->write_data( - guide => $guide, - node => "Crabtree Tavern $i", - os_x => 523465, - os_y => 177490, - categories => "Pubs", - ); - } - - my $output = $search->run( - return_output => 1, - vars => { - os_dist => 1500, - os_x => 523500, - os_y => 177500, - }, - ); - like( $output, qr/supersearch.cgi?.*os_x=523500.*Next.*results/s, - "os_x retained in next page link" ); - like( $output, qr/supersearch.cgi?.*os_y=177500.*Next.*results/s, - "os_y retained in next page link" ); - like( $output, qr/supersearch.cgi?.*os_dist=1500.*Next.*results/s, - "os_dist retained in next page link" ); -} - -# Test with OSIE co-ords. -eval { require Geography::NationalGrid::IE; }; -SKIP: { - skip "Geography::NationalGrid::IE not installed", 3 if $@; - - # We must create a new search object after changing the geo_handler - # in order to force it to create a fresh locator. - $config->geo_handler( 2 ); - my $search = OpenGuides::SuperSearch->new( config => $config ); - - foreach my $i ( 1 .. 30 ) { - OpenGuides::Test->write_data( - guide => $guide, - node => "I Made This Place Up $i", - osie_x => 100005, - osie_y => 200005, - ); - } - - my $output = $search->run( - return_output => 1, - vars => { - osie_dist => 1500, - osie_x => 100000, - osie_y => 200000, - }, - ); - like( $output, qr/supersearch.cgi?.*osie_x=100000.*Next.*results/s, - "osie_x retained in next page link" ); - like( $output, qr/supersearch.cgi?.*osie_y=200000.*Next.*results/s, - "osie_y retained in next page link" ); - like( $output, qr/supersearch.cgi?.*osie_dist=1500.*Next.*results/s, - "osie_dist retained in next page link" ); -} - -# Test with UTM. -eval { require Geo::Coordinates::UTM; }; -SKIP: { - skip "Geo::Coordinates::UTM not installed", 3 if $@; - - # We must create a new search object after changing the geo_handler - # in order to force it to create a fresh locator. - $config->geo_handler( 3 ); - my $search = OpenGuides::SuperSearch->new( config => $config ); - - foreach my $i ( 1 .. 30 ) { - OpenGuides::Test->write_data( - guide => $guide, - node => "London Aquarium $i", - latitude => 51.502, - longitude => -0.118, - ); - } - - my $output = $search->run( - return_output => 1, - vars => { - latlong_dist => 1500, - latitude => 51.5, - longitude => -0.12, - }, - ); - like( $output, qr/supersearch.cgi?.*latitude=51.5.*Next.*results/s, - "latitude retained in next page link" ); - like( $output, qr/supersearch.cgi?.*longitude=-0.12.*Next.*results/s, - "longitude retained in next page link" ); - like( $output, qr/supersearch.cgi?.*latlong_dist=1500.*Next.*results/s, - "latlong_dist retained in next page link" ); -}
Copied: trunk/t/35_search_two_searches.t (from rev 715, trunk/t/35_supersearch_two_searches.t)
Deleted: trunk/t/35_supersearch_two_searches.t =================================================================== --- trunk/t/35_supersearch_two_searches.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/35_supersearch_two_searches.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,135 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} - -eval { require Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; -} - -# Strictly speaking we don't need to skip _all_ tests if we don't have -# the modules below. Revisit this when not in a hurry. -# We only actually need the former for the National Grid tests and the -# latter for the UTM tests. -eval { require Geography::NationalGrid; }; -if ( $@ ) { - plan skip_all => "Geography::NationalGrid not installed"; -} - -eval { require Geo::Coordinates::UTM; }; -if ( $@ ) { - plan skip_all => "Geo::Coordinates::UTM not installed"; -} - -plan tests => 10; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; - -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); -my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - geo_handler => 1, - } -); - -# Plucene is the recommended searcher now. -eval { require CGI::Wiki::Search::Plucene; }; -if ( $@ ) { $config->use_plucene( 0 ) }; - -my $search = OpenGuides::SuperSearch->new( config => $config ); - -# Write some data. -my $wiki = $search->{wiki}; -$wiki->write_node( "Wandsworth Common", "A common.", undef, - { category => "Parks" } ) - or die "Can't write node"; -$wiki->write_node( "Hammersmith", "A page about Hammersmith." ) - or die "Can't write node"; - -# Check that the search forgets input search term between invocations. -$search->run( - return_output => 1, - vars => { search => "parks" }, - ); -ok( $search->{search_string}, "search_string set" ); -$search->run( - return_output => 1, - ); -ok( !$search->{search_string}, "...and forgotten" ); - -# Sanity check. -my (@results, %tt_vars); -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "parks" }, - ); -@results = sort map { $_->{name} } @{ $tt_vars{results} || [] }; -is_deeply( @results, [ "Wandsworth Common" ], - "first search returns expected results" ); -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "hammersmith" }, - ); -@results = sort map { $_->{name} } @{ $tt_vars{results} || [] }; -is_deeply( @results, [ "Hammersmith" ], - "so does second" ); - -# Check that the search forgets input geodata between invocations. -# First with British National Grid. -$search->run( - return_output => 1, - vars => { os_x => 500000, os_y => 100000, os_dist => 1000 }, - ); -ok( $search->{x}, "x-coord set" ); -$search->run( - return_output => 1, - vars => { search => "foo" }, - ); -ok( !$search->{x}, "...and forgotten" ); - -# Now with Irish National Grid. -$config->geo_handler( 2 ); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( - return_output => 1, - vars => { osie_x => 100000, osie_y => 200000, osie_dist => 100 }, - ); -ok( $search->{x}, "x-coord set" ); -$search->run( - return_output => 1, - vars => { search => "foo" }, - ); -ok( !$search->{x}, "...and forgotten" ); - -# Now with UTM. -$config->geo_handler( 3 ); -$config->ellipsoid( "Airy" ); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( - return_output => 1, - vars => { latitude => 10, longitude => 0, latlong_dist => 1000 }, - ); -ok( $search->{x}, "x-coord set" ); -$search->run( - return_output => 1, - vars => { search => "foo" }, - ); -ok( !$search->{x}, "...and forgotten" ); - -
Copied: trunk/t/36_search_order.t (from rev 715, trunk/t/36_supersearch_order.t)
Deleted: trunk/t/36_supersearch_order.t =================================================================== --- trunk/t/36_supersearch_order.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/36_supersearch_order.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,141 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; - exit 0; -} - -eval { require CGI::Wiki::Search::Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; - exit 0; -} - -plan tests => 9; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; - -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); -my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - use_plucene => 1 - } -); - -my $search = OpenGuides::SuperSearch->new( config => $config ); -isa_ok( $search, "OpenGuides::SuperSearch" ); - -# Write some data. -my $wiki = $search->{wiki}; -$wiki->write_node( "Parks", "A page about parks." ) - or die "Can't write node"; -$wiki->write_node( "Wandsworth Common", "A common.", undef, - { category => "Parks" } ) - or die "Can't write node"; -$wiki->write_node( "Kake", "I like walking in parks." ) - or die "Can't write node"; - -my %tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "parks" }, - ); -foreach my $result ( @{ $tt_vars{results} || [] } ) { - print "# $result->{name} scores $result->{score}\n"; -} -my %scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []}; -ok( $scores{Kake} < $scores{'Wandsworth Common'}, - "content match scores less than category match" ); -ok( $scores{'Wandsworth Common'} < $scores{Parks}, - "title match scores more than category match" ); - -# Now test locales. -$wiki->write_node( "Hammersmith", "A page about Hammersmith." ) - or die "Can't write node"; -$wiki->write_node( "The Gate", "A restaurant.", undef, - { locale => "Hammersmith" } ) - or die "Can't write node"; -$wiki->write_node( "Kake Pugh", "I live in Hammersmith." ) - or die "Can't write node"; - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "hammersmith" }, - ); -foreach my $result ( @{ $tt_vars{results} || [] } ) { - print "# $result->{name} scores $result->{score}\n"; -} -%scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []}; -ok( $scores{'Kake Pugh'} < $scores{'The Gate'}, - "content match scores less than locale match" ); -ok( $scores{'The Gate'} < $scores{Hammersmith}, - "locale match scores less than title match" ); - -# Check that two words in the title beats one in the title and -# one in the content. -$wiki->write_node( "Putney Tandoori", "Indian food" ) - or die "Couldn't write node"; -$wiki->write_node( "Putney", "There is a tandoori restaurant here" ) - or die "Couldn't write node"; - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "putney tandoori" }, - ); -foreach my $result ( @{ $tt_vars{results} || [] } ) { - print "# $result->{name} scores $result->{score}\n"; -} -%scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []}; -ok( $scores{Putney} < $scores{'Putney Tandoori'}, - "two words in title beats one in title and one in content" ); - -SKIP: { - skip "Word proximity not yet taken into account", 1; -# Check that in an AND match words closer together get higher priority. -$wiki->write_node( "Spitalfields Market", - "Mango juice from the Indian stall" ) - or die "Can't write node"; -$wiki->write_node( "Borough Market", "dried mango and real apple juice" ) - or die "Can't write node"; - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "mango juice" }, - ); -foreach my $result ( @{ $tt_vars{results} || [] } ) { - print "# $result->{name} scores $result->{score}\n"; -} -%scores = map { $_->{name} => $_->{score} } @{$tt_vars{results} || []}; -ok( $scores{'Borough Market'} < $scores{'Spitalfields Market'}, - "words closer together gives higher score" ); -} # end of SKIP - -# Check that the number of occurrences of the search term is significant. - -$wiki->write_node( "Pub Crawls", "The basic premise of the pub crawl is to visit a succession of pubs, rather than spending the entire evening or day in a single establishment. London offers an excellent choice of themes for your pub crawl.", undef, { category => "Pubs" } ) or die "Can't write node"; -$wiki->write_node( "The Pub", "A pub.", undef, { category => "Pubs" } ) or die "Can't write node"; - -%tt_vars = $search->run( - return_tt_vars => 1, - vars => { search => "pub" } - ); -foreach my $result ( @{ $tt_vars{results} || [] } ) { - print "# $result->{name} scores $result->{score}\n"; -} -is( $tt_vars{results}[0]{name}, "Pub Crawls", - "node with two mentions of search term comes top" ); -ok( $tt_vars{results}[0]{score} > $tt_vars{results}[1]{score}, - "...with a score strictly greater than node with one mention" );
Copied: trunk/t/37_search_summaries.t (from rev 715, trunk/t/37_supersearch_summaries.t)
Deleted: trunk/t/37_supersearch_summaries.t =================================================================== --- trunk/t/37_supersearch_summaries.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/37_supersearch_summaries.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,48 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} else { - plan tests => 2; - - # Clear out the database from any previous runs. - unlink "t/node.db"; - unlink <t/indexes/*>; - - CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); - my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - } - ); - - # Plucene is the recommended searcher now. - eval { require CGI::Wiki::Search::Plucene; }; - if ( $@ ) { $config->use_plucene( 0 ) }; - - my $search = OpenGuides::SuperSearch->new( config => $config ); - isa_ok( $search, "OpenGuides::SuperSearch" ); - my $wiki = $search->wiki; - $wiki->write_node( "Pub Crawls", "The basic premise of the pub crawl is to visit a succession of pubs, rather than spending the entire evening or day in a single establishment. London offers an excellent choice of themes for your pub crawl.", undef, { category => "Pubs" } ) or die "Can't write node"; - - my $output = $search->run( - return_output => 1, - vars => { search => "pub" } - ); - SKIP: { - skip "TODO: summaries", 1; - like( $output, qr|<b>pub</b>|i, - "outputs at least one bolded occurence of 'pub'" ); - } # end of SKIP -}
Copied: trunk/t/38_search_params.t (from rev 715, trunk/t/38_supersearch_params.t)
Deleted: trunk/t/38_supersearch_params.t =================================================================== --- trunk/t/38_supersearch_params.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/38_supersearch_params.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,180 +0,0 @@ -use strict; -use CGI; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::Config; -use OpenGuides::SuperSearch; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; - exit 0; -} - -eval { require CGI::Wiki::Search::Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; - exit 0; -} - -# Strictly speaking we don't need to skip _all_ tests if we don't have -# the modules below. Revisit this when not in a hurry. -# We only actually need them for the tests where lat/long are converted. -eval { require Geography::NationalGrid; }; -if ( $@ ) { - plan skip_all => "Geography::NationalGrid not installed"; -} - -eval { require Geo::Coordinates::UTM; }; -if ( $@ ) { - plan skip_all => "Geo::Coordinates::UTM not installed"; -} - -plan tests => 19; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; - -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); -my $config = OpenGuides::Config->new( - vars => { - dbtype => "sqlite", - dbname => "t/node.db", - indexing_directory => "t/indexes", - script_name => "wiki.cgi", - script_url => "http://example.com/", - site_name => "Test Site", - template_path => "./templates", - use_plucene => 1, - geo_handler => 1, # British National Grid - } -); - -# Check the British National Grid case. -my $q = CGI->new( "" ); -$q->param( -name => "os_x", -value => 500000 ); -$q->param( -name => "os_y", -value => 200000 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -my %vars = $q->Vars(); -my $search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -is( $search->{distance_in_metres}, 500, - "os_dist picked up when OS co-ords given and using British grid" ); -is( $search->{x}, 500000, "...x set from os_x" ); -is( $search->{y}, 200000, "...y set from os_y" ); - -$q = CGI->new( "" ); -$q->param( -name => "osie_x", -value => 500000 ); -$q->param( -name => "osie_y", -value => 200000 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -ok( !defined $search->{distance_in_metres}, - "OSIE co-ords ignored when using British grid" ); - -$q = CGI->new( "" ); -$q->param( -name => "latitude", -value => 51 ); -$q->param( -name => "longitude", -value => 1 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -is( $search->{distance_in_metres}, 700, - "latlong_dist picked up when lat/long given and using British grid" ); -ok( defined $search->{x}, "...x set" ); -ok( defined $search->{y}, "...y set" ); - - -# Check the Irish National Grid case. -$config->geo_handler( 2 ); - -$q = CGI->new( "" ); -$q->param( -name => "osie_x", -value => 500000 ); -$q->param( -name => "osie_y", -value => 200000 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -is( $search->{distance_in_metres}, 600, - "osie_dist picked up when OS co-ords given and using Irish grid" ); -is( $search->{x}, 500000, "...x set from osie_x" ); -is( $search->{y}, 200000, "...y set from osie_y" ); - -$q = CGI->new( "" ); -$q->param( -name => "os_x", -value => 500000 ); -$q->param( -name => "os_y", -value => 200000 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -ok( !defined $search->{distance_in_metres}, - "OS co-ords ignored when using Irish grid" ); - -$q = CGI->new( "" ); -$q->param( -name => "latitude", -value => 55 ); -$q->param( -name => "longitude", -value => -5 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -is( $search->{distance_in_metres}, 700, - "latlong_dist picked up when lat/long given and using Irish grid" ); -ok( defined $search->{x}, "...x set" ); -ok( defined $search->{y}, "...y set" ); - - -# Check the UTM case. -$config->geo_handler( 3 ); -$config->ellipsoid( "Airy" ); - -$q = CGI->new( "" ); -$q->param( -name => "os_x", -value => 500000 ); -$q->param( -name => "os_y", -value => 200000 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -ok( !defined $search->{distance_in_metres}, - "OS co-ords ignored when using UTM" ); - -$q = CGI->new( "" ); -$q->param( -name => "osie_x", -value => 500000 ); -$q->param( -name => "osie_y", -value => 200000 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -ok( !defined $search->{distance_in_metres}, - "OSIE co-ords ignored when using UTM" ); - -$q = CGI->new( "" ); -$q->param( -name => "latitude", -value => 51 ); -$q->param( -name => "longitude", -value => 1 ); -$q->param( -name => "os_dist", -value => 500 ); -$q->param( -name => "osie_dist", -value => 600 ); -$q->param( -name => "latlong_dist", -value => 700 ); -%vars = $q->Vars(); -$search = OpenGuides::SuperSearch->new( config => $config ); -$search->run( vars => %vars, return_output => 1 ); -is( $search->{distance_in_metres}, 700, - "latlong_dist picked up when lat/long given and using UTM" ); -ok( defined $search->{x}, "...x set" ); -ok( defined $search->{y}, "...y set" );
Copied: trunk/t/39_search_form.t (from rev 715, trunk/t/39_supersearch_form.t)
Deleted: trunk/t/39_supersearch_form.t =================================================================== --- trunk/t/39_supersearch_form.t 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/t/39_supersearch_form.t 2005-11-24 20:01:09 UTC (rev 716) @@ -1,121 +0,0 @@ -use strict; -use CGI::Wiki::Setup::SQLite; -use OpenGuides::SuperSearch; -use OpenGuides::Test; -use Test::More; - -eval { require DBD::SQLite; }; -if ( $@ ) { - plan skip_all => "DBD::SQLite not installed"; -} - -eval { require Plucene; }; -if ( $@ ) { - plan skip_all => "Plucene not installed"; -} - -eval { require Test::HTML::Content; }; -if ( $@ ) { - plan skip_all => "Test::HTML::Content not installed"; - exit 0; -} - -# Strictly speaking we don't need to skip _all_ tests if we don't have -# the modules below. Revisit this when not in a hurry. -# We only actually need the former for the National Grid tests and the -# latter for the UTM tests. -eval { require Geography::NationalGrid; }; -if ( $@ ) { - plan skip_all => "Geography::NationalGrid not installed"; -} - -eval { require Geo::Coordinates::UTM; }; -if ( $@ ) { - plan skip_all => "Geo::Coordinates::UTM not installed"; -} - -plan tests => 27; - -# Clear out the database from any previous runs. -unlink "t/node.db"; -unlink <t/indexes/*>; - -CGI::Wiki::Setup::SQLite::setup( { dbname => "t/node.db" } ); -my $config = OpenGuides::Test->make_basic_config; -$config->use_plucene( 1 ); - -# British National Grid guides should have os and latlong search fields. -my $search = OpenGuides::SuperSearch->new( config => $config ); -my $output = $search->run( return_output => 1 ); -# Strip Content-Type header to stop Test::HTML::Content getting confused. -$output =~ s/^Content-Type.*[\r\n]+//m; - -Test::HTML::Content::tag_ok( $output, "input", { name => "os_dist" }, - "search page includes os_dist input with BNG" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "os_x" }, - "...and os_x" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "os_y" }, - "...and os_y" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "latlong_dist" }, - "...and latlong_dist" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "latitude" }, - "...and latitude" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "longitude" }, - "...and longitude" ); -Test::HTML::Content::no_tag( $output, "input", { name => "osie_dist" }, - "...but not osie_dist" ); -Test::HTML::Content::no_tag( $output, "input", { name => "osie_x" }, - "...nor osie_x" ); -Test::HTML::Content::no_tag( $output, "input", { name => "osie_y" }, - "...nor osie_y" ); - -# Irish National Grid guides should have osie and latlong. -$config->geo_handler( 2 ); -$search = OpenGuides::SuperSearch->new( config => $config ); -$output = $search->run( return_output => 1 ); -$output =~ s/^Content-Type.*[\r\n]+//m; - -Test::HTML::Content::tag_ok( $output, "input", { name => "osie_dist" }, - "search page includes os_dist input with ING" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "osie_x" }, - "...and osie_x" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "osie_y" }, - "...and osie_y" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "latlong_dist" }, - "...and latlong_dist" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "latitude" }, - "...and latitude" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "longitude" }, - "...and longitude" ); -Test::HTML::Content::no_tag( $output, "input", { name => "os_dist" }, - "...but not os_dist" ); -Test::HTML::Content::no_tag( $output, "input", { name => "os_x" }, - "...nor os_x" ); -Test::HTML::Content::no_tag( $output, "input", { name => "os_y" }, - "...nor os_y" ); - -# UTM guides should have latitude/longitude/latlong_dist only. -$config->geo_handler( 3 ); -$config->ellipsoid( "Airy" ); -$search = OpenGuides::SuperSearch->new( config => $config ); -$output = $search->run( return_output => 1 ); -$output =~ s/^Content-Type.*[\r\n]+//m; - -Test::HTML::Content::tag_ok( $output, "input", { name => "latlong_dist" }, - "includes latlong_dist with UTM" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "latitude" }, - "...and latitude" ); -Test::HTML::Content::tag_ok( $output, "input", { name => "longitude" }, - "...and longitude" ); -Test::HTML::Content::no_tag( $output, "input", { name => "os_dist" }, - "...but not os_dist" ); -Test::HTML::Content::no_tag( $output, "input", { name => "os_x" }, - "...nor os_x" ); -Test::HTML::Content::no_tag( $output, "input", { name => "os_y" }, - "...nor os_y" ); -Test::HTML::Content::no_tag( $output, "input", { name => "osie_x" }, - "...but not osie_x" ); -Test::HTML::Content::no_tag( $output, "input", { name => "osie_y" }, - "...nor osie_y" ); -Test::HTML::Content::no_tag( $output, "input", { name => "osie_dist" }, - "...nor osie_dist" );
Modified: trunk/templates/differences.tt =================================================================== --- trunk/templates/differences.tt 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/templates/differences.tt 2005-11-24 20:01:09 UTC (rev 716) @@ -32,7 +32,7 @@ <a href="[% cgi_url %]?action=list_all_versions;id=[% node_param %]">List all versions</a><br />
<p> -<form action="supersearch.cgi" method="get"> +<form action="search.cgi" method="get"> <input type="text" size="50" name="search" /> <input type="submit" name="Go" value="Search" class="form_button" /> </form>
Modified: trunk/templates/footer.tt =================================================================== --- trunk/templates/footer.tt 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/templates/footer.tt 2005-11-24 20:01:09 UTC (rev 716) @@ -1,7 +1,7 @@ <br clear="all" />
<div id="search_form"> - <form action="supersearch.cgi" method="get"> + <form action="search.cgi" method="get"> <strong><label for="search">Search [% site_name %]:</label></strong> <input type="text" size="50" name="search" id="search" value="Search text" onclick="this.value=''" /> <input type="submit" name="Go" value="Go" id="go" class="form_button" /> </form>
Modified: trunk/templates/navbar.tt =================================================================== --- trunk/templates/navbar.tt 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/templates/navbar.tt 2005-11-24 20:01:09 UTC (rev 716) @@ -41,13 +41,13 @@
<ul> <li> - <form method="post" action="supersearch.cgi" enctype="application/x-www-form-urlencoded"> + <form method="post" action="search.cgi" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="action" value="search" /> <input type="text" size="15" name="search" id="nav_search" value="Search text" onfocus="this.value=''" /> <label for="nav_search" class="hidden">Search text</label> <input type="submit" value="Go" class="form_button" /> </form> </li> - <li><a href="supersearch.cgi">Advanced Search</a></li> + <li><a href="search.cgi">Advanced Search</a></li> </ul>
[% UNLESS not_editable %]
Modified: trunk/templates/node.tt =================================================================== --- trunk/templates/node.tt 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/templates/node.tt 2005-11-24 20:01:09 UTC (rev 716) @@ -39,7 +39,7 @@ [% IF coord_field_1_value AND coord_field_2_value %] <br clear="all" /> <div id="find_within_distance"> - <form action="supersearch.cgi"> + <form action="search.cgi"> <label for="distance">Find all things within</label> <select name="[% dist_field %]" id="distance"> <option value="500">500 metres</option>
Copied: trunk/templates/search.tt (from rev 715, trunk/templates/supersearch.tt) =================================================================== --- trunk/templates/supersearch.tt 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/templates/search.tt 2005-11-24 20:01:09 UTC (rev 716) @@ -0,0 +1,111 @@ +[% IF search_terms %] +[% node_name = "Search results for $search_terms" %] +[% ELSE %] +[% node_name = "Search" %] +[% END %] +[% INCLUDE header.tt %] +[% INCLUDE banner.tt %] +<div id="content"> +[% INCLUDE navbar.tt %] +<div id="maincontent"> + [% IF search_terms %] + <h2>Search Results for <em>[% search_terms %]</em></h2> + [% IF results.size %] + <h3>[% total_num %] matches found, showing [% first_num %] - [% last_num %]</h3> + [% END %] + [% ELSE %] + <h2>Search [% site_name %]</h2> + [% END %] + + <p><small> + Version [% ss_version %]. See the + <a href="[% ss_info_url %]">information page</a> for help and more details. + </small></p> + + <form method="get" action="search.cgi"> + <table border="1"> + <tr> + <th> + <label for="search_upper">Pages containing text:</label> + </th> + <td> + <input type="text" name="search" value="[% IF search_terms %][% search_terms %][% END %]" size="50" maxlength="80" id="search_upper" /> + </td> + </tr> + <tr> + <th>Location:</th> + <td> + [% IF coord_field_1 != 'latitude' %] + <p> + within <input type="text" name="[% dist_field %]" value="[% dist %]" size="5" maxlength="5" /> metres of<br /> + [% coord_field_1_name %] <input type="text" name="[% coord_field_1 %]" value="[% coord_field_1_value %]" size="10" maxlength="10" />,<br /> + [% coord_field_2_name %] <input type="text" name="[% coord_field_2 %]" value="[% coord_field_2_value %]" size="10" maxlength="10" /> + </p> + [% END %] + <p> + within <input type="text" name="latlong_dist" value="[% dist %]" size="5" maxlength="5" /> metres of<br /> + latitude (decimal) <input type="text" name="latitude" value="[% latitude %]" size="10" maxlength="10" />,<br /> + longitude (decimal) <input type="text" name="longitude" value="[% longitude %]" size="10" maxlength="10" /> + </p> + </td> + </tr> + <tr> + <td colspan="2" align="right"> + <input type="submit" name="go" class="form_button" value="Go" /> + </td> + </tr> + </table> + </form> + + [% IF search_terms OR dist %] + + <hr /> + + [% IF results.size %] + + <ol start="[% first_num %]"> + [% FOREACH result = results %] + <li> + <a href="[% result.url %]"><b>[% result.name %]</b></a> (score: [% result.score %]) + [% IF result.distance %] + ([% result.distance %] metres away) + [% END %][% IF result.summary %] + <div class="hit_summary"> + [% result.summary %] + </div>[% END %] + </li> + [% END %] + </ol> + + <p> + Matches [% first_num %] - [% last_num %] of [% total_num %]. + [% IF (first_num > 20) %] + <a href="search.cgi?search=[% search_terms %]&next=[% first_num - 21 %]">Previous 20 results</a> + [% END %] + [% IF ((first_num > 20) and next_page_startpos) %] + / + [% END %] + [% IF next_page_startpos %] + <a href="search.cgi?search=[% search_terms %];[% dist_field %]=[% dist %];[% coord_field_1 %]=[% coord_field_1_value %];[% coord_field_2 %]=[% coord_field_2_value %];next=[% next_page_startpos %]">Next + [% IF ((total_num - last_num >= 20)) %] + 20 + [% ELSE %] + [% total_num - last_num %] + [% END %] + results</a> + [% END %] + </p> + + [% ELSE %] + <h2>No Items Matched</h2> + [% END %] + + <form method="get" action="search.cgi"> + <label for="search_lower">Search:</label> + <input type="text" name="search" id="search_lower" value="[% search_terms %]" size="50" maxlength="80" value="Search text" onclick="this.value=''" /> + <input type="submit" name="go" class="form_button" value="Go" /> + </form> + [% END %] + +</div> +[% INCLUDE footer.tt %]
Deleted: trunk/templates/supersearch.tt =================================================================== --- trunk/templates/supersearch.tt 2005-11-21 08:54:03 UTC (rev 715) +++ trunk/templates/supersearch.tt 2005-11-24 20:01:09 UTC (rev 716) @@ -1,111 +0,0 @@ -[% IF search_terms %] -[% node_name = "Search results for $search_terms" %] -[% ELSE %] -[% node_name = "Search" %] -[% END %] -[% INCLUDE header.tt %] -[% INCLUDE banner.tt %] -<div id="content"> -[% INCLUDE navbar.tt %] -<div id="maincontent"> - [% IF search_terms %] - <h2>Search Results for <em>[% search_terms %]</em></h2> - [% IF results.size %] - <h3>[% total_num %] matches found, showing [% first_num %] - [% last_num %]</h3> - [% END %] - [% ELSE %] - <h2>Search [% site_name %]</h2> - [% END %] - - <p><small> - Version [% ss_version %]. See the - <a href="[% ss_info_url %]">information page</a> for help and more details. - </small></p> - - <form method="get" action="supersearch.cgi"> - <table border="1"> - <tr> - <th> - <label for="search_upper">Pages containing text:</label> - </th> - <td> - <input type="text" name="search" value="[% IF search_terms %][% search_terms %][% END %]" size="50" maxlength="80" id="search_upper" /> - </td> - </tr> - <tr> - <th>Location:</th> - <td> - [% IF coord_field_1 != 'latitude' %] - <p> - within <input type="text" name="[% dist_field %]" value="[% dist %]" size="5" maxlength="5" /> metres of<br /> - [% coord_field_1_name %] <input type="text" name="[% coord_field_1 %]" value="[% coord_field_1_value %]" size="10" maxlength="10" />,<br /> - [% coord_field_2_name %] <input type="text" name="[% coord_field_2 %]" value="[% coord_field_2_value %]" size="10" maxlength="10" /> - </p> - [% END %] - <p> - within <input type="text" name="latlong_dist" value="[% dist %]" size="5" maxlength="5" /> metres of<br /> - latitude (decimal) <input type="text" name="latitude" value="[% latitude %]" size="10" maxlength="10" />,<br /> - longitude (decimal) <input type="text" name="longitude" value="[% longitude %]" size="10" maxlength="10" /> - </p> - </td> - </tr> - <tr> - <td colspan="2" align="right"> - <input type="submit" name="go" class="form_button" value="Go" /> - </td> - </tr> - </table> - </form> - - [% IF search_terms OR dist %] - - <hr /> - - [% IF results.size %] - - <ol start="[% first_num %]"> - [% FOREACH result = results %] - <li> - <a href="[% result.url %]"><b>[% result.name %]</b></a> (score: [% result.score %]) - [% IF result.distance %] - ([% result.distance %] metres away) - [% END %][% IF result.summary %] - <div class="hit_summary"> - [% result.summary %] - </div>[% END %] - </li> - [% END %] - </ol> - - <p> - Matches [% first_num %] - [% last_num %] of [% total_num %]. - [% IF (first_num > 20) %] - <a href="supersearch.cgi?search=[% search_terms %]&next=[% first_num - 21 %]">Previous 20 results</a> - [% END %] - [% IF ((first_num > 20) and next_page_startpos) %] - / - [% END %] - [% IF next_page_startpos %] - <a href="supersearch.cgi?search=[% search_terms %];[% dist_field %]=[% dist %];[% coord_field_1 %]=[% coord_field_1_value %];[% coord_field_2 %]=[% coord_field_2_value %];next=[% next_page_startpos %]">Next - [% IF ((total_num - last_num >= 20)) %] - 20 - [% ELSE %] - [% total_num - last_num %] - [% END %] - results</a> - [% END %] - </p> - - [% ELSE %] - <h2>No Items Matched</h2> - [% END %] - - <form method="get" action="supersearch.cgi"> - <label for="search_lower">Search:</label> - <input type="text" name="search" id="search_lower" value="[% search_terms %]" size="50" maxlength="80" value="Search text" onclick="this.value=''" /> - <input type="submit" name="go" class="form_button" value="Go" /> - </form> - [% END %] - -</div> -[% INCLUDE footer.tt %]