File:  [Repository] / ECHO_content / ECHO_xslt.py
Revision 1.13: download - view: text, annotated - select for diffs - revision graph
Thu Oct 12 16:37:33 2006 UTC (17 years, 8 months ago) by dwinter
Branches: MAIN
CVS tags: HEAD
link mechanismus geaendert, kann jetzt backlinks

    1: ### XSLT Class ###
    2: ### setzt 4 suite vorraus ###
    3: from Acquisition import Implicit
    4: from Products.PageTemplates.PageTemplateFile import PageTemplateFile
    5: from Globals import DTMLFile
    6: from ECHO_Nav import ECHO_pageTemplate
    7: from threading import Thread,Timer
    8: import threading
    9: from ECHO_helpers import *
   10: import ECHO_language
   11: import sys
   12: import urllib
   13: import urlparse
   14: from Ft.Xml.Domlette import Print, PrettyPrint
   15: from StringIO import StringIO
   16: from types import *
   17: from Globals import package_home
   18: import transaction
   19: 
   20: import os.path
   21: 
   22: import urllib
   23: 
   24: try:
   25:     from Ft.Xml.Xslt.Processor import Processor
   26:     from Ft.Xml import InputSource, EMPTY_NAMESPACE,Parse
   27:     from Ft.Xml.Domlette import NonvalidatingReader
   28: except:
   29:     print "4suite has to be installed"
   30: 
   31: 
   32: class getXML(Implicit):
   33:     """get XML thread"""
   34: 
   35:     def set(self,qs,xsl,result):
   36:         """set"""
   37:    
   38:         self._v_qs=qs
   39:         self.xsl=xsl
   40:         self.result=None        
   41: 
   42: #    def acquireLock(self):
   43: #    
   44: #         lock=getattr(self, "_v_lock", None)
   45: #         if not lock:
   46: #             self._v_lock=threading.Lock()
   47: #             lock=self._v_lock
   48: #         lock.acquire()
   49: #
   50: #    def releaseLock(self):
   51: #         # acquire() should have been called
   52: #         # about one second before. This means the volatile lock
   53: #         # should still be there
   54: #    
   55: #         self._v_lock.release()
   56: #        
   57:   
   58:     def __call__(self):
   59:         """wait"""
   60:         return True
   61:     
   62:     def run(self):
   63:         """call it"""
   64:         xml=""
   65: 
   66:         try:
   67:   
   68:             urlH=urllib.urlopen(self._v_qs)
   69:             xml=urlH.read()
   70:             urlH.close()
   71:             xsltproc=Processor()
   72:             document = InputSource.DefaultFactory.fromString(xml)
   73:             
   74:             stylesheet = InputSource.DefaultFactory.fromUri(self.xsl)
   75:             
   76:             xsltproc.appendStylesheet(stylesheet)
   77:             
   78:         
   79:             #print self.xsl
   80:             #< xsltproc.run(document)
   81:             tmp=xsltproc.run(document)
   82:             
   83:             self.result=tmp[0:]
   84:             
   85:         
   86:        	except:
   87:                
   88:                self.result="<html>error: %s %s<br>"%sys.exc_info()[0:2]
   89:                self.result+=xml
   90:                self.result+="</html>"
   91:         
   92:         
   93:     
   94:     def getResult(self):
   95: 
   96:         return self.result
   97: 
   98: from ZODB import DB
   99: from ZODB.FileStorage import FileStorage
  100: class ECHO_cache:
  101:     def __init__(self):
  102:         """init the storage"""
  103:         self.storage=FileStorage("/var/tmp/echo_cache.fs")
  104:         self.db=DB(self.storage)    
  105:         self.connection=self.db.open()
  106:         self.root=self.connection.root()
  107:     
  108:     def deleteObject(self,name,pn=None):
  109:         """delete an object from cache"""
  110:         fileStore=self.root.get(name,None)
  111:         if fileStore:
  112:             if not pn:
  113:                 del(self.root[name])
  114:             else:
  115:                 if self.root[name].get(pn,None):
  116:                     del(self.root[name][pn])
  117:                     
  118:         
  119:     def storeObject(self,name,pn,object):
  120:         """store an object"""
  121:         
  122:         if not self.root.get(name,None):
  123:             self.root[name]={}
  124:             
  125: 
  126:         #following is necessary to make clear that object has really changed for ZODB
  127:         tmp=self.root[name]
  128:         tmp[pn]=object
  129:         self.root[name]=tmp
  130:         transaction.get().commit()
  131:         return True
  132:    
  133:     def retrieveObject(self,name,pn):
  134:         """retrieve it"""
  135:         
  136:         fileStore=self.root.get(name,None)
  137:         if not fileStore:
  138:             return None
  139:         else:
  140:            
  141:             return self.root[name].get(pn,None)
  142:         
  143: 
  144: class ECHO_xslt(ECHO_pageTemplate,ECHO_language.ECHO_language):
  145:     """ECHO_xslt classe"""
  146: 
  147:     meta_type="ECHO_xslt"
  148:     
  149:     cache=ECHO_cache() # cache for analysed pages
  150:     caching="yes"
  151:     
  152:     appendQueryString=True # add query string to the cgiUrl can be changed with addChanges
  153:     
  154:     passURL=False #use url from querystring parameter fn to retrieve the text and not the url in cgi-url can be changed with addChanges
  155:         
  156:     
  157:     results={}
  158:     manage_options=ECHO_pageTemplate.manage_options+(
  159:      {'label':'Change xml-ressource','action':'change_ECHO_xsltForm'},)
  160:      
  161:     def refreshTxt(self):
  162:         """txt fuer refresh"""
  163:         return """ 2;url=%s?repeat=%s """%(self.absolute_url(),self.threadName)
  164: 
  165:     def xslt(self):
  166:         """xslt"""
  167: 
  168:         return self.document_src()
  169: 
  170:     def change_ECHO_xsltForm(self):
  171:         """change form"""
  172:         pt=zptFile(self, 'zpt/ChangeECHO_xsltForm.zpt')
  173:         return pt()
  174: 
  175:     def addChanges(self,cgiUrl,appendQueryString=False,passURL=False,caching=False,RESPONSE=None):
  176:         """change the xslt, ueberschriebt addChanges in ECHO_PageTemplate"""
  177:     
  178:         if urlparse.urlparse(cgiUrl)[0]=="":#relative url in absolute
  179:             self.cgiUrl=urlparse.urljoin(self.absolute_url(), cgiUrl)
  180:         else:
  181:             self.cgiUrl=cgiUrl
  182:         
  183:         if appendQueryString: 
  184:             self.appendQueryString=True
  185:         else:
  186:             self.appendQueryString=False
  187:         
  188:         if passURL:
  189:             self.passURL=True
  190:         else:
  191:             self.passURL=False
  192:        
  193:         if caching:
  194:             self.caching="yes"
  195:         else:
  196:             self.caching="No"
  197:         
  198: 
  199:         if RESPONSE:
  200:             RESPONSE.redirect("manage_main")
  201:         
  202:     def index_html(self,repeat=None):
  203:         """standard ausgabe"""
  204: 
  205:         threadName=repeat
  206:         
  207:         if not threadName or threadName=="":
  208:             
  209:             #abwaertskompatibilitŠt mit altem nivht konfigurierbaren prototypen
  210:             
  211:             if getattr(self,'cgiUrl','')=='':
  212:                 self.cgiUrl="http://medea.mpiwg-berlin.mpg.de/cgi-bin/search/q1"
  213:                 
  214:             qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
  215:             xsl=self.absolute_url()+"/xslt"
  216:             self._v_xmltrans=getXML().__of__(self)
  217:             #self._xmltrans.start()
  218:             thread=Thread(target=self._v_xmltrans)
  219:             thread.start()
  220:             self._v_xmltrans.set(qs,xsl,None)
  221:             self._v_xmltrans.run()
  222:             
  223:             
  224:             self.threadName=thread.getName()[0:]
  225:             wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
  226:             if wait_template:
  227:                 return wait_template[0][1]()
  228:             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
  229:             return pt()
  230:             #_v_xmltrans.run()
  231:         
  232:         else:
  233:             
  234:             if (self._v_xmltrans.getResult()==None):
  235: 
  236:                 wait_template=self.aq_parent.ZopeFind(self.aq_parent,obj_ids=['wait_template'])
  237:                 if wait_template:
  238:                         return wait_template[0][1]()
  239:                 
  240:                 pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','xsltWait.zpt')).__of__(self)
  241:                 return pt()
  242:             else:
  243:                 return self._v_xmltrans.getResult()
  244: 
  245:     
  246:     def getText(self):
  247:         """print nur den text"""
  248:         qs,baseUri=self.getTextInput()
  249:         self.REQUEST.RESPONSE.redirect(qs)
  250: 
  251:     def deleteCache(self):
  252:         """deletefrom cache"""
  253:         fn=self.REQUEST['fn']
  254:         self.cache.deleteObject(fn)
  255:         
  256:     
  257:     def createLinkNode(self,url,dom):
  258:         """createa a link node"""
  259:         txt=dom.createTextNode("<XMLLink>")
  260:         node=dom.createElementNS("http://test.de","a")
  261:         node.setAttributeNS("http://test.de","href",url)
  262:         node.appendChild(txt)
  263:         return node
  264:       
  265:     def forwardLink(self,linkid,url,type="target",RESPONSE=None):
  266:         """forward to link"""
  267:         if RESPONSE:
  268:             RESPONSE.redirect(self.getLink(linkid,url,type=type))
  269:             
  270:         else:
  271:             return self.getLink(linkid,url,type=type)
  272:     def getLink(self,linkid,url,type="target"):
  273:         """get target for linkid"""
  274:         dom=NonvalidatingReader.parseUri(url)
  275:         
  276:         masterurl=dom.xpath("//mpiwg:masterurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  277:         slaveurl=dom.xpath("//mpiwg:slaveurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  278:         
  279:         #check now if there are in the link file
  280:      
  281:         xp="//mpiwg:link[@id='%s']"%linkid
  282:         
  283:         if type=="target":
  284:             for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
  285:                 fn=link.xpath("mpiwg:target/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  286:                 ref=link.xpath("mpiwg:target/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  287:                 
  288:                 ref2=link.xpath("mpiwg:target/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  289:                 selectionNodeIndex=link.xpath("mpiwg:target/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  290:                              
  291:                 lstr=slaveurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s'%(ref2,selectionNodeIndex)
  292:                 lstr+="&_links="+urllib.quote(url)+'&_linkid='+linkid+'&_linktype=target'
  293:                 
  294:         else:
  295:             for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
  296:                 fn=link.xpath("mpiwg:source/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  297:                 ref=link.xpath("mpiwg:source/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  298:                 
  299:                 ref2=link.xpath("mpiwg:source/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  300:                 selectionNodeIndex=link.xpath("mpiwg:source/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  301:                              
  302:                 lstr=masterurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s'%(ref2,selectionNodeIndex)
  303:                 lstr+="&_links="+urllib.quote(url)+'&_linkid='+linkid+'&_linktype=source'
  304:         return lstr
  305:    
  306:     def addLinks(self,txt,url="http://127.0.0.1:8080/HFQP/linkCreator/getCollectionXML?collection=commentary2"):
  307:         """add links to a page from xml linkfile"""
  308:         
  309:         dom=NonvalidatingReader.parseUri(url)
  310:         textDom=NonvalidatingReader.parseString(txt)
  311: 
  312:         #find ids in txt
  313:         ids=textDom.xpath("//*[@id]")
  314:         masterurl=dom.xpath("//mpiwg:masterurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  315:         slaveurl=dom.xpath("//mpiwg:slaveurl/@ref",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  316:         
  317:         #check now if there are in the link file
  318:         for textid in ids:
  319:             xp="//mpiwg:link[mpiwg:source/@refid='%s']"%textid.xpath("@id")[0].value
  320:             for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
  321:                 fn=link.xpath("mpiwg:target/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  322:                 ref=link.xpath("mpiwg:target/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  323:                 
  324:                 ref2=link.xpath("mpiwg:target/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  325:                 selectionNodeIndex=link.xpath("mpiwg:target/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  326:                 linkid=link.xpath("@id")[0].value         
  327:                 lstr=slaveurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s'%(ref2,selectionNodeIndex)
  328:                 lstr+="&_links="+urllib.quote(url)+'&_url='+url+'&_linkid='+linkid+'&_linktype=target'
  329:                 node=self.createLinkNode(lstr,textDom)
  330:                 textid.parentNode.insertBefore(node,textid)
  331:               
  332:           
  333:             xp="//mpiwg:link[mpiwg:target/@refid='%s']"%textid.xpath("@id")[0].value
  334:             for link in dom.xpath(xp,explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
  335:                 fn=link.xpath("mpiwg:source/@filename",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  336:                 ref=link.xpath("mpiwg:source/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  337:                 
  338:                 ref2=link.xpath("mpiwg:source/mpiwg:pagelink/@refid",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  339:                 selectionNodeIndex=link.xpath("mpiwg:source/mpiwg:pagelink/@selectionNodeIndex",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})[0].value
  340:                 linkid=link.xpath("@id")[0].value                    
  341:                 lstr=masterurl+'fn='+fn+'&_id='+ref+'&_pagelink=%s///%s'%(ref2,selectionNodeIndex)
  342:                 lstr+="&_links="+urllib.quote(url)+'&_linkid='+linkid+'&_linktype=source'
  343:                 
  344:                 node=self.createLinkNode(lstr,textDom)
  345:                 textid.parentNode.insertBefore(node,textid)
  346:               
  347:             
  348:         
  349:         strio = StringIO()
  350:         PrettyPrint(textDom,strio) 
  351:         xmlstr = strio.getvalue()
  352:         
  353:         return xmlstr
  354: 
  355:             
  356:         
  357:     def getPageLex(self,_pn="1",_id=None,_caching=None,_links=None):
  358:         """getpage mit lexikalischer analyse und xslt transform
  359:         if _caching=yes dann wird die lwxikalisch analysierte seite in einem cache abgespeichert
  360:         """
  361: 
  362:         if not _caching:
  363:             _caching=self.caching
  364:             
  365:         fn=self.REQUEST['fn']
  366: 
  367:         if not _id:
  368:            
  369:             fromCache=self.cache.retrieveObject(fn,_pn)
  370:      
  371:             if fromCache and _caching=="yes":
  372:               
  373:                 txt = fromCache
  374:             else:
  375:                 txt=self.tagLex(nr=_pn)   
  376:               
  377:                 self.cache.storeObject(fn,_pn,txt[0:])
  378:             
  379:         else:
  380:            txt=self.tagLex(id=_id)
  381:       
  382:         xsl=self.xslt()
  383:         
  384:         xsltproc=Processor()
  385:         if type(txt)==UnicodeType:
  386:             document = InputSource.DefaultFactory.fromString(txt.encode('utf-8'))
  387:         else:
  388:             document = InputSource.DefaultFactory.fromString(txt)
  389:         stylesheet = InputSource.DefaultFactory.fromString(xsl)
  390:         xsltproc.appendStylesheet(stylesheet)
  391:         tmp=xsltproc.run(document)
  392:         
  393:         if _links:
  394:             _links=urllib.unquote(_links)
  395:             tmp=self.addLinks(tmp,url=_links)
  396:             
  397:         #bugfix for digilib images which doesn't accept &amp;
  398:         tmp=tmp.replace("&amp;","&")
  399:         
  400: 
  401:         return tmp[0:]
  402:             
  403:     def getTextInput(self):
  404:         """get the text
  405:         wie der text geholt wird liegt an der konfiguration,
  406:         is appendQueryString gesetzt, dann wir jeweils der Querystring an vorgebenen url gesetzt, erwartet wird fn=
  407:         fŸr den Pfad, is passURL gesetzt, dann wird falls fn= eine vollstŠndige url enthŠlt, diese anstelle der in cgiurl definierten genommen.
  408:         """
  409:         
  410:         if getattr(self,'passURL',False) and self.REQUEST.has_key('fn') and (urlparse.urlparse(self.REQUEST['fn'])[0]=='http'):
  411:             qs=self.REQUEST['fn']
  412:             baseUri=qs
  413:         elif getattr(self,'pappendQueryString',True):
  414:             qs="%s%s"%(self.cgiUrl,self.REQUEST['QUERY_STRING'])
  415:             baseUri=self.cgiUrl
  416:         else:
  417:             qs="%s"%(self.cgiUrl)
  418:             baseUri=self.cgiUrl
  419:         
  420:         #fact= InputSource.DefaultFactory.fromUri(qs)
  421:         return qs,baseUri
  422:         #return InputSource.InputSource(fact)
  423:         #xmlt=urllib.urlopen(qs).read()
  424:         
  425:     def getPage(self,_pn="-1",_id=None,REQUEST=None,_caching=None):
  426:         """get a page from an xml"""
  427:         
  428:         if not _caching:
  429:             _caching=self.caching
  430:             
  431:         pn=int(_pn)-1
  432:         if pn<0 and (not _id):
  433:             if REQUEST:
  434:                 return "Sorry, pagenumbers have to be greater than 0"
  435:             else:
  436:                 return None
  437:        
  438:         xmlt,self.baseUri=self.getTextInput()
  439:         
  440:         #get the text from cache, if existing
  441:         fromCache=self.cache.retrieveObject(self.baseUri,"-1")
  442:         if fromCache and _caching=="yes":
  443:           
  444:             txt = fromCache
  445:         else:
  446: 
  447:             txt=urllib.urlopen(xmlt).read()
  448:             
  449:             self.cache.storeObject(self.baseUri,"-1",txt)
  450:         
  451:         
  452:         dom=NonvalidatingReader.parseString(txt,self.baseUri)
  453:         
  454:         #pb should have a namespache
  455: 
  456:         pbs=dom.xpath("//mpiwg:pb",explicitNss={'mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
  457:         
  458:         if len(pbs)==0: # versuche nochmal ohne
  459:             pbs=dom.xpath("//pb")
  460: 
  461:         if _id:
  462:             #suche wieviele pb for der id
  463:             
  464:             
  465:             idpb=dom.xpath("//*[@id='%s']/preceding::node()/mpiwg:pb"%_id,explicitNss={'html':'http://test.de','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'})
  466:             if len(idpb)==0:
  467:                 idpb=dom.xpath("//*[@id='%s']/preceding::node()/pb"%_id)
  468:          
  469:             if len(idpb)==0:
  470:                         k=0
  471:                         for node in dom.xpath("//*[@id='%s']//preceding::node()"%_id,explicitNss={'html':'http://test.de','mpiwg':'http://www.mpiwg-berlin.mpg.de/namespace'}):
  472:                             if getattr(node,'tagName',"")=="mpiwg:pb":
  473:                                 k+=1
  474:             else:
  475:                 k=len(idpb)
  476:             pn=k-1 #-1 wegen Seitenzahlzaehlung startet mit 0
  477:             
  478:         if pn > len(pbs):
  479:             if REQUEST:
  480:                 return "Sorry, pagenumber %s does not exit"%(pn+1)
  481:             else:
  482:                 return None
  483:             
  484:         beginNode=pbs[pn] #take the n'th pb
  485: 
  486:         if not (pn==len(pbs)-1): # nicht die letzte Seite
  487:             endNode=pbs[pn+1]
  488:         else:
  489:             endNode=None
  490:         
  491:         deleteNodes=beginNode.xpath('preceding::node()')
  492:         if endNode:
  493:             deleteNodes+=endNode.xpath('following::node()')
  494:         for node in deleteNodes:
  495:             try:
  496:                 parent=node.xpath("..")
  497:            
  498:                 if parent:
  499:                     parent[0].removeChild(node)
  500:             except:
  501:                 zLOG.LOG("ECHO_Resource (getAccessRightMD)", zLOG.INFO,"%s (%s)"%sys.exc_info()[0:2])
  502:         strio = StringIO()
  503:         PrettyPrint(dom,strio) 
  504:         xmlstr = strio.getvalue()
  505:         
  506:         return xmlstr
  507: 
  508: 
  509:         
  510: def manage_addECHO_xsltForm(self):
  511:     """Form for adding"""
  512:     pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','AddECHO_xslt.zpt')).__of__(self)
  513:     return pt()
  514: 
  515: from urllib import quote
  516: 
  517: 
  518: def manage_addECHO_xslt(self, id, label, weight= 0,contentType=0,title=None, text=None, cgiUrl=None,
  519:                            REQUEST=None, submit=None):
  520:     "Add a Page Template with optional file content."
  521: 
  522:     
  523:     id = str(id)
  524:     if REQUEST is None:
  525:         self._setObject(id, ECHO_xslt(id, text))
  526:         ob = getattr(self, id)
  527:         setattr(ob,'weight',weight)
  528:         setattr(ob,'label',label)
  529:         setattr(ob,'contentType',contentType)
  530:         if title:
  531:             ob.pt_setTitle(title)
  532:         return ob
  533:         setattr(ob,'cgiUrl',cgiUrl)
  534:     else:
  535:         file = REQUEST.form.get('file')
  536:         headers = getattr(file, 'headers', None)
  537:         if headers is None or not file.filename:
  538:             zpt = ECHO_xslt(id)
  539:         else:
  540:             zpt = ECHO_xslt(id, file, headers.get('contentType'))
  541: 
  542:         self._setObject(id, zpt)
  543:         ob = getattr(self, id)
  544:         setattr(ob,'weight',weight)
  545:         setattr(ob,'label',label)
  546:         setattr(ob,'cgiUrl',cgiUrl)
  547:         if title:
  548:             ob.pt_setTitle(title)
  549:         
  550:         try:
  551:             u = self.DestinationURL()
  552:         except AttributeError:
  553:             u = REQUEST['URL1']
  554: 
  555:         if submit == " Add and Edit ":
  556:             u = "%s/%s" % (u, quote(id))
  557:         REQUEST.RESPONSE.redirect(u+'/manage_main')
  558:     return ''
  559: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>