changeset 86:ab836d3f96dc

styles for staff list.
author casties
date Tue, 14 May 2013 17:24:30 +0200
parents 271cf05a8648
children 77f2478ae971
files MPIWGStaff.py MPIWGStaff_old.py css/mpiwg.css zpt/staff/member_index_html.zpt zpt/www/common_template.zpt
diffstat 5 files changed, 171 insertions(+), 1109 deletions(-) [+]
line wrap: on
line diff
--- a/MPIWGStaff.py	Tue May 14 10:36:48 2013 +0200
+++ b/MPIWGStaff.py	Tue May 14 17:24:30 2013 +0200
@@ -1,1010 +1,39 @@
 """This file contains the classes for the organization of the staff"""
-# TODO: pruefe ob die id der einzelnen tabellen, wie id in publications noch benutzt werden
-# TODO: pruefe ob die bibliographischen felder in publications noch benutzt werden
-# TODO: wird username gebraucht?
 
 from zExceptions import Redirect
 
 from OFS.Folder import Folder
 from Products.PageTemplates.PageTemplateFile import PageTemplateFile
-from Products.PageTemplates.PageTemplate import PageTemplate
-from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
-from Products.ZCatalog.CatalogPathAwareness import CatalogAware
-from Products.versionedFile.extVersionedFile import extVersionedFileFolder
-from AccessControl import getSecurityManager
 
-from Products.ZSQLExtend.ZSQLExtend import ZSQLExtendFolder
-
-from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder
 from AccessControl import ClassSecurityInfo
 from App.class_init import InitializeClass
 from Products.ExtFile.ExtFile import * 
+from Globals import package_home
+from Products.PythonScripts.standard import sql_quote
+from Products.ExtFile import ExtFile
 import os
 import logging
 import email
-from Globals import package_home
-from Products.PythonScripts.standard import sql_quote
-from types import *
-import time
-import logging
 import re
-from OFS.Cache import Cacheable
-import urllib2
-import transaction
+
+from Products.ZDBInterface.ZDBInterfaceFolder import ZDBInterfaceFolder
 
 from SrvTxtUtils import getHttpData, getAt, getInt, unicodify, utf8ify
