changeset 35:38cbbeaf266b

more work on projects. responsibleScientistsList has new format.
author casties
date Thu, 25 Apr 2013 21:39:57 +0200
parents b8ced08ebea9
children dbe037d2f574
files MPIWGProjects.py MPIWGRoot.py zpt/project/edit_basic.zpt zpt/project/project_template.zpt
diffstat 4 files changed, 796 insertions(+), 692 deletions(-) [+]
line wrap: on
line diff
--- a/MPIWGProjects.py	Thu Apr 25 12:07:56 2013 +0200
+++ b/MPIWGProjects.py	Thu Apr 25 21:39:57 2013 +0200
@@ -20,7 +20,7 @@
 import re
 import os 
 import email
-import xmlhelper # Methoden zur Verwaltung der projekt xml
+import xmlhelper  # Methoden zur Verwaltung der projekt xml
 import xmlrpclib
 import sys
 from types import *
@@ -31,15 +31,15 @@
 from Products.MPIWGBibliography.BibliographyManager import BibliographyManager
 from bibliography import *
 from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder
-#import xml.dom.minidom
-#from Ft.Xml.XPath import Evaluate
-#from Ft.Xml.XPath.Context import Context
-#from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print
-#from Ft.Xml import EMPTY_NAMESPACE
-#import copy
-#import updatePersonalWWW
+# import xml.dom.minidom
+# from Ft.Xml.XPath import Evaluate
+# from Ft.Xml.XPath.Context import Context
+# from Ft.Xml.Domlette import NonvalidatingReader,PrettyPrint, Print
+# from Ft.Xml import EMPTY_NAMESPACE
+# import copy
+# import updatePersonalWWW
 
-#import MPIWGStaff
+# import MPIWGStaff
 
 from HashTree import HashTree
 from MPIWGHelper import *
@@ -52,7 +52,25 @@
 
 
 # TODO: fix this
-fieldLabels={'WEB_title':'WEB_Title',
+definedFields = ['WEB_title', 
+                 'xdata_01', 
+                 'xdata_02', 
+                 'xdata_03', 
+                 'xdata_04', 
+                 'xdata_05', 
+                 'xdata_06', 
+                 'xdata_07', 
+                 'xdata_08', 
+                 'xdata_09', 
+                 'xdata_10', 
+                 'xdata_11', 
+                 'xdata_12', 
+                 'xdata_13', 
+                 'WEB_project_header', 
+                 'WEB_project_description', 
+                 'WEB_related_pub']
+
+fieldLabels = {'WEB_title':'WEB_Title',
          'xdata_01':'Responsible Scientists',
          'xdata_02':'Department',
          'xdata_03':'Historical Persons',
@@ -88,136 +106,136 @@
 class MPIWGProject_publication(Folder):
     """publications object fuer project"""
 
-    meta_type="MPIWGProject_publication"
-    def redirect(self,RESPONSE,url):
+    meta_type = "MPIWGProject_publication"
+    def redirect(self, RESPONSE, url):
         """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
         
-        timeStamp=time.time()
+        timeStamp = time.time()
         
-        if url.find("?")>-1: #giebt es schon parameter
-            addStr="&time=%s"
+        if url.find("?") > -1:  # giebt es schon parameter
+            addStr = "&time=%s"
         else:
-            addStr="?time=%s"
+            addStr = "?time=%s"
             
-        RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
-        logging.debug(email.Utils.formatdate()+' GMT')
-        RESPONSE.redirect(url+addStr%timeStamp)
+        RESPONSE.setHeader('Last-Modified', email.Utils.formatdate().split("-")[0] + 'GMT')
+        logging.debug(email.Utils.formatdate() + ' GMT')
+        RESPONSE.redirect(url + addStr % timeStamp)
 
-    def hasLinkToBookPage(self,mode="not_cached"):
+    def hasLinkToBookPage(self, mode="not_cached"):
         """teste ob eingebener link zu einer MPIWG Book page geht"""
         
         
         logging.debug("MPIWGProject_publication - begin hasLinkToBookPage")
-        if (getattr(self,'link','')==''):
-            return False #es gibt keinen link
+        if (getattr(self, 'link', '') == ''):
+            return False  # es gibt keinen link
         
-        logging.debug("MPIWGProject_publication - begin hasLinkToBookPage:"+self.link)
+        logging.debug("MPIWGProject_publication - begin hasLinkToBookPage:" + self.link)
         server = xmlrpclib.ServerProxy(self.link)
         
-        if(mode=="cached"):
-            if (hasattr(self,"_v_hasLinkToBookPage")):
+        if(mode == "cached"):
+            if (hasattr(self, "_v_hasLinkToBookPage")):
                 logging.debug("haslink cached")
                 return self._v_hasLinkToBookPage
         
         try:
             server.getImageUrls()
             logging.debug("MPIWGProject_publication - end TRUE")
-            self._v_hasLinkToBookPage=True
+            self._v_hasLinkToBookPage = True
             return True
         except:
             logging.debug("MPIWGProject_publication - end FALSE ")
-            self._v_hasLinkToBookPage=True
+            self._v_hasLinkToBookPage = True
             return False
         
     
     
-    def getImageUrls(self,mode="not_cached"):
+    def getImageUrls(self, mode="not_cached"):
         """get the image urls"""
         
-        if (getattr(self,'link','')==''):
-            return [] #es gibt keinen link
+        if (getattr(self, 'link', '') == ''):
+            return []  # es gibt keinen link
         
         server = xmlrpclib.ServerProxy(self.link)
         
         
-        if(mode=="cached"):
-            if (hasattr(self,"_v_imageUrls")):
+        if(mode == "cached"):
+            if (hasattr(self, "_v_imageUrls")):
                 logging.debug("getImageURL cached")
                 return self._v_imageUrls
        
         try:
             urls = server.getImageUrls()
-            ret=[]
+            ret = []
             for url in urls:
-                url = os.path.join(self.link,url)
+                url = os.path.join(self.link, url)
                 ret.append(url)
            
         except:
-            self._v_imageUrls=[]
+            self._v_imageUrls = []
             return []
-        self._v_imageUrls=ret[0:]
+        self._v_imageUrls = ret[0:]
         return ret
         
-    def editPublication(self,text=None,image1=None,image2=None,description=None,link=None,RESPONSE=None):
+    def editPublication(self, text=None, image1=None, image2=None, description=None, link=None, RESPONSE=None):
         """edit a publication"""
 
         if (not text) and (not description):
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_publicationForm.zpt')).__of__(self)
+            pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_publicationForm.zpt')).__of__(self)
             return pt()
 
        
         if text:
-            self.text=text[0:]
+            self.text = text[0:]
         
         if description:
-            self.description=description
+            self.description = description
         
         if link:
-            self.link=link[0:]
+            self.link = link[0:]
         
         if image1:
-            if hasattr(self,'publicationImage1'):
+            if hasattr(self, 'publicationImage1'):
                 self.publicationImage1.manage_upload(image1)
             else:
-                nO = Image('publicationImage1','',image1)
-                self._setObject('publicationImage1',nO)
+                nO = Image('publicationImage1', '', image1)
+                self._setObject('publicationImage1', nO)
                 
         if image2:
-            if hasattr(self,'publicationImage2'):
+            if hasattr(self, 'publicationImage2'):
                 self.publicationImage2.manage_upload(image2)
             else:
-                nO = Image('publicationImage2','',image2)
-                self._setObject('publicationImage2',nO)
+                nO = Image('publicationImage2', '', image2)
+                self._setObject('publicationImage2', nO)
                    
 
         self.ZCacheable_invalidate()
         if RESPONSE:
-            self.redirect(RESPONSE,"../managePublications")
+            self.redirect(RESPONSE, "../managePublications")
 
 class MPIWGProject_relatedProject(Folder):
     """publications object fuer project"""
 
-    meta_type="MPIWGProject_relatedProject"
-    def redirect(self,RESPONSE,url):
+    meta_type = "MPIWGProject_relatedProject"
+    def redirect(self, RESPONSE, url):
         """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
         
-        timeStamp=time.time()
+        timeStamp = time.time()
         
-        if url.find("?")>-1: #giebt es schon parameter
-            addStr="&time=%s"
+        if url.find("?") > -1:  # giebt es schon parameter
+            addStr = "&time=%s"
         else:
-            addStr="?time=%s"
+            addStr = "?time=%s"
             
-        RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
-        logging.debug(email.Utils.formatdate()+' GMT')
-        RESPONSE.redirect(url+addStr%timeStamp)
+        RESPONSE.setHeader('Last-Modified', email.Utils.formatdate().split("-")[0] + 'GMT')
+        logging.debug(email.Utils.formatdate() + ' GMT')
+        RESPONSE.redirect(url + addStr % timeStamp)
 
         
-    def editRelatedProject(self,link=None,RESPONSE=None):
+    def editRelatedProject(self, link=None, RESPONSE=None):
         """edit a publication"""
 
         if (not link):
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_relatedProjectForm.zpt')).__of__(self)
+            pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_relatedProjectForm.zpt')).__of__(self)
             return pt()
 
        
@@ -225,78 +243,78 @@
       
         
         # hole die id des projektes
-        splitted=link.split("/")
+        splitted = link.split("/")
         
-        #teste ob es das project gibt
-        if len(splitted)<1:
-            self.redirect(RESPONSE,'errorRelatedProjects?link='+link)
+        # teste ob es das project gibt
+        if len(splitted) < 1:
+            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
         
-        objid=splitted[-1]
-        object = getattr(self.projects,objid,None)
+        objid = splitted[-1]
+        object = getattr(self.projects, objid, None)
         
-        if object==None:
-            self.redirect(RESPONSE,'errorRelatedProjects?link='+link)
+        if object == None:
+            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
         
       
 
         
        
-        self.orginallink=link[0:]
-        self.objid=objid[0:]
+        self.orginallink = link[0:]
+        self.objid = objid[0:]
     
-        self.projectWEB_title=object.getContent('WEB_title')[0:]
+        self.projectWEB_title = object.getContent('WEB_title')[0:]
        
-        self.enabled=True;
+        self.enabled = True;
         self.ZCacheable_invalidate()
        
         if RESPONSE:
-            self.redirect(RESPONSE,"../manageRelatedProjects")
+            self.redirect(RESPONSE, "../manageRelatedProjects")
 
 class MPIWGProject_image(Image):
     """Images for Projects"""
 
-    meta_type="MPIWGProject_image"
+    meta_type = "MPIWGProject_image"
 
-    def showImage(self,imageUrl=None):
+    def showImage(self, imageUrl=None):
         """show Images at an extra page"""
-        self.getContent('WEB_project_description',filter='yes') #get the content and store image infos into session
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','projectImageView.zpt')).__of__(self)
+        self.getContent('WEB_project_description', filter='yes')  # get the content and store image infos into session
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'projectImageView.zpt')).__of__(self)
         return pt()
     
-    def editImage(self,file=None,caption=None,RESPONSE=None):
+    def editImage(self, file=None, caption=None, RESPONSE=None):
         """edit the Image"""
         if (not file) and (not caption):
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_imageForm.zpt')).__of__(self)
+            pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_imageForm.zpt')).__of__(self)
             return pt()
 
-        if file and (not file.filename.lstrip().rstrip()==""):
+        if file and (not file.filename.lstrip().rstrip() == ""):
             self.manage_upload(file)
 
         if caption:
-            self.caption=caption[0:]
+            self.caption = caption[0:]
 
         if RESPONSE:
-            self.redirect(RESPONSE,"../manageImages")
+            self.redirect(RESPONSE, "../manageImages")
 
 
-class MPIWGProject(CatalogAware,Folder,Cacheable):
+class MPIWGProject(CatalogAware, Folder, Cacheable):
     """Class for Projects"""
     
     security = ClassSecurityInfo()
     meta_type = 'MPIWGProject'
     
