Log in |
Fast Site SearchIn this How To you will see how to searchon your site using external Python methods. External methods are faster than Python scripts (internal methods) and works on any Zope version (2.2.x, 2.3.x, ...) This is the fast version of SiteSearch. Here is a benchmark: Search and list all items (422 items): 10 seconds - python scripts (Site Search) 5 seconds - external method (Fast Site Search) Search for 'news' (found 6 items): 4 seconds - python scripts (Site Search) <1 second - external method (Fast Site Search) You need to create 3 objects: site_search.py on your Extensions folder of your Zope fast_site_search - an external method. Put it in /scr/ folder of your website. Search - an DTML Document External Python FileCreate a file into extension folder of your Zope system:FileName: site_search.py Body: import string def sub_doc(s,pos,n,search_expr): #s - the string #pos - position in string #n - number of chars to show before and after pos start_ix = int(pos) - int(n) if start_ix < 0: start_ix = 0 end_ix = int(pos) + int(n) + len(search_expr) if end_ix > len(s): end_ix = len(s) ret = string.replace(s[start_ix:end_ix],'<',' ') ret = string.replace(ret,'>',' ') return string.replace(string.lower(ret),string.lower(search_expr),'<b><u>'+search_expr+'</u></b>') def fast_site_search(self,search_expr='',cnt=0): ret='' count=cnt for i in self.objectItems(['Folder','ZWiki Page','DTML Document']): o=i[1] #the object id=i[0] title=o.title #if (id!='index_html' and id!='index.htm' and id!='index.html') or o.getNodeName()=='ZWikiPage': if 1: des='' if o.hasProperty('descr'): des=o.descr if o.hasProperty('description'): des=o.description if o.getNodeName()=="Folder": ret1,count1=fast_site_search(o,search_expr,count) ret=ret+ret1 count=count1 else: ix1 = string.find(string.lower(o.raw),string.lower(search_expr)) #body ix2 = string.find(string.lower(des),string.lower(search_expr)) #description ix3 = string.find(string.lower(title),string.lower(search_expr)) #title if search_expr=='' or ix1 != -1 or ix2 != -1 or ix3 != -1 : count=count+1 ret=ret+'<img src="' if o.hasProperty('ico'): ret=ret+self.iconspath+o.ico else: ret=ret+o.icon ret=ret+'" border=0 width=18 height=16> <a href="'+o.absolute_url() if hasattr(o, 'item_info'): if o.item_info=='LocalForum': ret=ret+'/view_item' if o.item_info=='WikiForum': ret=ret+'/view_doc' if o.item_info=='IForum': ret=ret+'/../view_item?doc_id='+id if o.item_info=='News': ret=ret+'/view_news' ret=ret+'">'+o.title_or_id()+'</a>' # '<b>'+str(o.bobobase_modification_time())+'</b>' if search_expr!='': ret=ret+'<div style="margin-left:0.5cm; position:relative; text-align : left;">' if ix1!=-1: ret=ret+sub_doc(o.raw,ix1,400,search_expr) if ix2!=-1: ret=ret+sub_doc(des,ix2,400,search_expr) if ix3!=-1: ret=ret+sub_doc(title,ix3,400,search_expr) ret=ret+'</div><hr>' else: ret=ret+'<br>' return ret,count External MethodId: fast_site_searchTitle: External Python Method Module Name: site_search Function Name: fast_site_search Put it in /scr/ folder of your website. DTML DocumentId:SearchTitle:Site Search Body: <dtml-var standard_html_header> <h1>Site Search</h1> <dtml-unless do_search> <b>Type a search expression and hit enter to search the entire Site.<br> The expression is case-insensitive and spaces are preserved.</b><br><br> <u>Tip:</u> <i>Leave it blank to list all documents.</i><br><br> </dtml-unless> <form name=searchform method="POST"> <input name="search_expr" type="text" size="30" <dtml-if search_expr>value="<dtml-var search_expr>"</dtml-if>> <input type="submit" name="b_search" value=<dtml-if do_search>"Search again"<dtml-else>"Search"</dtml-if>> <input type="hidden" name="do_search" value="yes"> </form> <dtml-unless search_expr><dtml-call "REQUEST.set('search_expr','')"></dtml-unless> <dtml-if do_search> <br> <dtml-call "REQUEST.set('results',scr.fast_site_search(PARENTS[-1],search_expr,0))"> <b>Search Results <dtml-if "_.int(results[1])>0"> (found <dtml-var "results[1]"> <dtml-if "_.int(results[1])==1">item<dtml-else>items</dtml-if> )</dtml-if> :</b> <br> <dtml-if "_.int(results[1])>0"> <dtml-var "results[0]"> <br> <dtml-if "_.int(results[1])==1"> <b>Found only one item.</b> <dtml-else> <b>Total <dtml-var "results[1]"> items.</b> </dtml-if> <dtml-else> <br><b>Sorry! Nothing found!</a> </dtml-if> </dtml-if> <script> document.searchform.search_expr.focus(); </script> <dtml-var standard_html_footer> |