-import bibliography
-
-from MPIWGHelper import *
-#ersetzt logging
-def logger(txt,method,txt2):
-    """logging""" 
-    logging.info(txt+ txt2)
-
-departmentList="Renn\nRheinberger\nDaston\nKlein\nSibum\nIT\nInstitut\nBibliothek"
-coneService="http://127.0.0.1:8280/MetaDataManagerRestlet/cone/" # kann in MPIWGRoot konfiguriert werden.
-
-
-
-def createNewDBEntry(self,publish_the_data,key,name,vorname,titles_new,position,e_mail,e_mail_p,date_from,date_to,abteilung,heimat_inst,funded_by="",e_mail2="",txt="",txt_p="no",stay_at_mpiwg="",group="",web_object_created="no",current_work=""):
-        """lege person in der datenbank an"""
-
-        if date_to=="": # wenn date_to leer
-             date_to="date_none"
-        
-        if date_from=="": # wenn date_fromleer
-             date_from="date_none"
-        msg=""
-        #test ob id schon existiert
-        if self.ZSQLQuery("select key from personal_www where key='%s'"%id):
-            return False,"ERROR:key%s already exists"%key
-        
-        #eintragen
-        columnlist="""publish_the_data,key,last_name,first_name,titles_new,status,e_mail,e_mail_p,date_from,date_to,department,home_inst,funded_by,e_mail2,date_stay_at_mpiwg,web_object_created,"group",current_work,current_work_p """
-        insertTuple=(publish_the_data,key,name,vorname,titles_new,position,e_mail,e_mail_p,date_from,date_to,abteilung,heimat_inst,funded_by,e_mail2,stay_at_mpiwg,web_object_created,group,current_work,"yes")
-        
-        insert=[]
-        for element in insertTuple:
-            if element=="date_none": # date_none eintrag wird zu null uebersetzt
-                insert.append('null')
-            else:
-                insert.append("%s"%self.ZSQLQuote(element))
-            
-        insertStr=",".join(insert)
-        queryStr="INSERT INTO personal_www (%s) VALUES (%s)"%(columnlist,insertStr)
-        self.ZSQLQuery("SET DATESTYLE TO 'German'")
-        self.ZSQLQuery(queryStr)
-        logging.info("QQQQ %s:"%queryStr)
-        #currentwork
-        #if not (current_work==""):
-        #    queryStr="INSERT INTO current_work (key_main,current,publish) VALUES ('%s',%s,'%s')"%(key,self.ZSQLQuote(current_work),"yes")
-
-        #  self.ZSQLQuery(queryStr)
-        
-        return True,msg
-    
-    
-class MPIWGStaff(CatalogAware,ZSQLExtendFolder,Cacheable):
-    """Staff"""
-
-    meta_type="MPIWGStaff"
-    default_catalog='MembersCatalog'
-    departmentList=departmentList
-    #_v_cone=None;
-    security=ClassSecurityInfo()
-    
-    manage_options = Folder.manage_options+(
-        {'label':'Edit','action':'changeMPIWGStaffForm'},
-        {'label':'Change Publications Special','action':'changePublications_specialForm'},
-        ) + Cacheable.manage_options
-    
-    __manager_id = "ramCache"
-    def __init__(self,id, lastName,firstName,key):
-        """init"""
-        self.id=id
-        self.title=key
-        self.lastName=lastName
-        self.firstName=firstName
-        self.key=key
-    
-    # compat TODO: remove this
-    def getat(self, array, idx, default=None):
-        """returns always an int (0 in case of problems)"""
-        return getAt(array, idx, default)
-    
-    # compat TODO: remove this
-    def decode(self, s):
-        """TODO: remove this"""
-        return unicodify(s)
-    
-    def redirect(self,RESPONSE,url):
-        """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
-        
-        timeStamp=time.time()
-        
-        if url.find("?")>-1: #giebt es schon parameter
-            addStr="&time=%s"
-        else:
-            addStr="?time=%s"
-            
-        RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
-        logging.error(email.Utils.formatdate()+' GMT')
-        RESPONSE.redirect(url+addStr%timeStamp)
-        
-    def getKeyUTF8(self):
-        """get db_key utf8"""
-        logging.debug("KEY - MPIWGStaff 1:"+self.getKey())
-        logging.debug("KEY - MPIWGStaff 2 :"+utf8ify(self.getKey()))
-        
-        return utf8ify(self.getKey())
-    
-    def setKey(self,key):
-	"""set key"""
-	self.key=key
-
-    def rmKey(self):
-        """rm"""
-        self.key=None
-        return ""
-
-    def getKey(self):
-        """get database key"""
-        
-
-        if getattr(self,'key',None):
-            logging.debug("KEY - MPIWGStaff 4:"+self.key)
-            #logging.error("SAVED KEY:%s"%self.key)
-            return unicodify(self.key.lower())
-            #return self.key.lower()
-        
-        #fuer alt faelle ohne key
-        #logging.error("NEW KEY:%s"%(self.firstName+'_'+self.lastName).lower().replace(' ',''))
-        return (self.firstName+'_'+self.lastName).lower().replace(' ','')
-        
-    def getConnectionObj(self):
-         """returns connection id (from root)"""
-         try:
-             root = self.getMPIWGRoot()
-             return root.getConnectionObj()
-         except:
-             return self.en.getConnectionObj()
-
-    def isPublished(self):
-        """gib publications status aus der datenbank aus"""
-        key=self.getKey()
-        query="select count(publish_the_data) from personal_www where lower(key)='%s' and publish_the_data='yes'"%key
-        
-        res = self.ZSQLQuery(query)
-        
-        if res and res[0].count>0:
-            return True
-        else:
-            return False
-        
- 
-  
-    def updateDBEntry(self,publish_the_data,date_from,date_to,DBid=None,stay_at_mpiwg="",position="",abteilung=""): 
-        """zpddatedb"""
-        if not DBid:
-                    DBid=self.getDBId()
-        
- 
-        self.ZSQLQuery("SET DATESTYLE TO 'German'")
-
-        test=self.ZSQLQuery("select id from personal_www where id='%s' "%DBid)
+import MPIWGHelper
 
-        
-        if test and (len(test)>0): #dataset exists
-            logger("MPIWG Web",logging.INFO,'UPDATE: _table="personal_www",_identify="id=%s"'%DBid+',publish_the_data=%s'%publish_the_data+',date_from=%s'%date_from+',date_to=%s'%date_to+',stay_at_mpiwg=%s'%stay_at_mpiwg+',position=%s'%position)
-            self.ZSQLChange(_table="personal_www",_identify="id=%s"%DBid,publish_the_data=publish_the_data,
-                                   date_from=date_from,
-                                   date_to=date_to,stay_at_mpiwg=stay_at_mpiwg,position=position,abteilung=abteilung)
-            return True
-        else:
-            return False
-          
-    def getPublicationSelectionMode(self):
-        """get publication selection mode, default 'priority'"""
-        return getattr(self,'publicationSelectionMode','priority')
-        
-    def changePublicationSelectionMode(self,publicationSelectionMode,RESPONSE=None):
-        """change PublicationSelectionMode"""
-        
-        self.publicationSelectionMode=publicationSelectionMode
-        self.ZCacheable_invalidate()
-        if RESPONSE:
-            self.redirect(RESPONSE,"editPublications")
-            
-    
-    def downloadCV(self,RESPONSE):
-        """download cv file"""
-        ob=self._getOb("downloadableFiles")._getOb("cv.pdf")
-        
-        RESPONSE.redirect(ob.absolute_url()+"/download")
-    
-    def getLastUpdateCV(self):
-        """getDate of Last Update"""
-        try:
-                ob=self._getOb("downloadableFiles")._getOb("cv.pdf")
-                return ob.getLastChangeDate()
-        except:
-                return "No file yet!"
-    def getLastUpdatePublications(self):
-        """getDate of Last Update"""
-        try:
-                ob=self._getOb("downloadableFiles")._getOb("publications.pdf")
-                return ob.getLastChangeDate()
-        except:
-                return "No file yet!"
-    def downloadPublications(self,RESPONSE):
-        """download publications"""
-        ob=self._getOb("downloadableFiles")._getOb("publications.pdf")
-        
-        RESPONSE.redirect(ob.absolute_url()+"/download")
-   
-    def changeDownloads(self,cv_pdf=None,cv_publish=None,publications_pdf=None,publications_publish=None,RESPONSE=None):
-        """"change the downloadable files"""
-        self.ZCacheable_invalidate()
-        if not hasattr(self,'downloadableFiles'):
-           
-            extFolder =  extVersionedFileFolder()
-            extFolder.id = "downloadableFiles"
-            self._setObject(extFolder.id,extFolder)
-            
-        ob = self._getOb("downloadableFiles")
-        
-        if cv_publish:
-            self.cv_publish=cv_publish
-            
-        if publications_publish:
-            self.publications_publish=publications_publish
-            
-        if cv_pdf:
-            if not hasattr(ob,"cv.pdf"):
-                ob.addFile("",cv_pdf,newName="cv.pdf")
-            
-            else:
-                cvFile = getattr(ob,"cv.pdf")
-                cvFile.addContentObject("","",file=cv_pdf)
-        
-        if publications_pdf:
-            if not hasattr(ob,"publications.pdf"):
-                ob.addFile("",cv_pdf,newName="publications.pdf")
-            
-            else:
-                cvFile = getattr(ob,"publications.pdf")
-                cvFile.addContentObject("","",file=publications_pdf)
-        
-        if RESPONSE:
-            self.redirect(RESPONSE,self.REQUEST['HTTP_REFERER'])
-    
-
-    def getPublishImage(self):
-        """publish the image??, default no"""
-        return getattr(self,'publishImage','no')
-    
-    def updateImage(self,publishImage,file=None,rename=None,RESPONSE=None):
-        """update image"""
-
-        if file and not(file.filename==""):
-            if self.getImageObj():
-                              self.getImageObj().updateImage(file,_rename=None,RESPONSE=None)
-            else:
-                # create new image object
-                xp = file.filename.rfind('.')
-                if xp > 0:
-                    ext = file.filename[xp:]
-                    #fn = self.getId()+ext
-                    fn = self.getId()
-                    logger("MPWIG STAFF", logging.INFO, "new filename: %s"%fn)
-                    self.getImageFolder().addImage2(file,fileName=fn)
-                else:
-                    logger("MPWIG STAFF", logging.ERROR, "uploaded filename %s has no extension!"%file.filename)
-            
-        self.publishImage=publishImage
-        
-        if RESPONSE:
-            self.redirect(RESPONSE,"edit")
-            
-    def getImageFolder(self):
-        """getImageFolder"""
-        #TODO: make place of staff image folder configurable
-        
-        try:
-            return self.getPhysicalRoot().www_neu.images.staff_images
-        except: 
-            logger("MPWIG STAFF", logging.ERROR, "image folder not found: has to be add /www_neu/staff_images") 
-            return None
-        
-    def getImageObj(self):
-        """getImage"""
-        imageFolder=self.getImageFolder()
-        
-        if not imageFolder: return None
-        
-        image=getattr(imageFolder,self.getId(),None)
-
-        if not image:
-            for suffix in ['jpg','tif']:
-                
-                image=getattr(imageFolder,self.getId()+"."+suffix,None)
-                if image:
-                    break
-        return image
-            
-    def getImageUrl(self):
-        """getImageUrl"""
-        image=self.getImageObj()
-        if not image:
-            return None
-        else:
-            return self.getImageObj().absolute_url()+"/image"
-    
-    def PrincipiaSearchSource(self):
-        """Return cataloguable key for ourselves."""
-        return str(self)
+#
+# compatibility
+# TODO: should be removed when done
+import MPIWGStaff_old
 