-    manage_options = Folder.manage_options+(
-        {'label':'Load New File','action':'loadNewFileForm'},
-        {'label':'Edit','action':'editForm'},
+    manage_options = Folder.manage_options + (
+        {'label':'Load New File', 'action':'loadNewFileForm'},
+        {'label':'Edit', 'action':'editForm'},
         )
-        #{'label':'Edit ProjectInfo','action':'editMPIWGProjectForm'},
-        #{'label':'Edit BasisInfo','action':'editMPIWGBasisForm'},
-        #{'label':'Edit Publications','action':'editMPIWGRelatedPublicationsForm'},
-        #{'label':'Edit Themes & Disciplines','action':'editMPIWGDisciplinesThemesForm'},
-        #{'label':'Versionmanager','action':'versionManageForm'},
+        # {'label':'Edit ProjectInfo','action':'editMPIWGProjectForm'},
+        # {'label':'Edit BasisInfo','action':'editMPIWGBasisForm'},
+        # {'label':'Edit Publications','action':'editMPIWGRelatedPublicationsForm'},
+        # {'label':'Edit Themes & Disciplines','action':'editMPIWGDisciplinesThemesForm'},
+        # {'label':'Versionmanager','action':'versionManageForm'},
 
     # enthaelt die Lister der verantwortlichen Wissenschaftler in der Form (NAME, KEY), key ist "" falls Wissenschaftler nicht an unserem Haus
-    responsibleScientistsList=[]
+    responsibleScientistsList = []
 
     #
     # templates
@@ -304,102 +322,112 @@
     edit_css = ImageFile('css/edit.css', globals())
     # make css refreshable for development
     edit_css.index_html = refreshingImageFileIndexHtml
+    edit_basic = PageTemplateFile('zpt/project/edit_basic', globals())
     editForm = PageTemplateFile('zpt/project/edit_description', globals())
     edit_template = PageTemplateFile('zpt/project/edit_template', globals())
+    project_template = PageTemplateFile('zpt/project/project_template', globals())
+
     # TODO: compat
     edit_MPIWGProject_main = edit_template
 
 
     def __init__(self, id, argv=None):
         """initiere classe"""
-
-        self.creationTime=time.strftime("%Y%m%d%H%M%S",time.localtime())[0:]
-        self.id=id
-        self.title=id
-        self.isActiveFlag=True #Flag is true is the project is still active, False if accomplished
-        self.responsibleScientistsList=[] # enthaelt die Lister der verantwortlichen Wissenschaftler in der Form (NAME, KEY), key ist "" flass Wissenschaftler nicht an unserem Haus
+        self.creationTime = time.strftime("%Y%m%d%H%M%S", time.localtime())[0:]
+        self.id = id
+        self.title = id
+        self.isActiveFlag = True  # Flag is true is the project is still active, False if accomplished
+        self.responsibleScientistsList = []  # enthaelt die Lister der verantwortlichen Wissenschaftler in der Form (NAME, KEY), key ist "" flass Wissenschaftler nicht an unserem Haus
         
         if argv:
             for arg in definedFields:
                 try:
-                        setattr(self,arg,argv[arg])
+                        setattr(self, arg, argv[arg])
                 except:
-                        setattr(self,arg,"")
+                        setattr(self, arg, "")
         else:
             for arg in definedFields:
-                setattr(self,arg,'')
+                setattr(self, arg, '')
             
 
-    def redirect(self,RESPONSE,url):
+    def index_html(self):
+        """default html representation"""
+        # TODO: do we need to do date-stuff?
+        # get template
+        pt = getattr(self, 'project_template')
+        # render template
+        return pt()
+
+    def redirect(self, RESPONSE, url):
         """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
         
-        timeStamp=time.time()
+        timeStamp = time.time()
         
-        if url.find("?")>-1: #giebt es schon parameter
-            addStr="&time=%s"
+        if url.find("?") > -1:  # giebt es schon parameter
+            addStr = "&time=%s"
         else:
-            addStr="?time=%s"
+            addStr = "?time=%s"
             
-        RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
-        logging.debug(email.Utils.formatdate()+' GMT')
-        RESPONSE.redirect(url+addStr%timeStamp)
+        RESPONSE.setHeader('Last-Modified', email.Utils.formatdate().split("-")[0] + 'GMT')
+        logging.debug(email.Utils.formatdate() + ' GMT')
+        RESPONSE.redirect(url + addStr % timeStamp)
 
-    def decode(self,str):
+    def decode(self, str):
         """return unicode object"""
         return unicodify(str)
 
-    def isCheckField(self,fieldname):
+    def isCheckField(self, fieldname):
         """return chechfield"""
         return (fieldname in checkFields)
  
-    def sortedByPlace(self,metatype):
+    def sortedByPlace(self, metatype):
         """find metatype and sort by place"""
-        def sort(x,y):
-            return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
+        def sort(x, y):
+            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
 
-        logging.debug("MPIWGProjects begin: sorted by place: "+ metatype)
-        founds=self.ZopeFind(self,obj_metatypes=[metatype]);
+        logging.debug("MPIWGProjects begin: sorted by place: " + metatype)
+        founds = self.ZopeFind(self, obj_metatypes=[metatype]);
         
         founds.sort(sort)
-        logging.debug("MPIWGProjects end: sorted by place: "+ metatype)
+        logging.debug("MPIWGProjects end: sorted by place: " + metatype)
         return founds
     
 
-    def copyPublicationsToList(self,RESPONSE=None):
+    def copyPublicationsToList(self, RESPONSE=None):
         """copy publications in to list"""
 
-        publicationTxt=self.getContent('WEB_related_pub')
+        publicationTxt = self.getContent('WEB_related_pub')
 
-        pubSplits=publicationTxt.split("<p>")
+        pubSplits = publicationTxt.split("<p>")
 
         for pubSplit in pubSplits:
-            pubSplit=pubSplit.replace("</p>","")
+            pubSplit = pubSplit.replace("</p>", "")
             self.addPublication(pubSplit)
 
-        setattr(self,"WEB_related_pub_copied",True);
+        setattr(self, "WEB_related_pub_copied", True);
         
         if RESPONSE:
                 
-            self.redirect(RESPONSE,'managePublications')
+            self.redirect(RESPONSE, 'managePublications')
         
     def hasRelatedPublicationsOldVersion(self):
         """teste ob es related publications gibt"""
         
         ret = True;
-        if (self.getContent('WEB_related_pub')==''):
-            ret=False;  #nichts im alten feld
-        logging.debug("webrel:"+repr(ret))
-        if (getattr(self,'WEB_related_pub_copied',False)):
-            ret=False; # alte daten sind schon kopiert worden
+        if (self.getContent('WEB_related_pub') == ''):
+            ret = False;  # nichts im alten feld
+        logging.debug("webrel:" + repr(ret))
+        if (getattr(self, 'WEB_related_pub_copied', False)):
+            ret = False;  # alte daten sind schon kopiert worden
         
-        logging.debug("webrel_copied:"+repr(ret))
-        publications=self.ZopeFind(self,obj_metatypes=['MPIWGProject_publication']);
+        logging.debug("webrel_copied:" + repr(ret))
+        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication']);
         
-        if(len(publications)>0):
-            ret=False; # es gibt publicationen in der neuen liste
+        if(len(publications) > 0):
+            ret = False;  # es gibt publicationen in der neuen liste
       
         
-        logging.debug("len(publ)"+repr(ret))
+        logging.debug("len(publ)" + repr(ret))
         
         return ret;
     
@@ -407,7 +435,7 @@
         """test ob es digital sources gibt"""
         
         
-        ret = (self.getContent('xdata_11').lstrip().rstrip()=='')
+        ret = (self.getContent('xdata_11').lstrip().rstrip() == '')
             
       
       
@@ -416,21 +444,21 @@
         
     
     
-    def copyImageToMargin(self,RESPONSE=None):  
+    def copyImageToMargin(self, RESPONSE=None):  
         """copy inline images to marginal images"""
         
         
-        #getImages from WEB_project_description
-        description=self.getContent('WEB_project_description')
+        # getImages from WEB_project_description
+        description = self.getContent('WEB_project_description')
         
-        text2=description
-        splitted=text2.split("""<p class="picture">""")
+        text2 = description
+        splitted = text2.split("""<p class="picture">""")
         
-        imageURLs=[]
-        imageCaptions=[]
+        imageURLs = []
+        imageCaptions = []
         for split in  splitted[1:]:
-                tmp=split.split("</p>")
-                #return repr(splitted[1])
+                tmp = split.split("</p>")
+                # return repr(splitted[1])
                 
                 try:
                         imageURLs.append(tmp[0].split("\"")[1].encode('utf-8'))
@@ -441,144 +469,144 @@
                     except:
                         imageURLs.append("")
                 
-                split2="</p>".join(tmp[1:])
+                split2 = "</p>".join(tmp[1:])
 
 
-                splitted=split2.split("""<p class="picturetitle">""")
-                if len(splitted)>1:
-                    tmp=splitted[1].split("</p>")
+                splitted = split2.split("""<p class="picturetitle">""")
+                if len(splitted) > 1:
+                    tmp = splitted[1].split("</p>")
                     imageCaptions.append(tmp[0].encode('utf-8'))
 
 
                 else:
-                    #keine caption
+                    # keine caption
 
                     imageCaptions.append("")
   
      
-        #eintragen:
+        # eintragen:
         for imageURL in imageURLs:
-            filename=imageURL.split("/")[-1]
-            #lege neues images object an, mit leerem bild
+            filename = imageURL.split("/")[-1]
+            # lege neues images object an, mit leerem bild
 
-            if self.ZopeFind(self,obj_ids=[filename]):
-                #existiert das bild schon, dann neuen filenamen
-                filename="project_image_"+filename
+            if self.ZopeFind(self, obj_ids=[filename]):
+                # existiert das bild schon, dann neuen filenamen
+                filename = "project_image_" + filename
             
-            self.addImage(None,imageCaptions[imageURLs.index(imageURL)],filename=filename)
-            #hole die bilddaten aus der url
-            url=self.absolute_url()+"/"+imageURL
-            #url=self.absolute_url()+"/"+filename
+            self.addImage(None, imageCaptions[imageURLs.index(imageURL)], filename=filename)
+            # hole die bilddaten aus der url
+            url = self.absolute_url() + "/" + imageURL
+            # url=self.absolute_url()+"/"+filename
         
-            try:#relative url
-                data=urllib.urlopen(url).read()
+            try:  # relative url
+                data = urllib.urlopen(url).read()
             except:
-                try:#absolute
-                    data=urllib.urlopen(self.imageURL).read()
+                try:  # absolute
+                    data = urllib.urlopen(self.imageURL).read()
                 except:
-                    logger("MPIWG Project",logging.ERROR,"can't open: %s"%url)
+                    logger("MPIWG Project", logging.ERROR, "can't open: %s" % url)
             
-            obj=getattr(self,filename)
+            obj = getattr(self, filename)
             obj.update_data(data)
         
         if RESPONSE:
         
-            self.redirect(RESPONSE,'manageImages')
+            self.redirect(RESPONSE, 'manageImages')
             
-    def manageImages(self,imageName=None,op=None):
+    def manageImages(self, imageName=None, op=None):
         """managage images"""
         if imageName and op:
-            if op=='up':
-                images=self.getImages()
+            if op == 'up':
+                images = self.getImages()
                 for image in images:
-                    if image[0]==imageName:
-                        nr=images.index(image)
-                        if not nr==0:
-                            images[nr-1][1].place+=1
-                            images[nr][1].place-=1
+                    if image[0] == imageName:
+                        nr = images.index(image)
+                        if not nr == 0:
+                            images[nr - 1][1].place += 1
+                            images[nr][1].place -= 1
                         pass
-            elif op=='down':
-                images=self.getImages()
+            elif op == 'down':
+                images = self.getImages()
                 for image in images:
-                    if image[0]==imageName:
-                        nr=images.index(image)
-                        if not (nr==len(images)-1):
-                            images[nr+1][1].place-=1
-                            images[nr][1].place+=1
+                    if image[0] == imageName:
+                        nr = images.index(image)
+                        if not (nr == len(images) - 1):
+                            images[nr + 1][1].place -= 1
+                            images[nr][1].place += 1
                         pass
 
 
         pt = PageTemplateFile('zpt/project/edit_images', globals()).__of__(self)
         return pt()
 
-    def managePublications(self,pubName=None,op=None):
+    def managePublications(self, pubName=None, op=None):
         """managage images"""
         if pubName and op:
-            if op=='up':
-                publications=self.getPublications()
+            if op == 'up':
+                publications = self.getPublications()
                 for publication in publications:
-                    if publication[0]==pubName:
-                        nr=publications.index(publication)
-                        if not nr==0:
-                            publications[nr-1][1].place+=1
-                            publications[nr][1].place-=1
+                    if publication[0] == pubName:
+                        nr = publications.index(publication)
+                        if not nr == 0:
+                            publications[nr - 1][1].place += 1
+                            publications[nr][1].place -= 1
                         pass
-            elif op=='down':
-                publications=self.getPublications()
+            elif op == 'down':
+                publications = self.getPublications()
                 for publication in publications:
-                    if publication[0]==pubName:
-                        nr=publications.index(publication)
-                        if not (nr==len(publications)-1):
-                            publications[nr+1][1].place-=1
-                            publications[nr][1].place+=1
+                    if publication[0] == pubName:
+                        nr = publications.index(publication)
+                        if not (nr == len(publications) - 1):
+                            publications[nr + 1][1].place -= 1
+                            publications[nr][1].place += 1
                         pass
 
 
-        pt=PageTemplateFile('zpt/project/edit_publications', globals()).__of__(self)
+        pt = PageTemplateFile('zpt/project/edit_publications', globals()).__of__(self)
         return pt()
     
-    def manageRelatedProjects(self,pubName=None,op=None):
+    def manageRelatedProjects(self, pubName=None, op=None):
         """managage relatedProjectd"""
         if pubName and op:
-            if op=='up':
-                relatedProjects=self.getRelatedProjects()
+            if op == 'up':
+                relatedProjects = self.getRelatedProjects()
                 for project in relatedProjects:
-                    if project[0]==pubName:
-                        nr=relatedProjects.index(project)
-                        if not nr==0:
-                            relatedProjects[nr-1][1].place+=1
-                            relatedProjects[nr][1].place-=1
+                    if project[0] == pubName:
+                        nr = relatedProjects.index(project)
+                        if not nr == 0:
+                            relatedProjects[nr - 1][1].place += 1
+                            relatedProjects[nr][1].place -= 1
                         pass
-            elif op=='down':
-                relatedProjects=self.getRelatedProjects()
+            elif op == 'down':
+                relatedProjects = self.getRelatedProjects()
                 for project in relatedProjects:
-                    if project[0]==pubName:
-                        nr=relatedProjects.index(project)
-                        if not (nr==len(relatedProjects)-1):
-                            relatedProjects[nr+1][1].place-=1
-                            relatedProjects[nr][1].place+=1
+                    if project[0] == pubName:
+                        nr = relatedProjects.index(project)
+                        if not (nr == len(relatedProjects) - 1):
+                            relatedProjects[nr + 1][1].place -= 1
+                            relatedProjects[nr][1].place += 1
                         pass
 
 
-        pt=PageTemplateFile('zpt/project/edit_related_projects', globals()).__of__(self)
+        pt = PageTemplateFile('zpt/project/edit_related_projects', globals()).__of__(self)
         return pt()
     
     
     def hasExtendedPublicationList(self):
         """test if extended publication list exists"""
-        if not hasattr(self,"publicationList"):
+        if not hasattr(self, "publicationList"):
             return False
         else:
             return True
         
-    def createExtendedPublicationList(self,RESPONSE=None):
+    def createExtendedPublicationList(self, RESPONSE=None):
         """erzeuge erweiterte publications liste"""
-        pl = BibliographyManager("publicationList","","institutsbiblio",self.connection_id)
+        pl = BibliographyManager("publicationList", "", "institutsbiblio", self.connection_id)
         self._setObject("publicationList", pl)
         
     
-        zt=ZopePageTemplate('index.html')
-        pl._setObject('index.html',zt)
+        zt = ZopePageTemplate('index.html')
+        pl._setObject('index.html', zt)
         default_content_fn = os.path.join(package_home(globals()),
                                               'zpt/showExtendedProjectBibliography.zpt')
         text = open(default_content_fn).read()
@@ -586,126 +614,126 @@
 
     
         if RESPONSE:
-            self.redirect(RESPONSE,"managePublications")
+            self.redirect(RESPONSE, "managePublications")
 
             
     def getPublications(self):
         """get all Publications"""
-        def sort_images(x,y):
-            return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
+        def sort_images(x, y):
+            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
 
-        publications=self.ZopeFind(self,obj_metatypes=['MPIWGProject_publication'])
+        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_publication'])
         
         publications.sort(sort_images)
         return publications
 
     def getRelatedProjects(self):
         """get all Publications"""
-        def sort_images(x,y):
-            return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
+        def sort_images(x, y):
+            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
 
-        publications=self.ZopeFind(self,obj_metatypes=['MPIWGProject_relatedProject'])
+        publications = self.ZopeFind(self, obj_metatypes=['MPIWGProject_relatedProject'])
         
         publications.sort(sort_images)
         return publications
 
-    def addPublication(self,text,RESPONSE=None):
+    def addPublication(self, text, RESPONSE=None):
         """add an MPIWG_Publication"""
-        number=self.getLastPublicationNumber()+1
-        name="publication_"+str(number)
-        while hasattr(self,name):
-            number+=1
-            name="publication_"+str(number)
+        number = self.getLastPublicationNumber() + 1
+        name = "publication_" + str(number)
+        while hasattr(self, name):
+            number += 1
+            name = "publication_" + str(number)
         
-        newPublication=MPIWGProject_publication(name)
+        newPublication = MPIWGProject_publication(name)
 
-        self._setObject(name,newPublication)
-        obj=getattr(self,name)
-        obj.text=text[0:]
-        obj.enabled=True;
-        obj.place=self.getLastPublicationNumber()+1
-        obj.id=name
+        self._setObject(name, newPublication)
+        obj = getattr(self, name)
+        obj.text = text[0:]
+        obj.enabled = True;
+        obj.place = self.getLastPublicationNumber() + 1
+        obj.id = name
         self.ZCacheable_invalidate()
         if RESPONSE is not None:
         
-            self.redirect(RESPONSE,'managePublications')
+            self.redirect(RESPONSE, 'managePublications')
 
-    def errorRelatedProjects(self,link):
+    def errorRelatedProjects(self, link):
         """error creating a related project"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_project_error_relatedProject.zpt')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_project_error_relatedProject.zpt')).__of__(self)
         return pt(link=link)
 
-    def addRelatedProject(self,link,RESPONSE=None):
+    def addRelatedProject(self, link, RESPONSE=None):
         """add an MPIWG_Publication"""
-        number=self.getLastPublicationNumber()+1
-        name="RelatedProject"+str(number)
-        while hasattr(self,name):
-            number+=1
-            name="RelatedProject_"+str(number)
+        number = self.getLastPublicationNumber() + 1
+        name = "RelatedProject" + str(number)
+        while hasattr(self, name):
+            number += 1
+            name = "RelatedProject_" + str(number)
         
         # hole die id des projektes
-        splitted=link.split("/")
+        splitted = link.split("/")
         
-        #teste ob es das project gibt
-        if len(splitted)<1:
-            self.redirect(RESPONSE,'errorRelatedProjects?link='+link)
+        # teste ob es das project gibt
+        if len(splitted) < 1:
+            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
         
-        objid=splitted[-1]
-        object = getattr(self.projects,objid,None)
+        objid = splitted[-1]
+        object = getattr(self.projects, objid, None)
         
-        if object==None:
-            self.redirect(RESPONSE,'errorRelatedProjects?link='+link)
+        if object == None:
+            self.redirect(RESPONSE, 'errorRelatedProjects?link=' + link)
             return
         
-        newPublication=MPIWGProject_relatedProject(name)
+        newPublication = MPIWGProject_relatedProject(name)
 
-        self._setObject(name,newPublication)
-        obj=getattr(self,name)
-        obj.orginallink=link[0:]
-        obj.objid=objid[0:]
-        logging.debug("add relobj:objid"+repr(obj.objid))
-        obj.projectWEB_title=object.getContent('WEB_title')[0:]
-        logging.debug("add relobj:webtitle"+repr(obj.projectWEB_title))
-        obj.enabled=True;
-        obj.place=self.getLastRelatedProjectNumber()+1
-        obj.id=name
+        self._setObject(name, newPublication)
+        obj = getattr(self, name)
+        obj.orginallink = link[0:]
+        obj.objid = objid[0:]
+        logging.debug("add relobj:objid" + repr(obj.objid))
+        obj.projectWEB_title = object.getContent('WEB_title')[0:]
+        logging.debug("add relobj:webtitle" + repr(obj.projectWEB_title))
+        obj.enabled = True;
+        obj.place = self.getLastRelatedProjectNumber() + 1
+        obj.id = name
         self.ZCacheable_invalidate()
         if RESPONSE is not None:
-            self.redirect(RESPONSE,'manageRelatedProjects')
+            self.redirect(RESPONSE, 'manageRelatedProjects')
 
  
     
     def getLastPublicationNumber(self):
-        publications=self.getPublications()
+        publications = self.getPublications()
        
         if not publications:
             return 0
         else:
-            return getattr(publications[-1][1],'place',0)
+            return getattr(publications[-1][1], 'place', 0)
         
     def getLastRelatedProjectNumber(self):
-        publications=self.getRelatedProjects()
+        publications = self.getRelatedProjects()
         
         if not publications:
             return 0
         else:
-            return getattr(publications[-1][1],'place',0)
+            return getattr(publications[-1][1], 'place', 0)
         
-    def deletePublication(self,id,RESPONSE=None):
+    def deletePublication(self, id, RESPONSE=None):
             """delete Publication id"""
             self.manage_delObjects([id])
             self.ZCacheable_invalidate()
             if RESPONSE:
         
-                self.redirect(RESPONSE,'managePublications')
+                self.redirect(RESPONSE, 'managePublications')
               
-    def deleteRelatedProject(self,id,RESPONSE=None):
+    def deleteRelatedProject(self, id, RESPONSE=None):
             """delete Publication id"""
             self.manage_delObjects([id])
             self.ZCacheable_invalidate()
             if RESPONSE:
         
-                self.redirect(RESPONSE,'manageRelatedProjects')
+                self.redirect(RESPONSE, 'manageRelatedProjects')
 
 
     def getNumber(self):
@@ -717,13 +745,61 @@
         else:
             return n
     
+    
+    def getProjectTitle(self):
+        """returns the project title"""
+        t = getattr(self, 'WEB_title', None)
+        if isinstance(t, list):
+            # compat with old lists
+            return t[0]
+        else:
+            return t
+    
+    def getResponsibleScientists(self):
+        """returns the responsible scientists as string"""
+        t = getattr(self, 'xdata_01', None)
+        if isinstance(t, list):
+            # compat with old lists
+            return t[0]
+        else:
+            return t
+    
+    
+    def getResponsibleScientistsList(self):
+        """returns a list with the responsible scientists as dicts with name, key, and shortname"""
+        return self.responsibleScientistsList
+
+    
+    def setResponsibleScientistsList(self, nameDict):
+        """sets the responsibleScientistsList from nameDict.
+        List will be ordered like the responsible scientists field."""
+        names = self.getResponsibleScientists()
+        if names.find(";") > -1:  # rate Trenner ist ;
+            nameList = names.split(";")  
+        else:
+            nameList = names.split(",")
+            
+        scientistsList = []
+        for name in nameList:
+            name = unicodify(name.strip())
+            logging.debug("setResponsibleScientistsList: name=%s"%repr(name))
+            if name in nameDict:
+                # found in data
+                data = nameDict[name]
+                scientistsList.append({'name': name, 'key': data['key'], 'username': data['username']})
+            else:
+                scientistsList.append({'name': name})
+        
+        logging.debug("setResponsibleScientistsList: nameDict=%s new list=%s"%(repr(nameDict),repr(scientistsList)))
+        self.responsibleScientistsList = scientistsList
+        
               
     def getUrl(self, baseUrl=None):
         """returns URL to this Project"""
         if baseUrl is None:
             return self.absolute_url()
 
-        return '%s/%s'%(baseUrl, self.getId())
+        return '%s/%s' % (baseUrl, self.getId())
                 
               
     def getThumbUrl(self, default='http://defaultthumb.jpg'):
@@ -741,99 +817,99 @@
         """returns the sorted list of images for this project"""
         items = self.objectValues(spec='MPIWGProject_image')[:]
         # sort by place
-        items.sort(key=lambda x:int(getattr(x,'place',0)))
+        items.sort(key=lambda x:int(getattr(x, 'place', 0)))
         return items          
 
               
     def getImages(self):
         """get all Images"""
 
-        def sort_images(x,y):
-            return cmp(getattr(x[1],'place',0),getattr(y[1],'place',0))
+        def sort_images(x, y):
+            return cmp(getattr(x[1], 'place', 0), getattr(y[1], 'place', 0))
 
 
-        if (getattr(self,'imageURL','')!='') or  (getattr(self,'imagecap','')!='')  :
+        if (getattr(self, 'imageURL', '') != '') or  (getattr(self, 'imagecap', '') != '')  :
             try:
-                self.addImage(None,getattr(self,'imagecap',''),RESPONSE=None,filename=getattr(self,'imageURL',''))
+                self.addImage(None, getattr(self, 'imagecap', ''), RESPONSE=None, filename=getattr(self, 'imageURL', ''))
             except:
                 pass
-            self.imageURL=''
-            self.imagecap=''
+            self.imageURL = ''
+            self.imagecap = ''
 
-        images=self.ZopeFind(self,obj_metatypes=['MPIWGProject_image'])
+        images = self.ZopeFind(self, obj_metatypes=['MPIWGProject_image'])
         
         images.sort(sort_images)
         return images
 
     def getLastImageNumber(self):
-        images=self.getImages()
+        images = self.getImages()
         
         if not images:
             return 0
         else:
-            return getattr(images[-1][1],'place',0)
+            return getattr(images[-1][1], 'place', 0)
         
-    def deleteImage(self,id,RESPONSE=None):
+    def deleteImage(self, id, RESPONSE=None):
         """delete Image id"""
         try:
                 self.manage_delObjects([id])
         except:
-                logging.error("ERROR MPIWG: %s %s"%sys.exc_info()[0:2])
+                logging.error("ERROR MPIWG: %s %s" % sys.exc_info()[0:2])
         if RESPONSE:
-            self.redirect(RESPONSE,'manageImages')
+            self.redirect(RESPONSE, 'manageImages')
 
 
  
-    def hasChildren(self,date=None,onlyActive=1,onlyArchived=1):
+    def hasChildren(self, date=None, onlyActive=1, onlyArchived=1):
         """check if project has children"""
         
-        ct=self.getContexts(childs=self.getContent('xdata_05'),
-                                 depth=1,date=date,onlyActive=onlyActive)
+        ct = self.getContexts(childs=self.getContent('xdata_05'),
+                                 depth=1, date=date, onlyActive=onlyActive)
         
-        if ct and len(ct)>0:
+        if ct and len(ct) > 0:
              return True
         else:
              return False
 
          
-    def addImage(self,fileHd,caption,RESPONSE=None,filename=None):
+    def addImage(self, fileHd, caption, RESPONSE=None, filename=None):
         """add an MPIWG_Project_image"""
 
         if not filename:
-            filename=fileHd.filename
+            filename = fileHd.filename
 
         if not fileHd:
-            fileHd=file(os.path.join(package_home(globals()),'blank.gif'))
+            fileHd = file(os.path.join(package_home(globals()), 'blank.gif'))
             
-        newImage=MPIWGProject_image(filename,filename,fileHd)
+        newImage = MPIWGProject_image(filename, filename, fileHd)
 
-        self._setObject(filename,newImage)
-        obj=getattr(self,filename)
-        obj.caption=caption[0:]
-        obj.enabled=True;
-        obj.place=self.getLastImageNumber()+1
-        obj.id=filename
+        self._setObject(filename, newImage)
+        obj = getattr(self, filename)
+        obj.caption = caption[0:]
+        obj.enabled = True;
+        obj.place = self.getLastImageNumber() + 1
+        obj.id = filename
 
         if RESPONSE is not None:
             
-            self.redirect(RESPONSE,'manageImages')
+            self.redirect(RESPONSE, 'manageImages')
 
     def versionHeader(self):
         """version Header, gibt header text entsprechend der aktuellen version aus"""
         
-        actualTime=time.localtime()
-        retTXT="""<h2>This is an outdated version, for the actual version please refer to <a href="%s">%s</a></h2>"""
-        s=self.aq_parent.absolute_url()
-        #print getattr(self,'archiveTime',actualTime)
-        if getattr(self,'archiveTime',actualTime)< actualTime:
-            return retTXT%(s,s)
+        actualTime = time.localtime()
+        retTXT = """<h2>This is an outdated version, for the actual version please refer to <a href="%s">%s</a></h2>"""
+        s = self.aq_parent.absolute_url()
+        # print getattr(self,'archiveTime',actualTime)
+        if getattr(self, 'archiveTime', actualTime) < actualTime:
+            return retTXT % (s, s)
         else:
             return ""
 
-    def getActualVersion(self,date=None):
+    def getActualVersion(self, date=None):
         """actuelle version"""
-        def sortProjectsByTime(x,y):
-            return cmp(x[1].archiveTime,y[1].archiveTime)
+        def sortProjectsByTime(x, y):
+            return cmp(x[1].archiveTime, y[1].archiveTime)
 
         if not date:
             if self.isActual():
@@ -841,12 +917,12 @@
             else:
                 return None
 
-        #suche ob aeltere versionen vorhanden sind
+        # suche ob aeltere versionen vorhanden sind
 
-        finds=self.ZopeFind(self,obj_metatypes=['MPIWGProject'])
-        if not finds: #wenn nicht dann teste ob die aktuelle version schon existiert hat.
-            ad=getattr(self,'creationTime','20050101000000')
-            if int(date)>int(ad):
+        finds = self.ZopeFind(self, obj_metatypes=['MPIWGProject'])
+        if not finds:  # wenn nicht dann teste ob die aktuelle version schon existiert hat.
+            ad = getattr(self, 'creationTime', '20050101000000')
+            if int(date) > int(ad):
                 return self
             else:
                 return None
@@ -855,14 +931,14 @@
             finds.sort(sortProjectsByTime)
 
         for find in finds:
-            #gehe durch die alten Projekte und finde das entprechende
-            if (int(find[1].archiveTime) > int(date)) and (int(date)>int(getattr(find[1],'creationTime','20050101000000'))):
+            # gehe durch die alten Projekte und finde das entprechende
+            if (int(find[1].archiveTime) > int(date)) and (int(date) > int(getattr(find[1], 'creationTime', '20050101000000'))):
                 return find[1]
 
-        #kein passendes gefunden, dann teste ob das aktuelle in frage kommt
-        ad=getattr(self,'creationTime','20050101000000')
+        # kein passendes gefunden, dann teste ob das aktuelle in frage kommt
+        ad = getattr(self, 'creationTime', '20050101000000')
         
-        if int(date)>int(ad):
+        if int(date) > int(ad):
         
             return self
         else:
@@ -871,11 +947,11 @@
         
     def isActual(self):
         """gibt 1 zurueck wenn aktuell, 0 sonst"""
-        actualTime=time.localtime()
+        actualTime = time.localtime()
         
         
-        #print getattr(self,'archiveTime',actualTime)
-        if getattr(self,'archiveTime',actualTime)< actualTime:
+        # print getattr(self,'archiveTime',actualTime)
+        if getattr(self, 'archiveTime', actualTime) < actualTime:
             return 0
         else:
             return 1
@@ -883,25 +959,25 @@
     def copyObjectToArchive(self):
         """kopiere aktuelles objekt ins archiv"""
         logging.info("copytoarchive 1")
-        cb=self.aq_parent.manage_copyObjects(self.getId())
+        cb = self.aq_parent.manage_copyObjects(self.getId())
         logging.info("copytoarchive 2")
         self.manage_pasteObjects(cb)
         logging.info("copytoarchive 3")
-        actualTime=time.localtime()
+        actualTime = time.localtime()
         
-        self.manage_renameObject(self.getId(),self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime))
+        self.manage_renameObject(self.getId(), self.getId() + "_" + time.strftime("%Y%m%d%H%M%S", actualTime))
         logging.info("copytoarchive 4")
