You are not logged in Log in Join
You are here: Home » Members » Ioan's Zope Documents » Fast Site Search

Log in
Name

Password

 

Fast Site Search

In this How To you will see how to search
on 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 File

Create 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 Method

Id: fast_site_search
Title: External Python Method
Module Name: site_search
Function Name: fast_site_search
Put it in /scr/ folder of your website.

DTML Document

Id:Search
Title: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>