-    def getPersonID(self):
-        """gibt den ID fuer die Person zurueck"
-        im Moment ist personID = id, i.e. e-mail
-        """
-        return self.id
-
-    def getConeUrl(self):
-        """gibt coneURL zurueck"""
-        
-        self.coneService=getattr(self, "coneServiceURL",coneService)
-        logging.debug("coneservice:"+self.coneService)
-        
-        if getattr(self,'_v_cone',None)==None:
-            try:  
-                
-                self._v_cone=getHttpData(self.coneService+self.getPersonID())
-                #cone = urllib2.urlopen(self.coneService+self.getPersonID())              
-                #self._v_cone=cone.read()
-                if self._v_cone==None:
-                    self._v_cone=""
-            except:
-                self._v_cone=""
-                return ""
-            
-        return self._v_cone
-           
-           
-        
-        
-    def harvest_page_old(self,context=None):
-        """geharvestete seite = verschlankte version von members_main"""
-        #pt = getTemplate(self, "harvest_members_main")
-        
-        if not self.isPublished():
-            return ""
-        if not context:
-            context=self
-            
-        
-        ext=getattr(self,"harvest_members_main",None)
-        if ext:
-            return getattr(self,ext.getId())()
-        
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','harvest_members_main')).__of__(context)    
-
-
-        return pt()
-
-    def harvest_page(self,mode="normal"):
-        """harvest"""
-        logging.debug("AAAAXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")
-        if not self.isPublished():
-            return 
-        st = getattr(self.en.staff.members,self.getId()).index_html(mode)
-        
-        templates = self.en.getHarvestCache()
-        #templates = getattr(self,'getHarvestCache',self.en.getHarvestCache)()
-        rendered = st
-        templates[self.absolute_url()]=rendered
-        transaction.commit()
-        return rendered
-	
-        
-    
-    def index_html(self,mode="normal"):
-        """show homepage"""
-    
-        bound_names={}
-        request = self.REQUEST
-        if request is not None:
-            response = request.response
-            if not response.headers.has_key('content-type'):
-                response.setHeader('content-type', 'text/html')
-
-        security = getSecurityManager()
-        bound_names['user'] = security.getUser()
-
-        # Retrieve the value from the cache.
-        keyset = None
-        if self.ZCacheable_isCachingEnabled():
-            
-            # Prepare a cache key.
-            keyset = {'here': self}
-                      
-            result = self.ZCacheable_get(keywords=keyset)
-           
-            if result is not None:
-                # Got a cached value.
-                return result
-        
-        # look for individual page
-        if self.hasObject("index.html"):
-            pt = getattr(self, "index.html")
-        # else use template
-        else:
-            if mode=="slim":
-                pt = getTemplate(self, "members_main_slim")
-            else:
-                pt = getTemplate(self, "members_main")
-        # Execute the template in a new security context.
-        security.addContext(self)
-
-        try:
-            result = pt.pt_render(extra_context=bound_names)
-            if keyset is not None:
-                # Store the result in the cache.
-                self.ZCacheable_set(result, keywords=keyset)
-               
-            return result
-        finally:
-            security.removeContext(self)
-       
-
-   
-    def changePublications_specialForm(self):
-        """Priority publications manual field"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','changePublications_special.zpt')).__of__(self)
-        return pt()
-        
-    def changePublications_special(self,usePublicationsSpecial=None,specialPublicationsField=None,RESPONSE=None):
-        """change publications special params"""
-        self.ZCacheable_invalidate()
-        if usePublicationsSpecial:
-          self.usePublicationsSpecial=True
-         
-        else:
-          self.usePublicationsSpecial=False
-
-        self.specialPublicationsField=specialPublicationsField[0:]
-
-        if RESPONSE is not None:
-            self.redirect(RESPONSE,'manage_main')
-
-        
-    def publications_full(self):
-        """show publication"""
-        pt=getTemplate(self, "publications_full_main")
-        return pt()
-
-    def talks_full(self):
-        """show talks"""
-        pt=getTemplate(self, 'talks_full_main')
-        return pt()
-
-    def teaching_full(self):
-        """show talks"""
-        pt=getTemplate(self, 'teaching_full_main')
-        return pt()
-    
-    def changeMPIWGStaffForm(self):
-        """change form"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','edit_MPIWGStaff.zpt')).__of__(self)
-        return pt()
+createNewDBEntry = MPIWGStaff_old.createNewDBEntry
     