-        obj=getattr(self,self.getId()+"_"+time.strftime("%Y%m%d%H%M%S",actualTime))
-        obj.setArchiveTime(time.strftime("%Y%m%d%H%M%S",actualTime))
+        obj = getattr(self, self.getId() + "_" + time.strftime("%Y%m%d%H%M%S", actualTime))
+        obj.setArchiveTime(time.strftime("%Y%m%d%H%M%S", actualTime))
         logging.info("copytoarchive 5")
-        ids=[x[0] for x in self.ZopeFind(obj,obj_metatypes=['MPIWGProject'])]
+        ids = [x[0] for x in self.ZopeFind(obj, obj_metatypes=['MPIWGProject'])]
         logging.info("copytoarchive 6")
         obj.manage_delObjects(ids)
         logging.info("copytoarchive 7")
         
-    def setArchiveTime(self,time):
+    def setArchiveTime(self, time):
         """set Archive Time"""
-        self.archiveTime=time[0:]
+        self.archiveTime = time[0:]
         
     def delArchiveTime(self):
         """delete archive time"""
@@ -909,28 +985,28 @@
 
     def versionManageForm(self):
         """version Manage form:currently only set to invisible"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_versionManageForm.zpt')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_versionManageForm.zpt')).__of__(self)
         return pt()
 
-    def versionManage(self,invisible=None,RESPONSE=None):
+    def versionManage(self, invisible=None, RESPONSE=None):
         """version Manage form:currently only set to invisible"""
-        self.invisible=invisible
+        self.invisible = invisible
 
         if RESPONSE is not None:
-            self.redirect(RESPONSE,'manage_main')
+            self.redirect(RESPONSE, 'manage_main')
 
    
     def crossLinker(self):
         """experimental crosslinker"""
-        splitted=self.WEB_project_description[0].split()
-        new=[]
+        splitted = self.WEB_project_description[0].split()
+        new = []
         for split in splitted:
             try:
-                found=self.DescriptionCatalog({'fulltext':split})
+                found = self.DescriptionCatalog({'fulltext':split})
           
-                if len(found)>1:
+                if len(found) > 1:
              
-                    new.append("<a href=%s>%s</a>"%(split,split))
+                    new.append("<a href=%s>%s</a>" % (split, split))
                 else:
                     new.append(split)
             except:
@@ -940,24 +1016,24 @@
             
 
 
-    def generateTemplate(self,RESPONSE=None):
+    def generateTemplate(self, RESPONSE=None):
         """Erzeuge Template fuer defined fields not_used"""
 
-        id="index_html"
-        title=id
+        id = "index_html"
+        title = id
         if self._getOb('index_html'):
             self._delObject('index_html')
 
         
-        newObj=ZopePageTemplate(id,'TEXT')
-        self._setObject(id,newObj)
-        #self.manage_addPageTemplate(id,title)
+        newObj = ZopePageTemplate(id, 'TEXT')
+        self._setObject(id, newObj)
+        # self.manage_addPageTemplate(id,title)
         if RESPONSE is not None:
-            self.redirect(RESPONSE,'manage_main')
+            self.redirect(RESPONSE, 'manage_main')
             
     def isActiveProject(self):
         """check if the project is still active, default is true, set to false is the project is accomplished"""
-        return getattr(self,'isActiveFlag',True)
+        return getattr(self, 'isActiveFlag', True)
  
     def checkActive(self, active):
         """returns if the project state matches the active state.
