From 4372ce9bf443ceca12449bcaf1a89460e85c05db Mon Sep 17 00:00:00 2001 From: rich Date: Thu, 3 Aug 2006 13:33:15 +0000 Subject: [PATCH] Make the 404 page more informative - it now actually performs the search for you. --- html/_graphics/searching.gif | Bin 0 -> 1547 bytes html/_graphics/searching.xcf | Bin 0 -> 5133 bytes scripts/page.ml | 134 ++++++++++++++++++++++++++++++++++++++--- templates/page_404.html | 61 ++++++++++++++----- templates/page_404_header.html | 26 ++++++++ 5 files changed, 198 insertions(+), 23 deletions(-) create mode 100644 html/_graphics/searching.gif create mode 100644 html/_graphics/searching.xcf create mode 100644 templates/page_404_header.html diff --git a/html/_graphics/searching.gif b/html/_graphics/searching.gif new file mode 100644 index 0000000000000000000000000000000000000000..40a85ff0be0f5adff2c3120d181c09f570ff09e4 GIT binary patch literal 1547 zcmZ?wbhEHb3}+BvIK}`1jEsy-Oiawo%q%P{tgNiu+}u1oJOTm&!otELA|j%qqT=G> z5)u-Ul9EzVQqt1Wva+&ra&q$W@(KzHii(O#N=hm!DypigYHDig>gpOA8k(A#T3TA# z+Slp-m6g@i)wQ*?O-)U$t*vcsZ5kiUA}zz>eZ{)u3fu+{rZg?H*Vg%dF$4# z+qZAuxpU|4-Mjbi-+%Dn!J|iyo<4p0?Af#D&!4||@#591S8v|DdHeS5yLa#2zkmPX z!-tO_KYsrF`RmuO-@bkO{{8!pA3uKm`t|$w?>~S3{Qdj)-@kwV|NjSvI+RfS&+X?L z671|4;A*62z|05~R{SUGT$GwvlA5AWo>`Ki5R#Fq;O^-gz@Ye(g)@broiq19 zRc(tW=a#K#%V3OZ$<`MU(nzYd6BUsQTx>1oUY(|W)FzV2KwLPeT6#&Otcf_kf0HY( zl-Psqt>$dTAx&x?)m09P)hXND#3C8It1GLOtg1fDIVqHIN=`}Q+Zm-3e4eegd0YvJ zMGx*M8d&iCF<^FRKF%%ltspb;p%Y`%wr^7y1=269v5nx+xZ;*|ekxP-A%+dkM;lyS z0)!?oerTI8ht>IAPu0$Jo(4<3Y`rC#8PnthY*UW>@YLv5P?Y)BvZC<#vbhU0zo|$b zDB*9Hi(uTnXO7iot(7(oVJs_yIr_LmO57Y)6eOLNGtrSrQ23bY&&MiXl9Taz>5*nG zvu8n9_q3mF;S_YxP+ani`TFI~Rd-GNPJ)GA=ySsat(vLqS91k?FRUA~hE_E?hfZh+pf*4DYF*<;;ZDTo@L%Oqj*r z>Q@}AyW-Sb8!v$k^VW9wc5z5L%~*VP_xAVq+n5+f0~{m36R-q0=g(4?be0w_^=)q) z4-#B;bSN@wRPoUN$QdlJ!E*SKsiNA;8!orC?MHM?@hig@TdF9GA~8gc?I(-lYugu)ogBFI~J;p)|mwPF136T^dzw zo}U_!YD=WaD@Z{<@6q-`VJw|cmARXPQWTvR8btECCFJu(#OSz#q&-wdhnj=+ybx-N%~uv0)YTMc3Kk%nRZLphD#n53q+m-5 zwx;0R6r7KkY-yB*fc79t{eO)~nBlStG_P^3;X0b&C&~?djAh**Su2+b@k>sA)=SFey_ra4HVjF#3|a3kK+ZyNfTaeGG@~eAQLic+hbc z2DaGwL$YCadD%5^89`nsme1`3I6d3x=!6`&)oc;E0M@ia@@O^m$Ki}aX6GRR%VWvW z7czGfPE`QI@V1YL>!0}3` z4vau|yq~>-bEIg1=ap^A(O!hAj*1dTw;cOMU+v=#d=GwIInTcC9=zN-r()GZI8f-0 zxfJbZ4_42$2PbL2D=RDUbfERbpc|G!{Pswq!v-s0_}zw*1=XF<$_|4bBKqQbi1aLi z>12_KVK%){^OUmHsw5p|E~cLF=W|>W75pk>tx#*lmx{mbrttv=ji|d literal 0 HcmV?d00001 diff --git a/scripts/page.ml b/scripts/page.ml index 4a3b020..47e6ae9 100644 --- a/scripts/page.ml +++ b/scripts/page.ml @@ -1,7 +1,7 @@ (* COCANWIKI - a wiki written in Objective CAML. * Written by Richard W.M. Jones . * Copyright (C) 2004 Merjis Ltd. - * $Id: page.ml,v 1.49 2006/08/01 14:50:47 rich Exp $ + * $Id: page.ml,v 1.50 2006/08/03 13:33:15 rich Exp $ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -34,6 +34,7 @@ open Cocanwiki_date open Cocanwiki_server_settings open Cocanwiki_links open Cocanwiki_extensions +open Cocanwiki_strings type fp_status = FPOK of int32 * string * string * Calendar.t * bool | FPInternalRedirect of string @@ -74,6 +75,7 @@ let run r (q : cgi) dbh hostid let template_page = get_template ~page dbh hostid "page.html" in (* This is the simpler template for 404 pages. *) + let template_404_header = get_template dbh hostid "page_404_header.html" in let template_404 = get_template dbh hostid "page_404.html" in (* Host-specific fields. *) @@ -397,8 +399,8 @@ let run r (q : cgi) dbh hostid let make_404 () = Request.set_status r 404; (* Return a 404 error code. *) - let t = template_404 in - t#set "page" page; + let th = template_404_header in + th#set "page" page; let search_terms = String.map @@ -406,13 +408,129 @@ let run r (q : cgi) dbh hostid ('a'..'z' | 'A'..'Z' | '0'..'9') as c -> c | _ -> ' ') page in - t#set "search_terms" search_terms; + th#set "search_terms" search_terms; - t#conditional "can_edit" can_edit; - t#conditional "can_manage_users" can_manage_users; - t#conditional "has_stats" has_stats; + (* Flush out the header while we start the search. *) + q#header (); + ignore (print_string r th#to_string); + ignore (Request.rflush r); + + let t = template_404 in + t#set "query" search_terms; + t#set "canonical_hostname" host.canonical_hostname; + + (* This is a simplified version of the code in search.ml. *) + let have_results = + (* Get the keywords from the query string. *) + let keywords = Pcre.split ~rex:split_words search_terms in + let keywords = + List.filter (fun s -> not (string_is_whitespace s)) keywords in + let keywords = List.map String.lowercase keywords in + + (* Turn the keywords into a tsearch2 ts_query string. *) + let tsquery = String.concat "&" keywords in + + (* Search the titles first. *) + let rows = + PGSQL(dbh) + "select url, title, last_modified_date, + (lower (title) = lower ($search_terms)) as exact + from pages + where hostid = $hostid + and url is not null + and redirect is null + and title_description_fti @@ to_tsquery ('default', $tsquery) + order by exact desc, last_modified_date desc, title" in + + let titles = + List.map (function + | (Some url, title, last_modified, _) -> + url, title, last_modified + | _ -> assert false) rows in + + let have_titles = titles <> [] in + t#conditional "have_titles" have_titles; + + (* Search the contents. *) + let rows = + PGSQL(dbh) + "select c.id, p.url, p.title, p.last_modified_date + from contents c, pages p + where c.pageid = p.id + and p.hostid = $hostid + and url is not null + and p.redirect is null + and c.content_fti @@ to_tsquery ('default', $tsquery) + order by p.last_modified_date desc, p.title + limit 50" in + + let contents = + List.map (function + | (contentid, Some url, title, last_modified) -> + contentid, url, title, last_modified + | _ -> assert false) rows in + + let have_contents = contents <> [] in + t#conditional "have_contents" have_contents; + + (* Pull out the actual text which matched so we can generate a summary. + * XXX tsearch2 can actually do better than this by emboldening + * the text which maps. + *) + let content_map = + if contents = [] then [] + else ( + let rows = + let contentids = + List.map (fun (contentid, _,_,_) -> contentid) contents in + PGSQL(dbh) + "select id, sectionname, content from contents + where id in $@contentids" in + List.map (fun (id, sectionname, content) -> + id, (sectionname, content)) rows + ) in - q#template t + (* Generate the final tables. *) + let table = + List.map (fun (url, title, last_modified) -> + let last_modified = printable_date last_modified in + [ "url", Template.VarString url; + "title", Template.VarString title; + "last_modified", Template.VarString last_modified ] + ) titles in + t#table "titles" table; + + let table = + List.map + (fun (contentid, url, title, last_modified) -> + let sectionname, content = List.assoc contentid content_map in + let have_sectionname, sectionname = + match sectionname with + None -> false, "" + | Some sectionname -> true, sectionname in + let content = + truncate 160 + (Wikilib.text_of_xhtml + (Wikilib.xhtml_of_content r dbh hostid content)) in + let linkname = linkname_of_sectionname sectionname in + let last_modified = printable_date last_modified in + [ "url", Template.VarString url; + "title", Template.VarString title; + "have_sectionname", Template.VarConditional have_sectionname; + "sectionname", Template.VarString sectionname; + "linkname", Template.VarString linkname; + "content", Template.VarString content; + "last_modified", Template.VarString last_modified ] + ) contents in + t#table "contents" table; + + (* Do we have any results? *) + let have_results = have_titles || have_contents in + have_results in + t#conditional "have_results" have_results; + + (* Deliver the rest of the page. *) + ignore (print_string r t#to_string) in (* Fetch a page by name. This function can give three answers: diff --git a/templates/page_404.html b/templates/page_404.html index d6dda8d..f799265 100644 --- a/templates/page_404.html +++ b/templates/page_404.html @@ -1,24 +1,55 @@ - - - -Page not found - - - - - - -

Page not found

+::if(have_results):: + +::if(have_titles):: +
+
    +::table(titles):: +
  • + ::title_html:: + - Last change: ::last_modified_html:: +
  • +::end:: +
+
+::end:: + +::if(have_contents):: + +::end:: + +::else::

-Search our site for this page: +There are no similar pages found.

-

- +Some tips for finding what you want:

-
+ + + +::end:: + + ::include(footer.html):: diff --git a/templates/page_404_header.html b/templates/page_404_header.html new file mode 100644 index 0000000..f666742 --- /dev/null +++ b/templates/page_404_header.html @@ -0,0 +1,26 @@ + + + +Page not found + + + + + + + +

Page not found

+ +

+Search our site for this page: +

+ +
+

+ +

+
+ +

+Searching ... +

\ No newline at end of file -- 1.8.3.1