-    security.declareProtected('View management screens','changeMPIWGStaff')
-    def changeMPIWGStaff(self,lastName,firstName,key=None,RESPONSE=None):
-        """change it"""
-        self.ZCacheable_invalidate()
-        self.title="%s, %s"%(lastName,firstName)
-        self.lastName=lastName
-        self.firstName=firstName
-        if key:
-            self.key = key
-            
-        
-        if RESPONSE is not None:
-            self.redirect(RESPONSE,'manage_main')
-            
-    security.declareProtected('View management screens','edit')
-    def edit(self):
-        """Edit the pages"""
-        #TODO: zusammenspiel mit apache, redirect auf 18080 rausnehmen bzw. zumindest verallgemeinern
-        #if self.REQUEST['SERVER_URL']=="http://www.mpiwg-berlin.mpg.de":
-        #        redURL="http://xserve04.mpiwg-berlin.mpg.de:18080/www_neu/de/mitarbeiter/members/%s/edit"%self.getId()
-        #
-        #        self.REQUEST.RESPONSE.redirect(redURL)
-
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editMPIWGStaff.zpt')).__of__(self)
-        
-        
-        logging.debug("XX:"+email.Utils.formatdate().split("-")[0]+'GMT')
-        return pt()
-
-    mainEditFile=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editMPIWGStaff_main.zpt'))
-    addPublicationsBib=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addPublicationsBib.zpt'))
-
-    def getPathStyle(self, path, selected, style=""):
-        """returns a string with the given style + 'sel' if path == selected."""
-
-        if path == selected:
-            return style + 'sel'
-        else:
-            return style    
-
-
-    def getLabel(self):
-        """returns a label for this object"""
-        return self.title
-
-    def getBreadcrumbs(self):
-        """return list of breadcrumbs from here to the root"""
-        crumbs = []
-        # skip direct parent Folder /members/
-        parent = self.aq_parent.aq_parent
-        # get parents breadcrumbs
-        logging.debug("getbreadcrumbs-: title=%s self=%s parent=%s"%(self.title, repr(self), repr(parent)))
-        if hasattr(parent, 'getBreadcrumbs'):
-            logging.debug("getbreadcrumbs: recurse to %s"%parent)
-            crumbs = parent.getBreadcrumbs()
-        
-        # try to get acquisition URL from parent
-        if hasattr(parent, 'absolute_url'):
-            baseUrl = "%s/%s/"%(parent.absolute_url(), 'members')
-        else:
-            baseUrl = "/en/staff/members/"
-            
-        # add this
-        crumbs.append((self.getLabel(), baseUrl+self.getId(), self))
-            
-        return crumbs
-
-
-    def changeCurrentWork(self,current_work,key,publish="yes",RESPONSE=None):
-        """change current work"""
-        
-        query="UPDATE personal_www SET current_work =%s WHERE key='%s'"
-         
-        self.ZSQLQuery(query%(self.ZSQLQuote(current_work),key))
-       
-        query="UPDATE personal_www SET current_work_p =%s WHERE key='%s'"
-         
-        self.ZSQLQuery(query%(self.ZSQLQuote(publish),key))
-        self.ZCacheable_invalidate()
-        if RESPONSE:
-            self.redirect(RESPONSE,"edit")
-        
-    security.declareProtected('View management screens','changeResearch')
-    def changeResearch(self,noredirect=None,RESPONSE=None):
-        """change the research entries"""
-        self.ZCacheable_invalidate()
-        newEntries={}
-        key_main=self.REQUEST.form['key_main']
-
-        mainfieldL=self.REQUEST.form['main_fields'].split(",")
-        mainfield={}
-        for x in mainfieldL:
-            tmp=x.split('__')
-            mainfield[tmp[0]]=tmp[1]
-        for field in self.REQUEST.form.keys():
-            splittedField=field.split("__")
-            if len(splittedField)<3:
-                pass #kein datenbank eintrag
-
-            elif splittedField[2]=='new': # store new entries
-                if not newEntries.has_key(splittedField[0]):
-                    newEntries[splittedField[0]]={}
-                    
-                newEntries[splittedField[0]][splittedField[1]]=self.REQUEST.form[field]
-
-            else:
-                query="UPDATE %s "%splittedField[0]
-                query+="SET %s = '%s' "%(splittedField[1],sql_quote(self.REQUEST.form[field]))
-                query+="WHERE oid = '%s' "%sql_quote(splittedField[2])
-                
-                self.ZSQLQuery(query)
-
-
-        #new entries
-        for newEntry in newEntries.keys():
-            query="INSERT INTO %s "%newEntry
-            keys=['key_main']
-            values=["'"+sql_quote(key_main)+"'"]
-            for key in newEntries[newEntry].keys():
-                keys.append(key)
-                values.append("'"+sql_quote(newEntries[newEntry][key])+"'")
-
-
-            keystring=",".join(keys)
-                
-            valuestring=",".join(values)
-                
-            query+=" (%s) "%keystring
-            query+="VALUES (%s)"%valuestring
-            if not (newEntries[newEntry][mainfield[newEntry]].lstrip().rstrip()==""):
-                self.ZSQLQuery(query)
-
-        if not noredirect:
-            self.redirect(RESPONSE,self.REQUEST['HTTP_REFERER'])
-            
-    security.declareProtected('View management screens','editCV')    
-    def editCV(self,cv=None,oid=None,RESPONSE=None):
-         """edit Cv"""
-
-         if (not oid):
-             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editCV.zpt')).__of__(self)
-             return pt()
-        
-         query="UPDATE personal_www SET cv =%s WHERE oid='%s'"
-         self.ZCacheable_invalidate()
-         self.ZSQLQuery(query%(self.ZSQLQuote(cv),oid))
-        
-         if RESPONSE:
-            self.redirect(RESPONSE,"editCV")
-            
-    
-    def getProfile(self):
-        """get the profile"""
-        self.REQUEST.RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
-      
-        founds=self.ZSQLInlineSearchU(_table='personal_www',key=self.getKeyUTF8())
-        html="""<html><body>%s</body></html>"""
-        if founds.profile and founds.profile != "":
-           
-            return html%founds.profile
-        else:
-                        
-            return html%self.generateProfileForPerson(founds)
-            
-    def editProfile(self,oid=None,RESPONSE=None, kupu=None, preview=None):
-         """edit Profile, new entry replaces CD, current work and research interests"""
-        
-         if (not oid):
-             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editProfile.zpt')).__of__(self)
-             return pt()
-        
-         self.ZCacheable_invalidate() 
-         
-         
-         if preview:
-             pass
-             #TODO: not supported yet
-             #kupu=preview
-             # find content of body tags
-        
-         start=kupu.find("<body>")
-         end=kupu.find("</body>")
-         
-         newcontent= kupu[start+6:end]
-            
-            
-         
-        
-         if preview: 
-            #TODO: not supported yet
-            if RESPONSE:
-                self.redirect(RESPONSE,"editProfile")
-            
-            #return self.preview(newcontent)
-
-         query="UPDATE personal_www SET profile=%s WHERE oid='%s'"       
-         self.ZSQLQuery(query%(self.ZSQLQuote(newcontent),oid))
-         logging.error("PROFILE:"+query%(self.ZSQLQuote(newcontent),oid))
-         if RESPONSE:
-            self.redirect(RESPONSE,"editProfile")
-
-
-
-    def generateProfileForPerson(self,person):
-        """erzeugt ein automatisches Profil aus den alten Eintraegen  CV, Current work, und research interests"""
-        
-        ret=""
-        #founds=self.ZSQLInlineSearch(_table='research_interest',key_main=person.getKeyUTF8())
-        founds=self.ZSQLInlineSearch(_table='research_interest',key_main=person.key)
-        if founds:
-            ret="<p class=\"bio_section_header\">Research interests: </p><br/>"
-        for found in self.sortPriority(founds):
-            ret+=found.interest+"<br/>"
-        
-        
-        if (person.current_work) and (not person.current_work==""):
-            ret+="<p class=\"bio_section_header\">Current work: </p><br/>"
-      
-            ret+=person.current_work+"<br/>"
-    	if (person.cv) and (not person.cv==""):
-            ret+="<p class=\"bio_section_header\">Curriculum Vitae: </p><br/>"
-	    ret+=self.formatAscii(person.cv)
-        
-        return ret
-    security.declareProtected('View management screens','editDownloads')
-    def editDownloads(self):    
-        """editiere die Downloads von der Webseite"""
-        
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editDownloads.zpt')).__of__(self)
-        return pt()
-    
-    security.declareProtected('View management screens','editAdditionalLinks.zpt')
-    def editAdditionalLinks(self):    
-        """editiere die Downloads von der Webseite"""
-        
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editAdditionalLinks.zpt')).__of__(self)
-        return pt()
-    
+class MPIWGStaff(MPIWGStaff_old.MPIWGStaff):
+    """Staff"""
+    pass
     