@@ -965,14 +1041,14 @@
         active = 1 : active projects
         active = 2 : inactive projects
         """
-        act = getattr(self,'isActiveFlag',True)
+        act = getattr(self, 'isActiveFlag', True)
         return (active == 1 and act) or (active == 0) or (active == 2 and not act)
  
     def isArchivedProject(self):
         """check if the project is archived"""
-        completed=self.getCompletedAt()
-        #completed leer 
-        if completed=="" :
+        completed = self.getCompletedAt()
+        # completed leer 
+        if completed == "" :
             return False;
         if completed == 0:
             return False;
@@ -988,44 +1064,44 @@
         arch = self.isArchivedProject()
         return (archived == 1 and not arch) or (archived == 0) or (archived == 2 and arch)        
         
-    def setActiveFlag(self,status=True):
+    def setActiveFlag(self, status=True):
         """set the active flag"""
-        self.isActiveFlag=status
+        self.isActiveFlag = status
         
-    def setCompletedAt(self,date):
+    def setCompletedAt(self, date):
         """set the date of completion, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY"""
-        #logging.info("DATE:"+repr(date))
-        transformedDate=self.transformDate(date);
-        #logging.info("transformed"+repr(transformedDate))
+        # logging.info("DATE:"+repr(date))
+        transformedDate = self.transformDate(date);
+        # logging.info("transformed"+repr(transformedDate))
         if transformedDate is not None:
-            setattr(self,"completedAt",transformedDate)
+            setattr(self, "completedAt", transformedDate)
             return True;
         else:
             return False;
     
-    def setStartedAt(self,date):
+    def setStartedAt(self, date):
         """set the date of start, date should be in the form DD.MM.YYYY or MM.YYYY or YYYY"""
-        #logging.info("DATE:"+repr(date))
-        transformedDate=self.transformDate(date);
-        #logging.info("transformed"+repr(transformedDate))
+        # logging.info("DATE:"+repr(date))
+        transformedDate = self.transformDate(date);
+        # logging.info("transformed"+repr(transformedDate))
         if transformedDate is not None:
-            setattr(self,"startedAt",transformedDate)
+            setattr(self, "startedAt", transformedDate)
             return True;
         else:
             return False;
 
     def getCompletedAt(self):
         """gibt das transformierte Datum zurueck, an dem das Projekt beendet wurde."""
-        date=getattr(self,'completedAt','')
+        date = getattr(self, 'completedAt', '')
       
         if date:
             return self.reTransformDate(date);
         else:
             return ""
             # test ob parent abgeschlossen ist
-            try:          #TODO: ersetzte try except durch vernuenftige abfrage  
-                ct=self.getContexts(parents=self.getContent('xdata_05'),depth=1)
-                if (len(ct)>0): #is there are parent
+            try:  # TODO: ersetzte try except durch vernuenftige abfrage  
+                ct = self.getContexts(parents=self.getContent('xdata_05'), depth=1)
+                if (len(ct) > 0):  # is there are parent
                         return ct[0][0].getCompletedAt()
                 return '';
             except:
@@ -1033,153 +1109,153 @@
         
     def getStartedAt(self):
         """gibt das transformierte Datum zurueck, an dem Projekt begonnen wurde."""
-        date=getattr(self,'startedAt','')
+        date = getattr(self, 'startedAt', '')
         if date:
             return self.reTransformDate(date);
         else:
             return '';
         
-    def reTransformDate(self,date):
+    def reTransformDate(self, date):
         """transformiert , transformdate zurueck"""
-        year=int(date/10000)
-        month=int((date-year*10000)/100)
-        day=int((date-year*10000-month*100))
-        if (day==0) and (month==0):
-            return """%s"""%year;
-        if day==0 :
-            return """%s.%s"""%(month,year);
+        year = int(date / 10000)
+        month = int((date - year * 10000) / 100)
+        day = int((date - year * 10000 - month * 100))
+        if (day == 0) and (month == 0):
+            return """%s""" % year;
+        if day == 0 :
+            return """%s.%s""" % (month, year);
         
-        return """%s.%s.%s"""%(day,month,year);
+        return """%s.%s.%s""" % (day, month, year);
         
         
-    def transformDate(self,date):
+    def transformDate(self, date):
         """transformiert ein Datum von DD.MM.YYYY, MM.YYYY,YYYY nach  YYYYMMDD, alle nicht angebenen Werte
         werden auf 0 gesetzt, es wird null zurueckgegeben falls das Datum ungueltig ist""" 
    
-        if (date==None):
+        if (date == None):
             return None;
         
           
-        if (date.lstrip().rstrip()=="" ) :
+        if (date.lstrip().rstrip() == "") :
             return "";
         
-        splitted=date.split(".")
-        length=len(splitted)
-        year=0
-        month=0
-        day=0
+        splitted = date.split(".")
+        length = len(splitted)
+        year = 0
+        month = 0
+        day = 0
         if length > 3:
             return "";
-        if length==3:
+        if length == 3:
             day = int(splitted[0])
-        if length>1:
-            month=int(splitted[length-2])
+        if length > 1:
+            month = int(splitted[length - 2])
         
         if length > 0:
             try:
-                year = int(splitted[length-1])
+                year = int(splitted[length - 1])
             except:
                 pass
         
-       ## logging.info("month:"+(month))
-        if not (0<=month<13):
+       # # logging.info("month:"+(month))
+        if not (0 <= month < 13):
             return None;
         
-        if not(0<=day<32):
+        if not(0 <= day < 32):
             return None;
         
-        if (year>0) and (year<1900): #jahr nicht vierstellig eingegeben
-            year=2000+year;
-        return year*10000+month*100+day
+        if (year > 0) and (year < 1900):  # jahr nicht vierstellig eingegeben
+            year = 2000 + year;
+        return year * 10000 + month * 100 + day
         
         
     
-    def checkDate(self,date):
+    def checkDate(self, date):
         """teste ob zum Zeitpunkt date eine andere version existierte"""
         
 
-        def sortProjectsByTime(x,y):
-            return cmp(x[1].archiveTime,y[1].archiveTime)
+        def sortProjectsByTime(x, y):
+            return cmp(x[1].archiveTime, y[1].archiveTime)
 
-        #suche ob aeltere versionen vorhanden sind
+        # suche ob aeltere versionen vorhanden sind
 
-        finds=self.ZopeFind(self,obj_metatypes=['MPIWGProject'])
-        if not finds: #wenn nicht dann teste ob die aktuelle version schon existiert hat.
-            ad=getattr(self,'creationTime','20050101000000')
-            if int(date)>int(ad):
-                return self.REQUEST['URL1']+"/"+self.getId()
+        finds = self.ZopeFind(self, obj_metatypes=['MPIWGProject'])
+        if not finds:  # wenn nicht dann teste ob die aktuelle version schon existiert hat.
+            ad = getattr(self, 'creationTime', '20050101000000')
+            if int(date) > int(ad):
+                return self.REQUEST['URL1'] + "/" + self.getId()
             else:
-                return self.REQUEST['URL1']+"/no_project"
+                return self.REQUEST['URL1'] + "/no_project"
 
 
         else:
             finds.sort(sortProjectsByTime)
 
         for find in finds:
-            #gehe durch die alten Projekte und finde das entprechende
-            if (int(find[1].archiveTime) > int(date)) and (int(date)>int(getattr(find[1],'creationTime','20050101000000'))):
-                return self.REQUEST['URL1']+"/"+find[1].getId()
+            # gehe durch die alten Projekte und finde das entprechende
+            if (int(find[1].archiveTime) > int(date)) and (int(date) > int(getattr(find[1], 'creationTime', '20050101000000'))):
+                return self.REQUEST['URL1'] + "/" + find[1].getId()
 
-        #kein passendes gefunden, dann teste ob das aktuelle in frage kommt
-        ad=getattr(self,'creationTime','20050101000000')
+        # kein passendes gefunden, dann teste ob das aktuelle in frage kommt
+        ad = getattr(self, 'creationTime', '20050101000000')
         
-        if int(date)>int(ad):
+        if int(date) > int(ad):
         
-            return self.REQUEST['URL1']+"/"+self.getId()
+            return self.REQUEST['URL1'] + "/" + self.getId()
         else:
-            return self.REQUEST['URL1']+"/no_project"
+            return self.REQUEST['URL1'] + "/no_project"
         
             
     def no_project(self):
         """warnung: project noch nicht existent"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','no_project')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'no_project')).__of__(self)
         return pt()
     
   
