[dw-free] convert multisearch.bml to TT
[commit: http://hg.dwscoalition.org/dw-free/rev/73087735e83d]
http://bugs.dwscoalition.org/show_bug.cgi?id=3976
Refactor and convert multisearch.bml to multisearch.tt.
Patch by
kareila.
Files modified:
http://bugs.dwscoalition.org/show_bug.cgi?id=3976
Refactor and convert multisearch.bml to multisearch.tt.
Patch by
![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Files modified:
- bin/upgrading/deadphrases.dat
- cgi-bin/DW/Controller/Search/Multisearch.pm
- htdocs/multisearch.bml
- htdocs/multisearch.bml.text
- views/multisearch.tt
- views/multisearch.tt.text
-------------------------------------------------------------------------------- diff -r 59ef33796a97 -r 73087735e83d bin/upgrading/deadphrases.dat --- a/bin/upgrading/deadphrases.dat Wed Oct 19 00:05:03 2011 +0800 +++ b/bin/upgrading/deadphrases.dat Mon Oct 24 17:58:12 2011 +0800 @@ -183,7 +183,19 @@ general /modify_do.bml.title +general /multisearch.bml.formaterror +general /multisearch.bml.noaddress.text +general /multisearch.bml.noaddress.title +general /multisearch.bml.nofaqsearch.text +general /multisearch.bml.nofaqsearch.title +general /multisearch.bml.nointerest.text +general /multisearch.bml.nointerest.title +general /multisearch.bml.nomatch.text +general /multisearch.bml.nomatch.title +general /multisearch.bml.region.bodytext2 +general /multisearch.bml.region.head general /multisearch.bml.region.text +general /multisearch.bml.title.results general /register.bml.new.body general /register.bml.new.modify2 diff -r 59ef33796a97 -r 73087735e83d cgi-bin/DW/Controller/Search/Multisearch.pm --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cgi-bin/DW/Controller/Search/Multisearch.pm Mon Oct 24 17:58:12 2011 +0800 @@ -0,0 +1,253 @@ +#!/usr/bin/perl +# +# DW::Controller::Search::Multisearch +# +# Conversion of LJ's multisearch.bml, used for handling redirects +# from sitewide search bar (LJ::Widget::Search). +# +# Authors: +# Jen Griffin <kareila@livejournal.com> +# +# Copyright (c) 2011 by Dreamwidth Studios, LLC. +# +# This program is free software; you may redistribute it and/or modify it under +# the same terms as Perl itself. For a copy of the license, please reference +# 'perldoc perlartistic' or 'perldoc perlgpl'. +# + +package DW::Controller::Search::Multisearch; + +use strict; + +use DW::Routing; +use DW::Template; +use DW::Controller; + +DW::Routing->register_string( '/multisearch', \&multisearch_handler, app => 1 ); + +sub multisearch_handler { + my $r = DW::Request->get; + my $args = $r->did_post ? $r->post_args : $r->get_args; + + my $type = lc $args->{'type'} || ''; + my $q = lc $args->{'q'} || ''; + my $output = lc $args->{'output'} || ''; + + my ( $ok, $rv ) = controller( anonymous => 1 ); + return $rv unless $ok; + + my $tpl = 'multisearch.tt'; + + # functions for handling various call types + my ( $f_nav, $f_user, $f_int, $f_email, $f_im, $f_faq, $f_region ); + + $f_nav = sub { + # Some special shortcuts used for easy navigation + return $r->redirect( "$LJ::SITEROOT/support/faqbrowse?faqid=$1&view=full" ) + if $q =~ /^faq (\d+)$/; + return $r->redirect( "$LJ::SITEROOT/support/see_request?id=$2" ) + if $q =~ /^req(uest)? (\d+)$/; + + if ( $q =~ m!(.+)/(pics|full)! ) { + if ( my $u = LJ::load_user_or_identity($1) ) { + return $r->redirect( $u->profile_url( full => 1 ) ) + if $2 eq "full"; + return $r->redirect( $u->allpics_base ) + if $2 eq "pics"; + } + } + + eval "use LJ::NavTag;"; + return error_ml( 'error.tempdisabled' ) if $@; + + my @dests = LJ::NavTag->dests_of_tag( $q ); + my $last_is_untrusted = 0; + + if ( $type eq "nav_and_user" ) { + if ( my $u = LJ::load_user_or_identity($q) ) { + push @dests, LJ::NavTag::Dest->new( type => "LJUSER", + dest => $u->user ); + + # Presumably users will start registering usernames that match + # our site navigation tags, so let's preempt that and push them + # into a bottom section when site-defined tags are also present. + $last_is_untrusted = 1 if $u->is_visible; + } + } + + my $eq = LJ::ehtml( $q ); + return error_ml( '/multisearch.tt.errorpage.nomatch.nav', { query => $eq } ) + unless @dests; + return $r->redirect( $dests[0]->url ) if @dests == 1; + + # multiple matches + my @cats = ( { name => 'site', list => \@dests } ); + push @cats, { name => 'user', list => [ pop @dests ] } + if $last_is_untrusted; + + $rv->{type} = 'nav'; + $rv->{query} = $eq; + $rv->{cats} = \@cats; + + return DW::Template->render_template( $tpl, $rv ); + }; + + $f_user = sub { + my $user = $q; + $user =~ s!\@$LJ::USER_DOMAIN!!; + $user =~ s!/(\w+)!!; + my $what = defined $1 ? $1 : ''; + + $user =~ s/-/_/g; + $user =~ s/[^\w]//g; + + return $r->redirect( "$LJ::SITEROOT/random" ) unless $user; + + my $u = LJ::load_user( $user ); + return $r->redirect( "$LJ::SITEROOT/profile?user=$user" ) unless $u; + + return $r->redirect( $u->allpics_base ) if $what eq "pics"; + + return $r->redirect( $u->journal_base . '/data/foaf' ) + if $output eq "foaf"; + + my $url = $u->profile_url; + $url .= "?mode=full" if $what eq 'full'; + return $r->redirect( $url ); + }; + + $f_int = sub { + return error_ml( '/multisearch.tt.errorpage.nointerest' ) unless $q; + return $r->redirect( "$LJ::SITEROOT/interests?int=" . LJ::eurl( $q ) ); + }; + + $f_email = sub { + return error_ml( '/multisearch.tt.errorpage.noaddress' ) unless $q; + + my $dbr = LJ::get_db_reader(); + my $uid = $dbr->selectrow_array( qq{ + SELECT userid FROM user WHERE journaltype='P' AND statusvis='V' + AND allow_contactshow='Y' AND email=? LIMIT 1 }, undef, $q ); + + # if not in the user table, try the email table + $uid ||= $dbr->selectrow_array( qq{ + SELECT e.userid FROM user u, email e WHERE e.email=? + AND e.userid=u.userid AND u.journaltype='P' AND u.statusvis='V' + AND u.allow_contactshow='Y' LIMIT 1 }, undef, $q ); + + if ( my $u = LJ::load_userid( $uid ) ) { + my $show = $u->opt_whatemailshow; + if ( $show eq "A" || $show eq "B" ) { + return $r->redirect( $u->journal_base . '/data/foaf' ) + if $output eq "foaf"; + return $r->redirect( $u->profile_url ); + } + } + return error_ml( '/multisearch.tt.errorpage.nomatch' ); + }; + + $f_im = sub { + eval "use LJ::Directory::Constraint::ContactInfo;"; + return error_ml( 'error.tempdisabled' ) if $@; + + my $c = LJ::Directory::Constraint::ContactInfo->new( screenname => $q ); + my @uids = $c->matching_uids; + + if ( @uids == 1 ) { + my $u = LJ::load_userid( $uids[0] ); + return $r->redirect( $u->journal_base . '/data/foaf' ) + if $output eq "foaf"; + return $r->redirect( $u->profile_url ); + + } elsif ( @uids > 1 ) { + $rv->{type} = 'im'; + + my $us = [ values %{ LJ::load_userids( @uids ) } ]; + $rv->{results} = LJ::user_search_display( + users => $us, timesort => 1, perpage => 50 ); + + return DW::Template->render_template( $tpl, $rv ); + } + return error_ml( '/multisearch.tt.errorpage.nomatch' ); + }; + + $f_region = sub { + $q = LJ::trim( $q ); + my @parts = split /\s*,\s*/, $q; + if ( @parts == 0 || @parts > 3 ) { + $rv->{type} = 'region'; + return DW::Template->render_template( $tpl, $rv ); + } + + my $ctc = $parts[-1]; + my $dbr = LJ::get_db_reader(); + my $sth = $dbr->prepare( qq{ + SELECT code FROM codes WHERE type='country' + AND (code=? OR item=?) LIMIT 1 } ); + $sth->execute( $ctc, $ctc ); + my ( $country ) = $sth->fetchrow_array; + my ( $state, $city ); + + if ( $country ) { + pop @parts; + if ( @parts == 1 ) { + $state = $parts[0]; + } else { + ( $city, $state ) = @parts; + } + + } else { + $country = "US"; + + if ( @parts == 1 ) { + $city = $parts[0]; + } else { + ( $city, $state ) = @parts; + } + } + + ( $city, $state, $country ) = map { LJ::eurl($_) } + ( $city, $state, $country ); + return $r->redirect( "$LJ::SITEROOT/directorysearch?s_loc=1" . + "&loc_cn=$country&loc_st=$state&loc_ci=$city" . + "&opt_sort=ut&opt_format=pics&opt_pagesize=50" ); + }; + + $f_faq = sub { + return error_ml( '/multisearch.tt.errorpage.nofaq' ) unless $q; + return $r->redirect( "$LJ::SITEROOT/support/faqsearch?q=" . LJ::eurl( $q ) ); + }; + + # set up dispatch table + my $dispatch = { nav => $f_nav, + nav_and_user => $f_nav, + user => $f_user, + ljtalk => $f_user, + int => $f_int, + email => $f_email, + im => $f_im, + aolim => $f_im, + icq => $f_im, + yahoo => $f_im, + msn => $f_im, + jabber => $f_im, + region => $f_region, + faq => $f_faq, + }; + + return $dispatch->{$type}->() if exists $dispatch->{$type}; + + # Unknown type, try running site hooks + if ( $type ) { + # TODO: check return value of this hook, and fall back to another hook + # that shows the results here, rather than redirecting to another page + return LJ::Hooks::run_hook( 'multisearch_custom_search_redirect', + { type => $type, query => $q } ); + } + + # No type specified - redirect them somewhere useful. + return $r->redirect( "$LJ::SITEROOT/tools/search" ); +} + + +1; diff -r 59ef33796a97 -r 73087735e83d htdocs/multisearch.bml --- a/htdocs/multisearch.bml Wed Oct 19 00:05:03 2011 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,274 +0,0 @@ -<?_c -# This code was forked from the LiveJournal project owned and operated -# by Live Journal, Inc. The code has been modified and expanded by -# Dreamwidth Studios, LLC. These files were originally licensed under -# the terms of the license supplied by Live Journal, Inc, which can -# currently be found at: -# -# http://code.livejournal.org/trac/livejournal/browser/trunk/LICENSE-LiveJournal.txt -# -# In accordance with the original license, this code and all its -# modifications are provided under the GNU General Public License. -# A copy of that license can be found in the LICENSE file included as -# part of this distribution. -_c?> -<?_code -{ - use strict; - use vars qw(%GET %POST $title $body $arg); - - $title = ""; - $body = ""; - my $type = $POST{'type'} || $GET{'type'}; - my $q = $POST{'q'} || $GET{'q'}; - my $output = lc($POST{'output'}) || lc($GET{'output'}); - my $dbr = LJ::get_db_reader(); - - if ($type eq "nav_and_user" || $type eq "nav") { - # Some special shortcuts used for easy navigation - if ($q =~ /^faq (\d+)$/) { - return BML::redirect("$LJ::SITEROOT/support/faqbrowse?faqid=$1&view=full"); - } - if ($q =~ /^req(uest)? (\d+)$/) { - return BML::redirect("$LJ::SITEROOT/support/see_request?id=$2"); - } - if ($q =~ m!(.+)/(pics|full)!) { - if (my $u = LJ::load_user($1)) { - return BML::redirect( $u->profile_url('full' => 1) ) - if $2 eq "full"; - return BML::redirect( $u->allpics_base ) - if $2 eq "pics"; - } - } - - do "LJ/NavTag.pm"; - my @dests = LJ::NavTag->dests_of_tag($q); - my $last_is_untrusted = 0; - - if ($type eq "nav_and_user") { - my $u = LJ::load_user_or_identity($q); - if ($u) { - push @dests, LJ::NavTag::Dest->new(type => "LJUSER", dest => $u->{user}); - - # presumably users will start registering usernames that match our site navigation tags, - # so let's preempt that and throw them into a lame bottom section when site-defined tags - # are alse present. - $last_is_untrusted = 1 if $u->is_visible; - } - } - - my $eq = LJ::ehtml($q); - if (@dests == 0) { - $title = "No matches"; - $body = "<?h1 $ML{'Error'} h1?><?p No site page or username matches your search for <b>$eq</b>. p?>"; - return; - } - if (@dests == 1) { - return BML::redirect($dests[0]->url); - } - - $title = "Choices"; - $body = "<?h1 Multiple Choices h1?>"; - - my @cats = ({ - title => "Site pages", - text => "The following $LJ::SITENAMESHORT pages match your search for <b>$eq</b>:", - list => \@dests, - }); - - if ($last_is_untrusted) { - push @cats, { - title => "User account", - text => "The following user account matches your search for <b>$eq</b>:", - list => [ pop @dests ], - }; - } - - foreach my $cat (@cats) { - $body .= "<?h2 $cat->{title} h2?><?p $cat->{text} p?>"; - $body .= "<ul>"; - foreach my $dst (@{ $cat->{list} }) { - my $lju = $dst->ljuser; - my $link; - if ($lju) { - $link = $dst->ljuser->ljuser_display . " - " . LJ::ehtml($dst->title); - } else { - $link = "<a href=\"" . LJ::ehtml($dst->url) . "\">" . LJ::ehtml($dst->title) . "</a>"; - } - if ( ! $lju || $lju->is_visible ) { - $body .= "<li>$link</li>\n"; - } - } - $body .= "</ul>"; - } - - return; - } - - if ($type eq "user" || $type eq "ljtalk") { - my $user = lc($q); - $user =~ s!\@$LJ::USER_DOMAIN!!; - my $what; - if ($user =~ s!/(\w+)!!) { - $what = $1; - } - - $user =~ s/-/_/g; - $user =~ s/[^\w]//g; - if ($user) { - my $url; - if ($what eq "pics") { - $url = "$LJ::SITEROOT/allpics?user=$user"; - } elsif ($output eq "foaf") { - $url = LJ::journal_base($user) . '/data/foaf'; - } else { - if (my $u = LJ::load_user($user)) { - $url = $u->profile_url; - $url .= "?mode=full" if $what eq 'full'; - } else { - $url = "$LJ::SITEROOT/profile?user=$user"; - } - } - return BML::redirect($url); - } else { - return BML::redirect("$LJ::SITEROOT/random"); - } - } - - if ($type eq "int") { - my $int = lc($q); - if ($int) { - return BML::redirect("$LJ::SITEROOT/interests?int=" . LJ::eurl($int)); - } else { - $title = $ML{'.nointerest.title'}; - $body = "<?h1 $ML{'Error'} h1?><?p $ML{'.nointerest.text'} p?>"; - return; - } - } - - if ($type eq "email") { - my $email = lc($q); - unless ($email) { - $title = $ML{'.noaddress.title'}; - $body = "<?h1 $ML{'Error'} h1?><?p $ML{'.noaddress.text'} p?>"; - return; - } else { - my $uid = $dbr->selectrow_array("SELECT userid FROM user WHERE journaltype='P' AND statusvis='V' ". - "AND allow_contactshow='Y' AND email=? LIMIT 1", undef, $email); - # try the email table - unless ($uid) { - $uid = $dbr->selectrow_array(qq{ - SELECT e.userid - FROM user u, email e - WHERE e.email=? AND e.userid=u.userid AND u.journaltype='P' AND u.statusvis='V' - AND u.allow_contactshow='Y' LIMIT 1 - }, undef, $email); - } - if (my $u = LJ::load_userid($uid)) { - if ($u->opt_whatemailshow eq "A" || $u->opt_whatemailshow eq "B") { - if ($output eq "foaf") { - return BML::redirect( $u->journal_base . '/data/foaf' ); - } else { - return BML::redirect( $u->profile_url ); - } - } - } - $title = $ML{'.nomatch.title'}; - $body = "<?h1 $ML{'Sorry'} h1?><?p $ML{'.nomatch.text'} p?>"; - return; - } - } - - if ($type eq "im" || - $type eq "aolim" || $type eq "icq" || - $type eq "yahoo" || $type eq "msn" || - $type eq "jabber") { - - use LJ::Directory::Constraint::ContactInfo; - my @uids = LJ::Directory::Constraint::ContactInfo->new(screenname => $q)->matching_uids; - - if (@uids == 1) { - my $u = LJ::load_userid(shift @uids); - if ($output eq "foaf") { - return BML::redirect($u->journal_base . '/data/foaf'); - } else { - return BML::redirect($u->profile_url); - } - } elsif (@uids > 1) { - my $us = LJ::load_userids(@uids); - - $title = $ML{'.title.results'}; - $body .= LJ::user_search_display( - users => [ values %$us ], - timesort => 1, - perpage => 50, - ); - return; - } - - # If we haven't returned already then the search turned up nothing. - $title = $ML{'.nomatch.title'}; - $body = "<?h1 $ML{'Sorry'} h1?><?p $ML{'.nomatch.text'} p?>"; - return; - } - - if ($type eq "region") { - $q =~ s/^\s+//; $q =~ s/\s+$//; - my @parts = split(/\s*,\s*/, $q); - if (@parts==0 || @parts>3) { - $title = $ML{'.formaterror'}; - $body .= "<?h1 $ML{'.region.head'} h1?><?p " . BML::ml('.region.bodytext2', {'aopts' => "href='$LJ::SITEROOT/directorysearch'"}) . " p?>"; - return; - } - - my $ctc = $parts[-1]; - my $sth = $dbr->prepare("SELECT code FROM codes WHERE type='country' AND (code=? OR item=?) LIMIT 1"); - $sth->execute($ctc, $ctc); - my ($country) = $sth->fetchrow_array; - my ($state, $city); - - if ($country) { - pop @parts; - if (@parts == 1) { - $state = $parts[0]; - } elsif (@parts == 2) { - ($city, $state) = @parts; - } - } else { - $country = "US"; - if (@parts ==1) { - $city = $parts[0]; - } elsif (@parts == 2) { - ($city, $state) = @parts; - } - } - ($city, $state, $country) = map { LJ::eurl($_); } ($city, $state, $country); - return BML::redirect("$LJ::SITEROOT/directorysearch?s_loc=1&loc_cn=$country&loc_st=$state&loc_ci=$city&opt_sort=ut&opt_format=pics&opt_pagesize=50"); - } - - if ($type eq "faq") { - my $term = lc($q); - if ($term) { - return BML::redirect("$LJ::SITEROOT/support/faqsearch?q=" . LJ::eurl($term)); - } else { - $title = $ML{'.nofaqsearch.title'}; - $body = "<?h1 $ML{'Error'} h1?><?p $ML{'.nofaqsearch.text'} p?>"; - return; - } - } - - # Unknown type, try running site hooks - if ($type) { - # TODO: check return value of this hook, and fall back to another - # hook that shows the results here, rather than redirecting to another page - return LJ::Hooks::run_hook('multisearch_custom_search_redirect', { - type => $type, - query => $q, }); - } - - return; -} -_code?><?page -title=><?_code return $title; _code?> -body=><?_code return $body; _code?> -page?> diff -r 59ef33796a97 -r 73087735e83d htdocs/multisearch.bml.text --- a/htdocs/multisearch.bml.text Wed Oct 19 00:05:03 2011 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -;; -*- coding: utf-8 -*- -.formaterror=Format Error - -.noaddress.text=You didn't enter an email address. - -.noaddress.title=No Address - -.nofaqsearch.text=You didn't enter a term to search for in the FAQ. - -.nofaqsearch.title=No FAQ Search Term - -.nointerest.text=You didn't enter an interest. - -.nointerest.title=No Interest - -.nomatch.text=There were no results for the criteria you specified. - -.nomatch.title=No Match - -.region.bodytext2<< -You can search by region in one of the following formats: -<ul> - <li>Country</li> - <li>City *</li> - <li>City, State *</li> - <li>State, Country</li> - <li>City, State, Country</li> -</ul> -Notes: -<ul> - <li>* searching for only a city or a city and state defaults to assuming the country is the United States.</li> - <li>Country can either be the country's full name, or its two letter country code</li> -</ul> -If you want to do a different type of search, check out the <a [[aopts]]>directory search</a>. -. - -.region.head=Search by Region - -.title.results=Search Results - diff -r 59ef33796a97 -r 73087735e83d views/multisearch.tt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/views/multisearch.tt Mon Oct 24 17:58:12 2011 +0800 @@ -0,0 +1,43 @@ +[%# TT conversion of multisearch.bml + # + # Authors: + # Jen Griffin <kareila@livejournal.com> + # + # Copyright (c) 2011 by Dreamwidth Studios, LLC. + # + # This program is free software; you may redistribute it and/or modify it + # under the same terms as Perl itself. For a copy of the license, please + # reference 'perldoc perlartistic' or 'perldoc perlgpl'. + # +%] + +[%- sections.title=".title.$type" | ml -%] + +[%- IF type == 'nav' -%] + [%- FOREACH cats -%] + <h2>[% ".head.$name" | ml %]</h2> + <p>[% ".text.$name" | ml(query = query, sitename = site.nameshort) %]</p> + <ul class="bullet-list"> + [%- FOREACH dst = list; + link_title = dst.title | html; + link_url = dst.url | html; + lju = dst.ljuser -%] + + [%- IF lju -%] + [%- IF lju.is_visible -%] + <li>[% lju.ljuser_display %] - [% link_title %]</li> + [%- END -%] + [%- ELSE -%] + <li><a href="[% link_url %]">[% link_title %]</a></li> + [%- END -%] + + [%- END -%] + </ul> + [%- END -%] +[%- END -%] + +[%- IF type == 'im'; results; END -%] + +[%- IF type == 'region'; + '.region.bodytext' | ml(aopts = "href='$site.root/directorysearch'"); + END -%] diff -r 59ef33796a97 -r 73087735e83d views/multisearch.tt.text --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/views/multisearch.tt.text Mon Oct 24 17:58:12 2011 +0800 @@ -0,0 +1,46 @@ +;; -*- coding: utf-8 -*- +.errorpage.noaddress=You didn't enter an email address. + +.errorpage.nofaq=You didn't enter a term to search for in the FAQ. + +.errorpage.nointerest=You didn't enter an interest. + +.errorpage.nomatch=There were no results for the criteria you specified. + +.errorpage.nomatch.nav=No site page or username matches your search for <b>[[query]]</b>. + +.head.site=Site pages + +.head.user=User account + +.region.bodytext<< +<p>Your search criteria were incorrectly specified.</p> + +<p>You can search by region in one of the following formats:</p> +<ul class='bullet-list'> + <li>Country</li> + <li>City *</li> + <li>City, State *</li> + <li>State, Country</li> + <li>City, State, Country</li> +</ul> +<p>Notes:</p> +<ul class='bullet-list'> + <li>* Searching for only a city or a city and state defaults to assuming + the country is the United States.</li> + <li>Country can either be the country's full name, or its two letter + country code.</li> +</ul> +<p>If you want to do a different type of search, check out the +<a [[aopts]]>directory search</a>.</p> +. + +.text.site=The following [[sitename]] pages match your search for <b>[[query]]</b>: + +.text.user=The following user account matches your search for <b>[[query]]</b>: + +.title.im=Search Results + +.title.nav=Multiple Choices + +.title.region=Search by Region --------------------------------------------------------------------------------