-    security.declareProtected('View management screens','editAwards')    
-    def editAwards(self,awards=None,oid=None,RESPONSE=None):
-         """edit a awards"""
-     
-         if (not oid):
-             pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editAwards.zpt')).__of__(self)
-             return pt()
-         self.ZCacheable_invalidate()
-         query="UPDATE personal_www SET awards =%s WHERE oid='%s'"
-      
-         self.ZSQLQuery(query%(self.ZSQLQuote(awards),oid))
-        
-        
-         if RESPONSE:
-            self.redirect(RESPONSE,"editAwards")
-
-    security.declareProtected('View management screens','editTalks')    
-    def editTalks(self):
-        """edit talks"""
-
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editTalks.zpt')).__of__(self)
-        return pt()
-        
-    security.declareProtected('View management screens','editTeaching')    
-    def editTeaching(self):
-        """edit Teaching"""
-
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editTeaching.zpt')).__of__(self)
-        return pt()
-        
-    def getDocTypes(self):
-        finds = self.ZopeFind(self.metadata.main.meta.bib,obj_metatypes=["OSAS_MetadataMapping__neu"])
-
-        list= [x[0] for x in finds]
-        return "\n".join(list)
-
-    security.declareProtected('View management screens','editMainData')    
-    def editMainData(self,REQUEST=None,RESPONSE=None):
-        """edit main data"""
-        self.ZCacheable_invalidate()
-        argv=REQUEST.form
-        
-        if not argv.has_key('last_name'):
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editMainData.zpt')).__of__(self)
-            return pt() 
-        else:
-            self.ZSQLChange(argv,_table="personal_www",_identify="lower(key)=%s"%utf8ify(self.getKey().lower()),USE_FORM="yes")
-            # aendere auch dien enstsprechen infos in der instance
-            self.changeMPIWGStaff(argv['last_name'],argv['first_name']);
-            
-            
-            
-            self.reindex_object()
-            
-            
-            
-            if RESPONSE:
-                self.redirect(RESPONSE,"editMainData")
-                
-    security.declareProtected('View management screens','newBibliogrpaphy')    
-    def newBibliography(self,_docType=None, _addEntry=None,RESPONSE=None,**argv):
-        
-        """add an entry to the bibliography"""
-        if not _docType: #kein docType
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','newBibliographyEntryDocType.zpt')).__of__(self)
-            return pt() 
-        elif _docType and not _addEntry: #doctype aber keine daten
-            self.REQUEST['_docType']=_docType
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','newBibliographyEntry.zpt')).__of__(self)
-            return pt() 
-        else: #doctype und daten
-            try:
-                newId=self.ZSQLSimpleSearch("select nextval('id_raw')")[0].nextval
-            except:#id_raw existiert nich, dann neu erzeugen
-                
-                self.createOrUpdateId_raw()
-                newId=self.ZSQLSimpleSearch("select nextval('id_raw')")[0].nextval
-                                
-            bookId="b%06i" % newId
-            
-            self.ZSQLAdd(argv,_table="bibliography",reference_type=_docType,id=bookId)
-
-            self.ZSQLAdd(_useRequest=False,_table="publications",id_gen_bib=bookId,key_main=self.getDBId(),publish='yes')
-            self.updatePublicationDB(personId=self.getDBId())
-            
-        
-        if RESPONSE:
-            self.redirect(RESPONSE,"editPublications")
-            
-        return True
-    
-    security.declareProtected('View management screens','editImage')    
-    def editImage(self):
-        """edit images"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editImageStaff.zpt')).__of__(self)
-        return pt()
-    
-    security.declareProtected('View management screens','editBibliography')    
-    def editBibliography(self):
-        """edit the bibliography"""
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editBibliographyEntry.zpt')).__of__(self)
-        return pt()
-    
-      
-    security.declareProtected('View management screens','editPublications')    
-    def editPublications(self):
-        """edit the bibliographie"""
-
-        pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','editPublications.zpt')).__of__(self)
-        return pt()
-    
-    def changeSortingMode(self,sortingMode,RESPONSE=None,REQUEST=None):
-        """change sorting mode"""
-        self.ZCacheable_invalidate()
-        self.sortingMode=sortingMode
-        
-        if RESPONSE and REQUEST:
-            self.redirect(RESPONSE,REQUEST['HTTP_REFERER'])
-
-        return True
-
-    def getSortingMode(self):
-        """get sorting mode"""
-        mode=getattr(self,'sortingMode','priority')
-        if mode=="year":
-            return "year DESC"
-        else:
-            return mode
-        
-    def integer(self,value):
-        try:
-            return int(value)
-        except:
-            return 0
-        
-    security.declareProtected('View management screens','changePublications')    
-    def changePublications(self,RESPONSE=None):
-        """change the publication list"""
-        self.changeResearch(noredirect=True)
-        self.ZCacheable_invalidate()
-        #self.updatePublicationDB(personId=self.getDBId())
-        self.redirect(RESPONSE,self.REQUEST['HTTP_REFERER'])
-        
-
-  
-    security.declareProtected('View management screens','addPublications')    
-    def addPublications(self,submit=None,REQUEST=None,noredirect=None,RESPONSE=None):
-        """add publications"""
-
-        #setzte flag ob aufruf aus suchformular
-        
-        if REQUEST.get("QUERY_STRING",None) and (not submit):
-            self.REQUEST.set('fromSearch','1')
-        else:
-            self.REQUEST.set('fromSearch','0')
-             
-        if not submit or (not (submit == "add")):
-            pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addPublications.zpt')).__of__(self)
-            return pt()
-        
-        #new entries
-        entries = REQUEST.form.get('addEntries',None)
-        if not (type(entries) is ListType):
-            entries=[entries]
-        
-        
-        for bibId in entries: 
-            query="INSERT INTO %s " % "publications"
-            query+="(key_main,id_institutsbibliographie,publish) "
-            query+="VALUES ('%s','%s','yes')" %(sql_quote(self.getKey()),sql_quote(bibId))
-            
-            #self.ZSQLAdd(_table="publications",id_institutsbibliographie=bibId,id_main=self.getDBId(),publish='yes')
-            self.ZSQLQuery(query)
-     
-        self.updatePublicationDB(personId=self.getKey())
-        
-        if not noredirect:
-            
-            self.redirect(RESPONSE,"./editPublications")
-            
-            return True
-        
-    
-    def getDBId(self):
-        """get id from the personal database"""
-        
-        #in der neuen version ist definitions gemaess der key der Datenbank gleich dem key im Object.
-        # TODO: remove all occurences of getDBId and replaces it by getKey
-        return self.getKey()
-        
-    formatBiblHelp=bibliography.formatBiblHelp
-    
-    def sortBibliography(self,list,sortingMode=None,max=None):
-        if not sortingMode:
-            sortingMode=self.getSortingMode()
-    
-        if sortingMode == "year":
-            l= self.sortYear(list)
-        else:
-            l=self.sortPriority(list)
-        
-        if max:
-            return l[0:min(len(l),max)]
-        else:
-            return l
-        
-    def sortPriority(self,list):
-        def sort(x,y):
-            try:
-                xInt=int(x.priority)
-            except:
-                xInt=0
-            try:
-                yInt=int(y.priority)
-            except:
-                yInt=0
-
-            return cmp(xInt,yInt)
-
-        if not list:
-            return []
-        tmp=[x for x in list]
-        tmp.sort(sort)           
-        
-        return tmp
-
-    def sortYear(self,list):
-        #TODO: sort TO APPEAR and TO BE PUBLISHED etc...
-        
-        def sort(x,y):
-            try:
-                xInt=int(x.year)
-            except:
-                xInt=0
-            try:
-                yInt=int(y.year)
-            except:
-                yInt=0
-
-            return cmp(yInt,xInt)
-            
-            
-        tmp=[x for x in list]
-        
-        tmp.sort(sort)           
-        return tmp
-    
-    def deleteField(self,table,oid,RESPONSE=None):
-        """delete entry"""
-        query="DELETE FROM %s WHERE oid = '%s'"%(table,oid)
-
-        self.ZSQLQuery(query)
-        self.redirect(RESPONSE,self.REQUEST['HTTP_REFERER'])
-        
-    
-def manage_addMPIWGStaffForm(self):
-    """form for adding the project"""
-    pt=PageTemplateFile(os.path.join(package_home(globals()),'zpt','addMPIWGStaffForm.zpt')).__of__(self)
-    return pt()
-
-def manage_addMPIWGStaff(self,id,lastName,firstName,RESPONSE=None):
-    """add it"""
-    newObj=MPIWGStaff(id,lastName,firstName)
-
-    self._setObject(id,newObj)
-
-    if RESPONSE is not None:
-        self.redirect(RESPONSE,'manage_main')
+manage_addMPIWGStaffForm = MPIWGStaff_old.manage_addMPIWGStaffForm
+manage_addMPIWGStaff = MPIWGStaff_old.manage_addMPIWGStaff
 
 
     
@@ -1035,7 +64,7 @@
                 id = stack[-1]
                 logging.debug(id)
                
-                member = self.getMember(id)
+                member = self.getMember(username=id)
                 if member is not None:
                     member = member.__of__(self)
                     request.set('MPIWGStaffMember', member)
@@ -1062,11 +91,9 @@
         member = REQUEST.get('MPIWGStaffMember', None)
         mode = REQUEST.get('MPIWGStaffMode', None)
         if member is not None:
-            
             if mode is not None:
                 return member.execute(mode,REQUEST);
             
-            
             logging.debug("member: key=%s"%(member.getKey()))
             pt = None
             try:
@@ -1091,13 +118,13 @@
             email = '%s@mpiwg-berlin.mpg.de'%username
             content = self.executeZSQL("select * from personal_www where e_mail = %s", [email])
             if len(content) > 0:
-                member = MPIWGStaffMember(self, dbresult=content)
+                member = MPIWGStaffMember(self, dbresult=content[0])
         
         elif key is not None:
             # TODO: sometimes key is lowercased (e.g. responsibleScientistsList), we should fix the data
             content = self.executeZSQL("select * from personal_www where lower(key) = %s", [key.lower()])
             if len(content) > 0:
-                member = MPIWGStaffMember(self, dbresult=content)             
+                member = MPIWGStaffMember(self, dbresult=content[0])             
          
         return member
     
@@ -1108,6 +135,32 @@
         return len(res) > 0
 
 
+    def getMemberList(self, sortBy='last_name', onlyCurrent=False, limit=0):
+        """Return the list of members.
+        
+        Returns a list of MPIWGStaffMember objects.
+        """
+        members = []
+        query = "select * from personal_www_list where publish_the_data = 'yes' and is_scholar='yes'"
+        
+        if onlyCurrent:
+            query += " and date_from < CURRENT_DATE"
+            
+        if sortBy == 'last_name':
+            query += " order by lower(last_name)"
+        elif sortBy == 'date_from':
+            query += " order by date_from DESC"
+            
+        if limit > 0:
+            query += " limit %s"%int(limit)
+            
+        result = self.executeZSQL(query)
+        for res in result:
+            members.append(MPIWGStaffMember(self, dbresult=res))
+            
+        return members
+        
+
     def sortPriority(self,list):
         def sort(x,y):
             try:
@@ -1128,6 +181,7 @@
         
         return tmp
     
+    
     def getPublicationsFromPubman(self,coneId="renn",limit=None,publicationType=None):
         
         logging.debug("coneID:%s"%coneId)
@@ -1175,9 +229,9 @@
     
 
     def __init__(self, folder, dbresult):
-        """constructor: takes parent MPIWGStaffFolder and content"""
+        """constructor: takes parent MPIWGStaffFolder and content (DB row)"""
         self.folder = folder
-        self.content = dbresult[0]
+        self.content = dbresult
             
     def isValid(self):
         """returns if this member exists"""
@@ -1196,9 +250,11 @@
         id = re.sub('@mpiwg-berlin\.mpg\.de', '', self.content.e_mail)
         return id
     
+    getId = getUsername
+    
     def getConeId(self):
         """return cone ID"""
-        results= self.folder.executeZSQL("SELECT coneid FROM keys  WHERE  key_main = %s",[self.content.key]) 
+        results= self.folder.executeZSQL("SELECT coneid FROM keys WHERE key_main = %s",[self.content.key]) 
         for res in results:
             return res.coneid
         return None
@@ -1244,36 +300,18 @@
         else:
             return "NOT FOUND"
         
+        
+    getUrl = MPIWGHelper.getUrl
     
-    def getProfile(self,REQUEST):
-        """get the profile"""
-        self.REQUEST.RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
-      
-        
-        html="""<html><body>%s</body></html>"""
-        if self.content.profile and self.content.profile != "":
-           
-            return html%self.content.profile
-        else:
-                        
-            return html%""
-            
-    
-    
-   
-            
     def getTalks(self):
-        
         return self.folder.executeZSQL("SELECT oid,* FROM talks  WHERE  key_main = %s",[self.content.key]) 
         #return self.folder.ZSQLInlineSearch(_table='talks',key_main=self.content.key)
     
     
     def getTeaching(self):
-        
         return self.folder.executeZSQL("SELECT oid,* FROM teaching  WHERE  key_main = %s",[self.content.key]) 
     
     
-    
     def getLastUpdateCV(self):
         """getDate of Last Update"""
         try:
@@ -1283,6 +321,7 @@
                 return ob.bobobase_modification_time()
         except:
                 return "No file yet!"
+
             
     def getLastUpdatePublications(self):
         """getDate of Last Update"""
@@ -1294,7 +333,6 @@
     
     
     def downloadCV(self,REQUEST):
-      
         fname="%s_cv.pdf"%self.getUsername().encode('utf-8')
         logging.debug(fname)
         ob=self.folder._getOb("downloadableFiles")._getOb(fname)
@@ -1433,7 +471,7 @@
         return pt()
     
     
-        security.declareProtected('View management screens','editDownloads')
+    security.declareProtected('View management screens','editDownloads')
     def editDownloads(self,REQUEST):    
         """editiere die Downloads von der Webseite"""
         
@@ -1748,6 +786,20 @@
         return self.executeZSQL(query,[self.getKey()])
     
     
+    def getProfile(self,REQUEST):
+        """get the profile"""
+        self.REQUEST.RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
+      
+        
+        html="""<html><body>%s</body></html>"""
+        if self.content.profile and self.content.profile != "":
+           
+            return html%self.content.profile
+        else:
+                        
+            return html%""
+   
+            
     def generateProfileForPerson(self,REQUEST=None):
         """erzeugt ein automatisches Profil aus den alten Eintraegen  CV, Current work, und research interests"""
         
--- a/MPIWGStaff_old.py	Tue May 14 10:36:48 2013 +0200
+++ b/MPIWGStaff_old.py	Tue May 14 17:24:30 2013 +0200
@@ -27,7 +27,9 @@
 from OFS.Cache import Cacheable
 import urllib2
 import transaction
-import SrvTxtUtils
+
+from SrvTxtUtils import getHttpData, getAt, getInt, unicodify, utf8ify
+import bibliography
 
 from MPIWGHelper import *
 #ersetzt logging
@@ -76,6 +78,8 @@
         #  self.ZSQLQuery(queryStr)
         
         return True,msg
+    
+    
 class MPIWGStaff(CatalogAware,ZSQLExtendFolder,Cacheable):
     """Staff"""
 
@@ -85,6 +89,30 @@
     #_v_cone=None;
     security=ClassSecurityInfo()
     
+    manage_options = Folder.manage_options+(
+        {'label':'Edit','action':'changeMPIWGStaffForm'},
+        {'label':'Change Publications Special','action':'changePublications_specialForm'},
+        ) + Cacheable.manage_options
+    
+    __manager_id = "ramCache"
+    def __init__(self,id, lastName,firstName,key):
+        """init"""
+        self.id=id
+        self.title=key
+        self.lastName=lastName
+        self.firstName=firstName
+        self.key=key
+    
+    # compat TODO: remove this
+    def getat(self, array, idx, default=None):
+        """returns always an int (0 in case of problems)"""
+        return getAt(array, idx, default)
+    
+    # compat TODO: remove this
+    def decode(self, s):
+        """TODO: remove this"""
+        return unicodify(s)
+    
     def redirect(self,RESPONSE,url):
         """mache ein redirect mit einem angehaengten time stamp um ein reload zu erzwingen"""
         
@@ -312,20 +340,6 @@
         """Return cataloguable key for ourselves."""
         return str(self)
 
-    manage_options = Folder.manage_options+(
-        {'label':'Edit','action':'changeMPIWGStaffForm'},
-        {'label':'Change Publications Special','action':'changePublications_specialForm'},
-        ) + Cacheable.manage_options
-    
-    __manager_id = "ramCache"
-    def __init__(self,id, lastName,firstName,key):
-        """init"""
-        self.id=id
-        self.title=key
-        self.lastName=lastName
-        self.firstName=firstName
-        self.key=key
-    
     def getPersonID(self):
         """gibt den ID fuer die Person zurueck"
         im Moment ist personID = id, i.e. e-mail