-    def harvest_page(self,context=None,mode="normal"):
+    def harvest_page(self, context=None, mode="normal"):
         """seite fuer harvesting fuer die Projektsuche"""
        
         if not context:
-            context=self
+            context = self
             
         if self.isActiveProject() and self.isActual():
              templates = self.en.getHarvestCache()
             
-             ext=getattr(self,"harvest_main",None)
+             ext = getattr(self, "harvest_main", None)
              if ext:
-                 rendered = getattr(self,ext.getId())()
-                 templates[self.absolute_url()]=rendered
+                 rendered = getattr(self, ext.getId())()
+                 templates[self.absolute_url()] = rendered
                  transaction.commit()
                  return rendered
                  
 
-             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','harvest_main')).__of__(context)    
+             pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'harvest_main')).__of__(context)    
              
              rendered = pt()
-             templates[self.absolute_url()]=rendered
+             templates[self.absolute_url()] = rendered
              transaction.commit()
              return rendered
                  
  
       
-    def index_html(self,request=True,context=None):
+    def index_html_old(self, request=True, context=None):
         """show homepage"""
     
-        bound_names={}
+        bound_names = {}
          
         if not context:
-            context=self
+            context = self
         if request:
-            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected',None)==None:
-                self.REQUEST.SESSION['MPI_redirected']=1
-                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date'])+"?date="+self.REQUEST['date'])
+            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected', None) == None:
+                self.REQUEST.SESSION['MPI_redirected'] = 1
+                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date']) + "?date=" + self.REQUEST['date'])
             else:
-                self.REQUEST.SESSION['MPI_redirected']=None
+                self.REQUEST.SESSION['MPI_redirected'] = None
         
-        #ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
+        # ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
       
    
-        request2=getattr(self,'REQUEST',None)
+        request2 = getattr(self, 'REQUEST', None)
         
         if request2 is not None:
             response = request2.response
@@ -1207,9 +1283,9 @@
         security.addContext(self)
 
         try:
-            #logging.debug("index_html pt=%s"%repr(pt))
+            # logging.debug("index_html pt=%s"%repr(pt))
             result = pt.pt_render(extra_context=bound_names)
-            #logging.debug("index_html result=%s"%repr(result))
+            # logging.debug("index_html result=%s"%repr(result))
             if keyset is not None:
                 # Store the result in the cache.
                 self.ZCacheable_set(result, keywords=keyset)
@@ -1220,34 +1296,34 @@
        
 
       
-    def index_html_old(self,request=True,context=None):
+    def index_html_old2(self, request=True, context=None):
         """show homepage"""
         if not context:
-            context=self
+            context = self
         if request:
-            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected',None)==None:
-                self.REQUEST.SESSION['MPI_redirected']=1
-                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date'])+"?date="+self.REQUEST['date'])
+            if self.REQUEST.has_key('date') and self.REQUEST.SESSION.get('MPI_redirected', None) == None:
+                self.REQUEST.SESSION['MPI_redirected'] = 1
+                self.REQUEST.RESPONSE.redirect(self.checkDate(self.REQUEST['date']) + "?date=" + self.REQUEST['date'])
             else:
-                self.REQUEST.SESSION['MPI_redirected']=None
+                self.REQUEST.SESSION['MPI_redirected'] = None
         
-        #ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
+        # ext=self.ZopeFind(self.aq_parent,obj_ids=["project_main"])
       
-        ext=getattr(self,"project_main",None)
+        ext = getattr(self, "project_main", None)
         if ext:
-            return getattr(self,ext.getId())()
+            return getattr(self, ext.getId())()
         
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','project_main')).__of__(context)    
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'project_main')).__of__(context)    
 
         return pt()
 
     
     def getDataFields(self):
         """giveListofDatafields"""
-        ret=[]
-        for x in range(1,14):
-            if not x in [6,10,9]: # not used fields
-                ret.append('xdata_%02i'%x)
+        ret = []
+        for x in range(1, 14):
+            if not x in [6, 10, 9]:  # not used fields
+                ret.append('xdata_%02i' % x)
         return ret
             
     def getDefinedFields(self):
@@ -1255,150 +1331,150 @@
         
         return definedFields
 
-    def getAttribute(self,field):
+    def getAttribute(self, field):
         """get attrbiute"""
-        return getattr(self,field)
+        return getattr(self, field)
 
-    def getContent(self,field,filter=None):
+    def getContent(self, field, filter=None):
         """Inhalt des Feldes"""
-        #logging.debug("getContent field=%s filter=%s"%(field,filter))
+        # logging.debug("getContent field=%s filter=%s"%(field,filter))
         
-        if field=="short_title":
+        if field == "short_title":
                 text = self.getContent("xdata_07")
-                if text=="":
+                if text == "":
                         text = self.getContent("WEB_title")
                 return text
 
-        text=u''
+        text = u''
 
-        f = getattr(self,field)
+        f = getattr(self, field)
         if isinstance(f, list):
             # compat with old lists
             for x in f:
                 try:
-                    text +=x
+                    text += x
                 except:
                     text = x
         else:
             text = f
 
         try:
-            if text[len(text)-1]==";":
-                text=text[0:len(text)-1]
+            if text[len(text) - 1] == ";":
+                text = text[0:len(text) - 1]
                 
         except:
             pass
         
-        if text=='': ## wozu die folgenden Zeilen??
-            text2=text
+        if text == '':  # # wozu die folgenden Zeilen??
+            text2 = text
         else:
-            text2=re.sub(r';([^\s])','; \g<1>',text)
+            text2 = re.sub(r';([^\s])', '; \g<1>', text)
        
-        if field=="WEB_project_description":##Jedenfalls darf letzteres nicht gemacht werden, falls normaler text
-            text2=text
+        if field == "WEB_project_description":  # #Jedenfalls darf letzteres nicht gemacht werden, falls normaler text
+            text2 = text
             
-        #teste ob ergebnis leer und header dann nehme title
+        # teste ob ergebnis leer und header dann nehme title
         
-        if (text2=='') and (field=='WEB_project_header'):
+        if (text2 == '') and (field == 'WEB_project_header'):
             return self.getContent('WEB_title')
 
         if filter:
-            splitted=text2.split("""<p class="picture">""")
-            if len(splitted)>1:
-                tmp=splitted[1].split("</p>")
-                #return repr(splitted[1])
+            splitted = text2.split("""<p class="picture">""")
+            if len(splitted) > 1:
+                tmp = splitted[1].split("</p>")
+                # return repr(splitted[1])
                 try:
-                        self.imageURL=tmp[0].split("\"")[1].encode('utf-8')
+                        self.imageURL = tmp[0].split("\"")[1].encode('utf-8')
                 except:
                     try:
-                        self.imageURL=tmp[0].split("src=")[1].split(" ")[0].encode('utf-8')
+                        self.imageURL = tmp[0].split("src=")[1].split(" ")[0].encode('utf-8')
                     except:
-                        self.imageURL=""
+                        self.imageURL = ""
 
-                split2="</p>".join(tmp[1:])
+                split2 = "</p>".join(tmp[1:])
 
-                text3=splitted[0]+split2
+                text3 = splitted[0] + split2
 
-                splitted=text3.split("""<p class="picturetitle">""")
-                if len(splitted)>1:
-                    tmp=splitted[1].split("</p>")
-                    self.imagecap=tmp[0].encode('utf-8')
+                splitted = text3.split("""<p class="picturetitle">""")
+                if len(splitted) > 1:
+                    tmp = splitted[1].split("</p>")
+                    self.imagecap = tmp[0].encode('utf-8')
                 
-                    split4="".join(tmp[1:])
+                    split4 = "".join(tmp[1:])
 
-                    text5=splitted[0]+split4
+                    text5 = splitted[0] + split4
                 else:
-                    #keine caption
-                    text5=text3
+                    # keine caption
+                    text5 = text3
             else:
-                #kein bild
-                text5=text2
+                # kein bild
+                text5 = text2
         else:
-            text5=text2
+            text5 = text2
 
-        #teste ob WEB_project_description und keine fuehrenden p tags
-        if (len(text5)>4) and (not text5[0:3]=='<p>') and (field=='WEB_project_description'):
-            text5= "<p>"+text5+"</p>"
+        # teste ob WEB_project_description und keine fuehrenden p tags
+        if (len(text5) > 4) and (not text5[0:3] == '<p>') and (field == 'WEB_project_description'):
+            text5 = "<p>" + text5 + "</p>"
 
 
-        #filter image
+        # filter image
         
-        text5=text5.lstrip().rstrip() #loescher leerzeichen und einzelndes br
-        if (text5=="<br>") or (text5=="<br/>"):
-            text5=""
+        text5 = text5.lstrip().rstrip()  # loescher leerzeichen und einzelndes br
+        if (text5 == "<br>") or (text5 == "<br/>"):
+            text5 = ""
 
-        #logging.debug("getcontent: field=%s filter=%s -> %s"%(field,filter,repr(text5)))
+        # logging.debug("getcontent: field=%s filter=%s -> %s"%(field,filter,repr(text5)))
         return unicodify(text5)
-        #return utf8ify(text5) # return as utf-8 byte string
+        # return utf8ify(text5) # return as utf-8 byte string
 
 
-    def showImagesOfPage(self,imageUrl=None):
+    def showImagesOfPage(self, imageUrl=None):
         """show Images of project"""
-        self.getContent('WEB_project_description',filter='yes') #get the content and store image infos into session
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','projectImageView.zpt')).__of__(self)
+        self.getContent('WEB_project_description', filter='yes')  # get the content and store image infos into session
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'projectImageView.zpt')).__of__(self)
         return pt()
         
     
     def show_html(self):
         """simple index"""
-        #return "HI"
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_index.zpt')).__of__(self)
+        # return "HI"
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_index.zpt')).__of__(self)
         return pt()
 
     def saveFromPreview(self):
         """save content aus preview"""
-        self.WEB_project_description=self.previewTemplate.WEB_project_description[0:]
+        self.WEB_project_description = self.previewTemplate.WEB_project_description[0:]
         self.REQUEST.RESPONSE.redirect("./index.html")
         
-    def saveEditedContent(self,kupu=None,preview=None):
+    def saveEditedContent(self, kupu=None, preview=None):
         """save Edited content"""
-        #logging.debug("saveEditedContent kupu=%s preview=%s"%(kupu,preview))
+        # logging.debug("saveEditedContent kupu=%s preview=%s"%(kupu,preview))
 
         if preview:
-            kupu=preview
-        #find content of body tags
-        start=kupu.find("<body>")
-        end=kupu.find("</body>")
-        newcontent= kupu[start+6:end]
+            kupu = preview
+        # find content of body tags
+        start = kupu.find("<body>")
+        end = kupu.find("</body>")
+        newcontent = kupu[start + 6:end]
      
         if preview:
             return self.preview(newcontent)
 
         self.copyObjectToArchive()
         self.ZCacheable_invalidate()
-        self.WEB_project_description=newcontent[0:]
+        self.WEB_project_description = newcontent[0:]
        
         self.REQUEST.RESPONSE.redirect("./index.html")
         
         return True
 
-    security.declareProtected('View management screens','edit')
-    def edit(self,western=None):
+    security.declareProtected('View management screens', 'edit')
+    def edit(self, western=None):
         """Edit pages"""
         if western:
-            self.REQUEST.RESPONSE.setCookie("MP_debug_code","western",path="/")
+            self.REQUEST.RESPONSE.setCookie("MP_debug_code", "western", path="/")
 
-        #pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProjectNeu.zpt')).__of__(self)
+        # pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProjectNeu.zpt')).__of__(self)
         pt = self.editForm
         return pt()
     
@@ -1432,56 +1508,56 @@
         
         # try to get acquisition URL from parent
         if hasattr(parent, 'absolute_url'):
-            baseUrl = "%s/%s/"%(parent.absolute_url(), 'projects')
+            baseUrl = "%s/%s/" % (parent.absolute_url(), 'projects')
         else:
             baseUrl = "/en/research/projects/"
             
         # add in the internal project hierarchy
         
-        ct=self.getContexts(parents=self.getContent('xdata_05'))
+        ct = self.getContexts(parents=self.getContent('xdata_05'))
         # start with grandparents
         ct.reverse()
         for c in ct:
             label = shortenString(c[0].getLabel(), 13)
-            crumbs.append((label, baseUrl+c[0].getId(), c[0]))            
+            crumbs.append((label, baseUrl + c[0].getId(), c[0]))            
 
         # add this project
-        crumbs.append((self.getLabel(), baseUrl+self.getId(), self))
+        crumbs.append((self.getLabel(), baseUrl + self.getId(), self))
             
         return crumbs
 
     def getRootProject(self):
         """returns the root (=top level) project of the current project"""
         
-        ct=self.getContexts(parents=self.getContent('xdata_05'))
+        ct = self.getContexts(parents=self.getContent('xdata_05'))
         if len(ct) > 0:
             return ct[-1][0]
         else:
             return self        
 
 
-    def preview(self,description):
+    def preview(self, description):
         """preview"""
-        #logging.debug("preview description=%s"%description)
-        tmpPro=getattr(self,"previewTemplate",None)
+        # logging.debug("preview description=%s"%description)
+        tmpPro = getattr(self, "previewTemplate", None)
         if not tmpPro:
-            tmpPro=MPIWGProject("previewTemplate")
-            self._setObject("previewTemplate",tmpPro)
+            tmpPro = MPIWGProject("previewTemplate")
+            self._setObject("previewTemplate", tmpPro)
         for field in definedFields:
-            setattr(tmpPro,field,getattr(self,field))
-        tmpPro.WEB_project_description=description[0:]
-        tmpPro.invisible=True
-        pt=PageTemplateFile('zpt/previewFrame.zpt',globals()).__of__(self)
+            setattr(tmpPro, field, getattr(self, field))
+        tmpPro.WEB_project_description = description[0:]
+        tmpPro.invisible = True
+        pt = PageTemplateFile('zpt/previewFrame.zpt', globals()).__of__(self)
         return pt()
 
-        #return self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+"/previewTemplate")
+        # return self.REQUEST.RESPONSE.redirect(self.REQUEST['URL1']+"/previewTemplate")
         
 
     def getWebProject_description(self):
         """get description"""
-        debug = self.REQUEST.cookies.get("MP_debug_code",None)
+        debug = self.REQUEST.cookies.get("MP_debug_code", None)
         
-        if debug and debug=="western":
+        if debug and debug == "western":
             return """
             <html>
             <head>
@@ -1489,7 +1565,7 @@
             </head>
             <body>%s</body>
             </html>
-            """%self.WEB_project_description[0]
+            """ % self.WEB_project_description[0]
         
         return """
             <html>
@@ -1498,57 +1574,54 @@
             </head>
             <body>%s</body>
             </html>