@@ -633,7 +647,7 @@
     
     def getProfile(self):
         """get the profile"""
-	self.REQUEST.RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
+        self.REQUEST.RESPONSE.setHeader('Last-Modified',email.Utils.formatdate().split("-")[0]+'GMT')
       
         founds=self.ZSQLInlineSearchU(_table='personal_www',key=self.getKeyUTF8())
         html="""<html><body>%s</body></html>"""
@@ -909,18 +923,6 @@
         # TODO: remove all occurences of getDBId and replaces it by getKey
         return self.getKey()
         
-#        search=self.ZSQLInlineSearch(_table='personal_www',key=self.getKey(),publish_the_data='yes')
-#        if search:#name existiert und published, dann nimm diesen falls es mehrereeventuell nich publizierte datensaetze gibt.
-#            return search[0].id
-#        else:#nicht publiziert dann nimm einen davon
-#            search2=self.ZSQLInlineSearch(_table='personal_www',username=self.getId())
-#            if search2:
-#                return search2[0].id
-#            else:
-#                return None
-        
-    
-    
     formatBiblHelp=bibliography.formatBiblHelp
     
     def sortBibliography(self,list,sortingMode=None,max=None):
@@ -997,8 +999,9 @@
 
     self._setObject(id,newObj)
 
-
     if RESPONSE is not None:
         self.redirect(RESPONSE,'manage_main')
 