-            """%self.getContent('WEB_project_description')
+            """ % self.getContent('WEB_project_description')
         
         
         
     def editMPIWGProjectForm(self):
         """editform"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGProject.zpt')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGProject.zpt')).__of__(self)
         return pt()
 
-    def isResponsibleScientist(self,key):
+    def isResponsibleScientist(self, key):
         """teste ob eine Person in der Liste der respl. scientists auftaucht"""
-        keys = [unicodify(x[1]) for x in getattr(self,"responsibleScientistsList",[])]
-        #logging.error("RESP. SCIEN:%s"%getattr(self,"responsibleScientistsList",[]))
-        #logging.error("RESP. SCIEN:%s"%unicodify(key))
+        for resp in self.getResponsibleScientistsList():
+            if resp['key'] == key:
+                return True
         
-        if unicodify(key) in keys:
-            return True
-        else:
-            return False
+        return False
         
     def getPersonKeyList(self):
         """gibt die key Liste der beteiligten Personen zurueck (utf8 codiert)"""
-        #logging.error("getPersonKeyList:%s"%getattr(self,'responsibleScientistsList',[]))
+        # logging.error("getPersonKeyList:%s"%getattr(self,'responsibleScientistsList',[]))
         try:
-            return [utf8ify(x[1]) for x in getattr(self,'responsibleScientistsList',[])]
+            return [utf8ify(x[1]) for x in getattr(self, 'responsibleScientistsList', [])]
         except:
             return[]
         
        
-    def myCapitalize(self,txt):
+    def myCapitalize(self, txt):
         """kapitalisiere auch Namen mit -"""
-        splitted=[x.capitalize() for x in txt.split("-")]
+        splitted = [x.capitalize() for x in txt.split("-")]
         return "-".join(splitted)
     
-    def getNamesOrdered(self,list):
+    def getNamesOrdered(self, list):
         """Sortiert die Liste nach der Reihenfolge in xdata_01"""
         
-        nameList=self.getContent('xdata_01')
-        if nameList.find(";")>-1: # rate Trenner ist ;
-            names=nameList.split(";")  
+        nameList = self.getContent('xdata_01')
+        if nameList.find(";") > -1:  # rate Trenner ist ;
+            names = nameList.split(";")  
         else:
-            names=nameList.split(",")
+            names = nameList.split(",")
             
-        self._v_names=[]
+        self._v_names = []
         for name in names:
             self._v_names.append(name.rstrip().lstrip())
             
             
-        def sort(x,y):
+        def sort(x, y):
             try:
-                return cmp(self._v_names.index(x[0]),self._v_names.index(y[0]))
+                return cmp(self._v_names.index(x[0]), self._v_names.index(y[0]))
             except:
                 return 0
             
@@ -1557,7 +1630,7 @@
         return list
         
         
-    def identifyNames(self,nameList):
+    def identifyNames(self, nameList):
         """Bekommt eine Komma oder Semikolon getrennte Liste mit Name der Form Vorname MittelName(n) Nachname
         und ordnet diese dann Mitarbeiter IDs zu.
         
@@ -1565,31 +1638,31 @@
         
         @param nameList
         """
-        if nameList.find(";")>-1: # rate Trenner ist ;
-            names=nameList.split(";")  
+        if nameList.find(";") > -1:  # rate Trenner ist ;
+            names = nameList.split(";")  
         else:
-            names=nameList.split(",")
+            names = nameList.split(",")
             
-        ##nameList=nameList.replace(";",",") # falls ; als Trenner ersetze    
-        returnNamesDict={}
+        # #nameList=nameList.replace(";",",") # falls ; als Trenner ersetze    
+        returnNamesDict = {}
        
         for name in names:
-            name=name.strip()
+            name = name.strip()
             nameSplitted = name.split(" ")
-            if len(nameSplitted)>1:  #vor und nachname angegeben)
-                lastname=nameSplitted[-1]
-                firstname=nameSplitted[0]
+            if len(nameSplitted) > 1:  # vor und nachname angegeben)
+                lastname = nameSplitted[-1]
+                firstname = nameSplitted[0]
             else:
-                firstname =""
-                lastname=nameSplitted[0]
+                firstname = ""
+                lastname = nameSplitted[0]
                
-            #finde Mitarbeiter mit den entsprechenden Name
+            # finde Mitarbeiter mit den entsprechenden Name
             
-            #firstname=self.myCapitalize(firstname).encode('utf-8')
-            #lastname=self.myCapitalize(lastname).encode('utf-8')
-            logging.debug("Search: %s %s %s"%(name,repr(firstname),repr(lastname)))
+            # firstname=self.myCapitalize(firstname).encode('utf-8')
+            # lastname=self.myCapitalize(lastname).encode('utf-8')
+            logging.debug("Search: %s %s %s" % (name, repr(firstname), repr(lastname)))
             try:
-                #cataloggedNames=self.MembersCatalog(firstName=firstname,lastName=lastname)
+                # cataloggedNames=self.MembersCatalog(firstName=firstname,lastName=lastname)
                 # TODO: I think this does not work without firstname
                 # try to find names in members db by searching for sub-words
                 cataloggedNames = self.executeZSQL("select * from personal_www where first_name ~* ('\m'||%s||'\M') and last_name ~* ('\m'||%s||'\M')", (firstname, lastname))
@@ -1597,171 +1670,183 @@
                     # PostgreSQL has a bug with \m and words ending in non-ASCII :-(
                     cataloggedNames = self.executeZSQL("select * from personal_www where %s in (select regexp_split_to_table(lower(first_name), '\s+')) and %s in (select regexp_split_to_table(lower(last_name), '\s+'))", (firstname.lower(), lastname.lower()))
             except:
-                cataloggedNames=[]
-                logging.error("ERROR: identifyNames %s %s"%sys.exc_info()[0:2])
+                cataloggedNames = []
+                logging.error("ERROR: identifyNames %s %s" % sys.exc_info()[0:2])
             
-            if len(cataloggedNames)>0:
-               returnNamesDict[name]=cataloggedNames
+            if len(cataloggedNames) > 0:
+                returnNamesDict[name] = cataloggedNames
             else:
-                returnNamesDict[name]=[]
+                returnNamesDict[name] = []
        
-        logging.debug("id: %s"%repr(returnNamesDict))
+        logging.debug("id: %s" % repr(returnNamesDict))
         return returnNamesDict
 
         
-    def editMPIWGProject(self,RESPONSE=None,fromEdit=None):
+    def editMPIWGProject(self, RESPONSE=None, fromEdit=None):
         """edit the project and archive the old version"""
         
-        self.copyObjectToArchive() # archive the object
+        self.copyObjectToArchive()  # archive the object
         self.ZCacheable_invalidate()
 
+        formdata = self.REQUEST.form
+        logging.debug("REQUEST.form=%s" % repr(formdata))
+        
+        # set all definedFields
         for x in definedFields:
-            if self.REQUEST.has_key(x):
-                logging.debug("editMPIWGProject: key=%s val=%s"%(repr(x),repr(self.REQUEST.get(x))))
-                setattr(self,x,self.REQUEST.get(x))
+            if formdata.has_key(x):
+                setattr(self, x, formdata[x])
 
-        completedAt = self.REQUEST.get('completedAt')
+        # TODO: What does this do?
+        completedAt = formdata.get('completedAt')
         if not self.setCompletedAt(completedAt):
-            RESPONSE.redirect('./editMPIWGBasisEditor?error="dateWrong')
+            RESPONSE.redirect('./editMPIWGBasisEditor?error=dateWrong')
   
-        startedAt = self.REQUEST.get('startedAt')
+        startedAt = formdata.get('startedAt')
         if not self.setStartedAt(startedAt):
-            RESPONSE.redirect('./editMPIWGBasisEditor?error="dateWrong')
+            RESPONSE.redirect('./editMPIWGBasisEditor?error=dateWrong')
         
         if self.REQUEST.has_key('active'):
             self.setActiveFlag(True)
         else:
             self.setActiveFlag(False)
         
-        self.responsibleScientistsList=[] # setze die Liste der verantwortlichen Wissenschaftler zurueck
+        # make dict of responsible scientists
+        checkedScientists = {}
+        names = {}
+        keys = {}
+        for key in formdata.keys(): 
+            # gehe durch das Formular
+            keyParts = key.split("_")
+            if keyParts[0] == "responsibleScientist": 
+                # wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt
+                nr = keyParts[2]
+                if keyParts[1] == "name":
+                    names[nr] = formdata[key]
+                elif keyParts[1] == "key":
+                    keys[nr] = formdata[key]
+         
+        for nr in names.keys():
+            name = names[nr]
+            key = keys.get(nr, None)
+            username = None
+            if key:
+                # get username from db
+                member = self.executeZSQL("select * from personal_www where lower(key) = %s", [key.lower()])
+                if len(member) > 0:
+                    username = re.sub('@mpiwg-berlin\.mpg\.de', '', member[0].e_mail)
+                    
+            # schreibe keys und namen in die Liste
+            checkedScientists[names[nr]] = {'name' : name, 'key' : key, 'username' : username}
+             
+        self.setResponsibleScientistsList(checkedScientists)
         
-        names={}
-        keys={}
-        tmpList=[]
-        for key in self.REQUEST.keys(): #gehe durch das Formular
-            splitted=key.split("_")
-            if splitted[0]=="responsibleScientist": #wenn es ein Feld der Form reponsibleScientist_nr_KEY gibt
-                nr=splitted[2]
-                if splitted[1]=="name":
-                    names[nr]=self.REQUEST[key]
-                elif splitted[1]=="key":
-                    keys[nr]=self.REQUEST[key]
-         
-        for nr in names.keys():#schreibe keys und namen in die Liste, stelle ausserdem sicher, dass name unicode
-             tmpList.append((unicodify(names[nr]),unicodify(keys.get(nr,""))))
-             
-        self.responsibleScientistsList=tmpList
-        
-        #self.reindex_object()
         if fromEdit and (RESPONSE is not None):
-            #RESPONSE.redirect('./editMPIWGBasisEditor')
-            return self.editBasic(identifiedNames=self.identifyNames(self.decode(self.REQUEST.get('xdata_01',''))))
+            return self.editBasic()
             
         else:
             if RESPONSE is not None:
                 RESPONSE.redirect('manage_main')
 
 
-    def isChecked(self,wert,list):
+    def isChecked(self, wert, list):
         """check if wert is in ; seperated list"""
 
-        #felder sind manchmnal als liste mit einem element definiert
+        # felder sind manchmnal als liste mit einem element definiert
         if type(list) is StringType or UnicodeType: 
-            splitted=list.split(";")
+            splitted = list.split(";")
         else:
-            splitted=list[0].split(";")
+            splitted = list[0].split(";")
 
-        splitted=[y.rstrip().lstrip() for y in splitted]
+        splitted = [y.rstrip().lstrip() for y in splitted]
         
         for x in splitted:
-            x=re.sub(r"[^A-z ]","",x)
-            if (not x==u'') and x in wert:
+            x = re.sub(r"[^A-z ]", "", x)
+            if (not x == u'') and x in wert:
                 return 1
         return 0
 
-    security.declareProtected('View management screens','editBasic')
+    security.declareProtected('View management screens', 'editBasic')
     def editBasic(self, identifiedNames=None):
         """editform"""
         if not identifiedNames:
-            identifiedNames=self.identifyNames(self.getContent('xdata_01'))
-           # identifiedNames=self.getFullNameEntries()
+            identifiedNames = self.identifyNames(self.getResponsibleScientists())
         
-        logging.debug("IdentifiedNames: %s"%repr(identifiedNames))
-        pt=PageTemplateFile('zpt/project/edit_basic', globals()).__of__(self)
+        logging.debug("editBasic: IdentifiedNames=%s" % repr(identifiedNames))
+        pt = self.edit_basic
         return pt(identifiedNames=identifiedNames)
 
 
-    security.declareProtected('View management screens','editMPIWGBasisForm')
+    security.declareProtected('View management screens', 'editMPIWGBasisForm')
     def editMPIWGBasisForm(self):
         """editform"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGBasis.zpt')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGBasis.zpt')).__of__(self)
         return pt()
 
-    security.declareProtected('View management screens','editMPIWGRelatedPublicationsForm')
+    security.declareProtected('View management screens', 'editMPIWGRelatedPublicationsForm')
     def editMPIWGRelatedPublicationsForm(self):
         """Edit related Publications"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGRelatedPublications.zpt')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'edit_MPIWGRelatedPublications.zpt')).__of__(self)
         return pt()
         
     
     def loadNewFileForm(self):
         """Neues XML-File einlesen"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','MPIWGProject_newfile.zpt')).__of__(self)
+        pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'MPIWGProject_newfile.zpt')).__of__(self)
         return pt()
 
-    def loadNewFile(self,RESPONSE=None):
+    def loadNewFile(self, RESPONSE=None):
         """einlesen des neuen files"""
-        fileupload=self.REQUEST['fileupload']
+        fileupload = self.REQUEST['fileupload']
         if fileupload:
-            file_name=fileupload.filename
-            filedata=fileupload.read()
+            file_name = fileupload.filename
+            filedata = fileupload.read()
 