+
+
     
--- a/css/mpiwg.css	Tue May 14 10:36:48 2013 +0200
+++ b/css/mpiwg.css	Tue May 14 17:24:30 2013 +0200
@@ -42,29 +42,22 @@
     padding-left: 15px;
 }
 
-a.pdf {
-    background: url(../images/pdf.gif) no-repeat;
-    padding-left: 15px;
-    /* padding-top:1px; */
-}
-
-a.audio {
-    background: url(../images/audio.png) center left no-repeat;
-    padding-left: 15px;
-}
-
 a.down {
     background: url(../images/down.png) center left no-repeat;
     padding-left: 15px;
 }
 
-a.book {
-    background: url(../images/book.gif) no-repeat;
-    padding-left: 20px;
-    margin-left: -5px;
-    margin-top: -1px;
+a.jumptop {
+    background: url(../images/jump_top.png) center left no-repeat;
+    padding-left: 15px;
 }
 
+a.email {
+    background: url(../images/email.png) center left no-repeat;
+    padding-left: 23px;
+}
+
+/* old blue mail link */
 a.maillink {
     color: #3b4186 !important;
 }
@@ -346,6 +339,12 @@
     padding-left: 20px;
 }
 
+div.main div.center {
+    /* make sure center does not collapse */
+    min-width: 460px;
+}
+
+
 /* 
  * frontpage
  */
@@ -651,7 +650,8 @@
     position: relative;
 }
 