-            argv=xmlhelper.proj2hash(filedata)
-            #print argv.keys()
+            argv = xmlhelper.proj2hash(filedata)
+            # print argv.keys()
             for arg in definedFields:
                 
-                #print arg,argv[arg],getattr(self,arg)
+                # print arg,argv[arg],getattr(self,arg)
                 try:
-                    temp=argv[arg][0:]
-                    #old=getattr(self,arg)
-                    setattr(self,arg,temp)
-                    #print old,getattr(self,arg)
+                    temp = argv[arg][0:]
+                    # old=getattr(self,arg)
+                    setattr(self, arg, temp)
+                    # print old,getattr(self,arg)
                 except:
                     """nothing"""
                     
         if RESPONSE is not None:
             RESPONSE.redirect('manage_main')
 
-    def tagTheProject(self,RESPONSE=None):
+    def tagTheProject(self, RESPONSE=None):
         """TAG"""
-        id=self.getId();
-        tmpl =getattr(self.thesaurus,"main.html")
+        id = self.getId();
+        tmpl = getattr(self.thesaurus, "main.html")
         if RESPONSE:
-            RESPONSE.redirect("./thesaurus/main.html?project="+id)
+            RESPONSE.redirect("./thesaurus/main.html?project=" + id)
         return
         
 def manage_addMPIWGProjectForm(self):
     """form for adding the project"""
-    pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGProjectForm.zpt')).__of__(self)
+    pt = PageTemplateFile(os.path.join(package_home(globals()), 'zpt', 'addMPIWGProjectForm.zpt')).__of__(self)
     return pt()
 
-def manage_addMPIWGProject(self,id,RESPONSE=None):
+def manage_addMPIWGProject(self, id, RESPONSE=None):
     """method to add a project"""
-    #print argv
-    fileupload=self.REQUEST.get('fileupload',None)
+    # print argv
+    fileupload = self.REQUEST.get('fileupload', None)
     if fileupload:
 
-        file_name=fileupload.filename
-        filedata=fileupload.read()
+        file_name = fileupload.filename
+        filedata = fileupload.read()
         
-        argv=xmlhelper.proj2hash(filedata)
+        argv = xmlhelper.proj2hash(filedata)
         
-        #print argv
-        newObj=MPIWGProject(id,argv)
+        # print argv
+        newObj = MPIWGProject(id, argv)
     else:
-        newObj=MPIWGProject(id)
+        newObj = MPIWGProject(id)
 
-    self._setObject(id,newObj)
+    self._setObject(id, newObj)
 
     
     if RESPONSE is not None:
@@ -1771,12 +1856,13 @@
 class MPIWGProjectFolder(ZDBInterfaceFolder):
     """Folder of project objects"""
 
-    meta_type="MPIWGProjectFolder"
-    security=ClassSecurityInfo()
-
+    meta_type = "MPIWGProjectFolder"
+    security = ClassSecurityInfo()
+    
     # cached HashTree with project hierarchy
     _v_projectTree = None
 
+
     def getProjectTree(self):
         """returns the project hierarchy tree (and caches it).
         
@@ -1788,7 +1874,7 @@
                 tree.add(p.getNumber(), p)
                 
             self._v_projectTree = tree
-            #logging.debug("getProjectTree: tree=%s"%(tree.root.getSubtreeAsText()))
+            # logging.debug("getProjectTree: tree=%s"%(tree.root.getSubtreeAsText()))
 
         return tree
     
@@ -1803,14 +1889,14 @@
         archived = 1 : current projects
         archived = 2 : archived projects
         """
-        #logging.debug("getProjectsAsList(start=%s,active=%s,archived=%s)"%(repr(start),active,archived))
+        # logging.debug("getProjectsAsList(start=%s,active=%s,archived=%s)"%(repr(start),active,archived))
         tree = self.getProjectTree()
         node = tree.getNode(start)
         if node is None:
             return []
 
         pl = node.getSubtreeAsList()
-        #logging.debug("getProjectsAsList: node=(%s,%s) pl=%s"%(node.key,node.value,pl))
+        # logging.debug("getProjectsAsList: node=(%s,%s) pl=%s"%(node.key,node.value,pl))
         # return filtered list
         return [p for p in pl if (p.checkActive(active) and p.checkArchived(archived))]     
     
@@ -1839,7 +1925,7 @@
         return projects        
         
         
-    security.declareProtected('View management screens','updateAllProjectMembers')
+    security.declareProtected('View management screens', 'updateAllProjectMembers')
     def updateAllProjectMembers(self, updateResponsibleScientistsList=False):
         """re-creates responsibleScientistsLists and projects_members table from all current projects"""
         # empty table
@@ -1849,37 +1935,62 @@
         for p in self.objectValues(spec='MPIWGProject'):
             cnt += 1
             memberlist = []
-            logging.debug("updateAllProjectMembers: updating project %s"%p)
+            logging.debug("updateAllProjectMembers: updating project %s" % p)
             if updateResponsibleScientistsList:
-                newlist = []
-                names = p.identifyNames(p.getContent('xdata_01'))
+                newScientists = {}
+                names = p.identifyNames(p.getResponsibleScientists())
                 for name in names.keys():
-                    logging.debug("updateAllProjectMembers: name=%s"%repr(name))
+                    logging.debug("updateAllProjectMembers: name=%s" % repr(name))
                     members = names[name]
                     if len(members) > 0:
                         # take the first matching name
-                        newlist.append([name, members[0].key])
+                        newScientists[name] = {'name': name, 'key' : members[0].key, 'username' : re.sub('@mpiwg-berlin\.mpg\.de', '', members[0].e_mail)}
                     
-                memberlist = newlist
+                p.setResponsibleScientistsList(newScientists)
             
-            else:
-                memberlist = p.responsibleScientistsList
+            memberlist = p.getResponsibleScientistsList()
+               
+            if len(memberlist) == 0:
+                continue
+             
+            # update old format responsibleScientistsList
+            if isinstance(memberlist[0], tuple):
+                logging.debug("updateAllProjectMembers: updating memberlist for project %s" % p)
+                newScientists = {}
+                for m in memberlist:
+                    name = m[0]
+                    key = m[1] 
+                    username = None
+                    if key:
+                        if isinstance(key, list):
+                            key = key[0]
+                            
+                        # get username from db
+                        member = self.executeZSQL("select * from personal_www where lower(key) = %s", [key.lower()])
+                        if len(member) > 0:
+                            username = re.sub('@mpiwg-berlin\.mpg\.de', '', member[0].e_mail)
+                            
+                    newScientists[name] = {'name': name, 'key' : key, 'username' : username}
+                    
+                # set and re-read new list
+                p.setResponsibleScientistsList(newScientists)
+                memberlist = p.getResponsibleScientistsList()
                 
             # add members to table
             for m in memberlist:
-                memberKey = m[1]
+                memberKey = m.get('key')
                 if not memberKey or not isinstance(memberKey, basestring):
-                    logging.error("updateAllProjectMembers: not a valid member key: %s"%repr(memberKey))
+                    logging.error("updateAllProjectMembers: not a valid member key: %s" % repr(memberKey))
                     continue
                 
                 pNum = p.getNumber()
                 if not pNum or not isinstance(pNum, basestring):
-                    logging.error("updateAllProjectMembers: not a valid project number: %s"%repr(pNum))
+                    logging.error("updateAllProjectMembers: not a valid project number: %s" % repr(pNum))
                     continue
                 
                 self.executeZSQL('insert into projects_members (project_number, member_key) values (%s, %s)', (pNum, memberKey))
 
-        return "updated %s projects!"%cnt
+        return "updated %s projects!" % cnt
 
         
 def manage_addMPIWGProjectFolderForm(self):
@@ -1887,15 +1998,15 @@
     pt = PageTemplateFile('zpt/project/manage_add_MPIWGProjectFolder', globals()).__of__(self)
     return pt()
 
-def manage_addMPIWGProjectFolder(self,id,title,RESPONSE=None):
+def manage_addMPIWGProjectFolder(self, id, title, RESPONSE=None):
     """add a MPIWGProjectFolder"""
-    newObj=MPIWGProjectFolder(id,title)
+    newObj = MPIWGProjectFolder(id, title)
 
-    self._setObject(id,newObj)
+    self._setObject(id, newObj)
 
     if RESPONSE is not None:
         RESPONSE.redirect('manage_main')
 
 
         
-        
\ No newline at end of file
+        
--- a/MPIWGRoot.py	Thu Apr 25 12:07:56 2013 +0200
+++ b/MPIWGRoot.py	Thu Apr 25 21:39:57 2013 +0200
@@ -28,7 +28,7 @@
 import updatePersonalWWW
 from bibliography import *
 import MPIWGStaff
-from SrvTxtUtils import getInt, utf8ify, refreshingImageFileIndexHtml
+from SrvTxtUtils import getInt, getAt, utf8ify, refreshingImageFileIndexHtml
 
 
 def sortWeight(x,y):
@@ -307,10 +307,10 @@
     def isActiveMember(self,key):
         """tested ob Mitarbeiter key ist aktiv"""
         key=utf8ify(key)
-        ret=self.getat(self.ZSQLInlineSearch(_table='personal_www',
+        ret=getAt(self.ZSQLInlineSearch(_table='personal_www',
                                             _op_key='eq',key=key,
                                             _op_publish_the_data='eq',
-                                            publish_the_data='yes'))
+                                            publish_the_data='yes'), 0)
         
         logging.info("ACTIVE_MEMBER  %s"%ret)
         if ret:
--- a/zpt/project/edit_basic.zpt	Thu Apr 25 12:07:56 2013 +0200
+++ b/zpt/project/edit_basic.zpt	Thu Apr 25 21:39:57 2013 +0200
@@ -73,18 +73,16 @@
           <td>
             <table>
               <tr tal:repeat="member python:identifiedName[1]">
-                  <td tal:content="python:member.key" />
-                  <td tal:content="python:member.e_mail" />
-                  <td><input type="checkbox"
-                    tal:attributes="name python:'responsibleScientist_key_%s'%count; value python:member.key;
+                <td tal:content="python:member.key" />
+                <td tal:content="python:member.e_mail" />
+                <td><input type="checkbox"
+                  tal:attributes="name python:'responsibleScientist_key_%s'%count; value python:member.key;
                       checked python:here.isResponsibleScientist(member.key)" />
-                  </td>
+                </td>
               </tr>
             </table>
-
           </td>
         </tr>
-
       </table>
       <p>
         <input type="submit" value="change" />
--- a/zpt/project/project_template.zpt	Thu Apr 25 12:07:56 2013 +0200
+++ b/zpt/project/project_template.zpt	Thu Apr 25 21:39:57 2013 +0200
@@ -25,17 +25,12 @@
       </p>
     </tal:x>
 
-    <h1 tal:content="structure python:here.getContent('WEB_title')">History of Scientific Objectivity, 18th-19th Cs</h1>
+    <h1 tal:content="here/getProjectTitle">History of Scientific Objectivity, 18th-19th Cs</h1>
     <p class="maintext_authors">
-      <tal:block tal:repeat="person python:here.getNamesOrdered(here.responsibleScientistsList)">
-        <tal:block tal:define="name python:person[0]; url python:here.getMemberIdFromKey(person[1])">
-          <a tal:condition="python:(url!='') and here.isActiveMember(person[1])"
-            tal:attributes="href string:$root/${secmap/staff}/members/$url" tal:content="python:here.decode(name)"> Name of
-            responsible person </a>
-          <span tal:condition="not:python:(url!='') and here.isActiveMember(person[1])" tal:content="python:here.decode(name)">
-            Name of responsible person </span>
-        </tal:block>
-        <tal:block tal:condition="not:repeat/person/end">,</tal:block>
+      <tal:block tal:repeat="person here/getResponsibleScientistsList">
+          <a tal:omit-tag="python:not (person['username'] and here.isActiveMember(person['key']))"
+            tal:attributes="href string:$root/${secmap/staff}/members/${person/username}" tal:content="person/name"> Name of
+            responsible person</a><tal:block tal:condition="not:repeat/person/end">, </tal:block>
       </tal:block>
     </p>