-div.box h2 {
+div.box h2,
+h2.line {
     /* h2 is title with line */
     padding-bottom: 5px;
     border-bottom: 3px solid #dccbae;
@@ -1035,6 +1035,7 @@
     font-weight: bold;
     margin: 0;
 }
+
 /* 
  * sidebar 
  */
@@ -1047,6 +1048,7 @@
 }
 
 div.sideblock h2 {
+    position: relative;
     font-size: 12px;
     margin-top: 20px;
     padding-bottom: 5px;
@@ -1074,9 +1076,6 @@
 /*
  * project sidebars
  */
-div.sideblock h2 {
-    position: relative;
-}
 div.sideblock h2 .proj_state {
     position: absolute;
     right: 0;
--- a/zpt/staff/member_index_html.zpt	Tue May 14 10:36:48 2013 +0200
+++ b/zpt/staff/member_index_html.zpt	Tue May 14 17:24:30 2013 +0200
@@ -34,8 +34,8 @@
     </div>
     <!-- profile -->
     <div>
-      <tal:x tal:condition="python:not content.profile">
-        <tal:y tal:replace="structure python:member.generateProfileForPerson()" />
+      <tal:x tal:condition="not:content/profile">
+        <tal:y tal:replace="structure member/generateProfileForPerson" />
       </tal:x>
       <tal:x tal:condition="content/profile">
         <h2>Profile</h2>
@@ -43,32 +43,24 @@
       </tal:x>
     </div>
     <!-- publications -->
-    <tal:block tal:define="publications python:here.ZDBInlineSearch(_table='publications',key_main=key,_op_key_main='eq',publish='yes')"
+    <tal:block
+      tal:define="publications python:here.ZDBInlineSearch(_table='publications',key_main=key,_op_key_main='eq',publish='yes',_op_publish='eq')"
       tal:condition="publications">
       <h2>Selected publications</h2>
-      <!--<p tal:repeat="publication python:member.sortBibliography(publications,content.publications_sort,max=5)">
-        <a tal:omit-tag="not:publication/link" tal:attributes="href publication/link"
-          tal:content="structure python:here.formatBibliography(here,publication)" />
-      </p>
-      <p tal:condition="python:len(publications)>5">
-        <a class="internal" tal:attributes="href string:$baseUrl/publications_full">more</a>
-      </p>-->
-      
       <p tal:repeat="publication python:member.getPublicationsFromPubman(limit=5)">
         <a tal:attributes="href python:'http://pubman.mpiwg-berlin.mpg.de/pubman/faces/viewItemFullPage.jsp?itemId='+publication[0]"
           tal:content="structure python:publication[1]" />
       </p>
       <p tal:condition="python:len(publications)>5">
-        <a class="internal" tal:attributes="href string:$baseUrl/publicationsFull">more</a>
+        <a class="internal" tal:attributes="href string:$baseUrl/publicationsFull">More</a>
       </p>
       <p>
-      <a target="_blank"
-          tal:attributes="href python:member.getConeId()">
-          See all publications (pubman)</a>
-       </p>
+        <a class="external" target="_blank" tal:attributes="href member/getConeId">See all publications (PubMan)</a>
+      </p>
     </tal:block>
     <!-- Talks -->
-    <tal:block tal:define="talks python:here.ZDBInlineSearch(_table='talks',key_main=key,_op_key_main='eq',_sort='priority',published='yes')"
+    <tal:block
+      tal:define="talks python:here.ZDBInlineSearch(_table='talks',key_main=key,_op_key_main='eq',_sort='priority',published='yes')"
       tal:condition="talks">
       <h2>Talks and presentations</h2>
       <div class="namelist">
@@ -84,7 +76,7 @@
         </tal:block>
       </div>
       <p tal:condition="python:len(talks)>5">
-        <a tal:attributes="href string:$baseUrl/talks_full">more</a>
+        <a class="internal" tal:attributes="href string:$baseUrl/talks_full">More</a>
       </p>
     </tal:block>
     <!-- Teaching activities -->
@@ -104,7 +96,7 @@
           </div>
         </tal:block>
         <p tal:condition="python:len(teachings)>5">
-          <a tal:attributes="href string:$baseUrl/teaching_full">more</a>
+          <a class="internal" tal:attributes="href string:$baseUrl/teaching_full">More</a>
         </p>
       </div>
     </tal:block>
@@ -117,37 +109,30 @@
     <div class="sideblock">
       <h2>Contact</h2>
       <div class="item noline">
-        Max Planck Institute for the History of Science
-        <br />
-        Boltzmannstra&szlig;e 22
-        <br />
-        14195 Berlin
-        <br />
-        Germany
+        Max Planck Institute for the History of Science <br /> Boltzmannstra&szlig;e 22 <br /> 14195 Berlin <br /> Germany
       </div>
       <div class="item" tal:condition="python:content.telefon_p=='yes'">
-        tel.:<span tal:content="content/telefon">[FMP-Field: telefon]</span>
-        <br />
+        tel.: <span tal:content="content/telefon">[FMP-Field: telefon]</span> <br />
       </div>
       <div class="item" tal:condition="python:content.fax_p=='yes'">
-        fax:<span tal:content="content/fax">[FMP-Field: fax]</span>
-        <br />
+        fax: <span tal:content="content/fax">[FMP-Field: fax]</span> <br />
       </div>
-      <div class="item internal" tal:condition="python:content.e_mail_p=='yes'">
-        <a class="maillink" tal:attributes="href string:mailto:${content/e_mail}" tal:content="content/e_mail">[FMP-Field:
+      <div class="item" tal:condition="python:content.e_mail_p=='yes'">
+        <a class="email" tal:attributes="href string:mailto:${content/e_mail}" tal:content="content/e_mail">[FMP-Field:
           e_mail]</a>
       </div>
-      <div class="item external" tal:condition="python:content.e_mail2_p=='yes'">
-        <a class="maillink" tal:attributes="href string:mailto:${content/e_mail2}" tal:content="content/e_mail2">[FMP-Field:
+      <div class="item" tal:condition="python:content.e_mail2_p=='yes'">
+        <a class="email" tal:attributes="href string:mailto:${content/e_mail2}" tal:content="content/e_mail2">[FMP-Field:
           e_mail2]</a> (external)
       </div>
     </div>
 
-    <div class="sideblock" tal:define="projects python:here.getProjectFolder().getProjectsOfMember(key=key)" tal:condition="projects">
+    <div class="sideblock" tal:define="projects python:here.getProjectFolder().getProjectsOfMember(key=key)"
+      tal:condition="projects">
       <h2>Projects</h2>
       <div class="project" tal:repeat="project projects">
         <a tal:attributes="href python:project.getUrl(baseUrl=root+'/'+secmap['research']+'/projects/')"
-           tal:content="project/getLabel" />
+          tal:content="project/getLabel" />
       </div>
     </div>
 
@@ -157,15 +142,12 @@
         <a target="_blank" href="downloadCV">Download Curriculum Vitae</a>
       </div>
       <div class="item download" tal:condition="python:getattr(here,'publications_publish','no')=='yes'">
-        <a target="_blank" href="downloadPublications">Download Publication List</a>
-        <br />
+        <a target="_blank" href="downloadPublications">Download Publication List</a> <br />
       </div>
-      <div class="item internal">
-        <a target="_blank"
-          tal:attributes="href python:member.getConeId()">
-          See publications on pubman</a>
+      <div class="item external">
+        <a target="_blank" tal:attributes="href python:member.getConeId()"> See publications on PubMan</a>
       </div>
-      <div class="item internal"
+      <div class="item external"
         tal:repeat="addLink python:here.ZDBInlineSearch(_table='additionallink',key_main=key,_op_key_main='eq',_sort='priority',published='yes')">
         <a target="_blank" tal:content="addLink/title" tal:attributes="href addLink/link"> Daston on the History of Science
           (listen to CBC-Interview, Fall 2007)</a>
--- a/zpt/www/common_template.zpt	Tue May 14 10:36:48 2013 +0200
+++ b/zpt/www/common_template.zpt	Tue May 14 17:24:30 2013 +0200
@@ -55,5 +55,31 @@
   </div>
   <!-- feature -->
 
+
+  <!-- short person entry -->
+  <tr class="line" metal:define-macro="staff_member_row">
+    <td>
+      <a tal:attributes="href python:member.getUrl(baseUrl=memBaseUrl)"> 
+        <span tal:replace="member/content/first_name" />
+        <b><span tal:replace="member/content/last_name" /></b>
+      </a>
+      <tal:block metal:define-slot="name_more"/>
+    </td>
+    <td><span tal:replace="python:here.replaceNotEmpty('%s ',member.content.titles_new)" /> (<span
+      tal:replace="python:here.replaceNotEmpty('%s, ',member.content.status)" /> <span
+      tal:replace="python:here.replaceNotEmpty('%s',member.content.date_stay_at_mpiwg)" /><span
+      tal:replace="python:here.replaceNotEmpty(', funded by the %s',member.content.funded_by)" />)<tal:x
+        condition="python:member.content.current_work_p=='yes'">
+        <i tal:content="python:here.replaceNotEmpty(': %s',member.content.current_work)" />
+      </tal:x> <tal:block tal:condition="python:member.content.e_mail_p=='yes'">
+        <br />
+        <a class="email" tal:attributes="href python:'mailto:'+member.content.e_mail" tal:content="member/content/e_mail">[FMP-field:
+          e_mail]</a>
+      </tal:block></td>
+  </tr>
+  <!-- /short person entry -->
+
+
+
 </body>
 </html>